Loading src/com/android/settings/homepage/SettingsHomepageActivity.java +36 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.app.ActivityManager; import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.os.Bundle; Loading @@ -43,6 +45,7 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.Toolbar; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowCompat; Loading @@ -65,6 +68,7 @@ import com.android.settings.core.CategoryMixin; import com.android.settings.core.FeatureFlags; import com.android.settings.homepage.contextualcards.ContextualCardsFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settings.password.PasswordUtils; import com.android.settingslib.Utils; import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin; Loading Loading @@ -431,6 +435,32 @@ public class SettingsHomepageActivity extends FragmentActivity implements finish(); return; } if (!TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()), getPackageName())) { ActivityInfo targetActivityInfo = null; try { targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName, /* flags= */ 0); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Failed to get target ActivityInfo: " + e); finish(); return; } if (!targetActivityInfo.exported) { Log.e(TAG, "Must not launch an unexported Actvity for deep link"); finish(); return; } if (!isCallingAppPermitted(targetActivityInfo.permission)) { Log.e(TAG, "Calling app must have the permission of deep link Activity"); finish(); return; } } targetIntent.setComponent(targetComponentName); // To prevent launchDeepLinkIntentToRight again for configuration change. Loading Loading @@ -472,6 +502,12 @@ public class SettingsHomepageActivity extends FragmentActivity implements } } @VisibleForTesting boolean isCallingAppPermitted(String permission) { return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted( this, getActivityToken(), permission); } private String getHighlightMenuKey() { final Intent intent = getIntent(); if (intent != null && TextUtils.equals(intent.getAction(), Loading tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java +35 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; Loading @@ -37,9 +39,11 @@ import androidx.fragment.app.Fragment; import com.android.settings.R; import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl; import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest; import com.android.settings.testutils.shadow.ShadowPasswordUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -66,6 +70,11 @@ public class SettingsHomepageActivityTest { MockitoAnnotations.initMocks(this); } @After public void tearDown() { ShadowPasswordUtils.reset(); } @Test public void launch_shouldHaveAnimationForIaFragment() { final SettingsHomepageActivity activity = Robolectric.buildActivity( Loading Loading @@ -195,6 +204,32 @@ public class SettingsHomepageActivityTest { & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0); } @Test @Config(shadows = {ShadowPasswordUtils.class}) public void isCallingAppPermitted_emptyPermission_returnTrue() { SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity()); assertTrue(homepageActivity.isCallingAppPermitted("")); } @Test @Config(shadows = {ShadowPasswordUtils.class}) public void isCallingAppPermitted_noGrantedPermission_returnFalse() { SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity()); assertFalse(homepageActivity.isCallingAppPermitted("android.permission.TEST")); } @Test @Config(shadows = {ShadowPasswordUtils.class}) public void isCallingAppPermitted_grantedPermission_returnTrue() { SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity()); String permission = "android.permission.TEST"; ShadowPasswordUtils.addGrantedPermission(permission); assertTrue(homepageActivity.isCallingAppPermitted(permission)); } @Implements(SuggestionFeatureProviderImpl.class) public static class ShadowSuggestionFeatureProviderImpl { Loading Loading
src/com/android/settings/homepage/SettingsHomepageActivity.java +36 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import android.app.ActivityManager; import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.UserInfo; import android.content.res.Configuration; import android.os.Bundle; Loading @@ -43,6 +45,7 @@ import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.Toolbar; import androidx.annotation.VisibleForTesting; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowCompat; Loading @@ -65,6 +68,7 @@ import com.android.settings.core.CategoryMixin; import com.android.settings.core.FeatureFlags; import com.android.settings.homepage.contextualcards.ContextualCardsFragment; import com.android.settings.overlay.FeatureFactory; import com.android.settings.password.PasswordUtils; import com.android.settingslib.Utils; import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin; Loading Loading @@ -431,6 +435,32 @@ public class SettingsHomepageActivity extends FragmentActivity implements finish(); return; } if (!TextUtils.equals(PasswordUtils.getCallingAppPackageName(getActivityToken()), getPackageName())) { ActivityInfo targetActivityInfo = null; try { targetActivityInfo = getPackageManager().getActivityInfo(targetComponentName, /* flags= */ 0); } catch (PackageManager.NameNotFoundException e) { Log.e(TAG, "Failed to get target ActivityInfo: " + e); finish(); return; } if (!targetActivityInfo.exported) { Log.e(TAG, "Must not launch an unexported Actvity for deep link"); finish(); return; } if (!isCallingAppPermitted(targetActivityInfo.permission)) { Log.e(TAG, "Calling app must have the permission of deep link Activity"); finish(); return; } } targetIntent.setComponent(targetComponentName); // To prevent launchDeepLinkIntentToRight again for configuration change. Loading Loading @@ -472,6 +502,12 @@ public class SettingsHomepageActivity extends FragmentActivity implements } } @VisibleForTesting boolean isCallingAppPermitted(String permission) { return TextUtils.isEmpty(permission) || PasswordUtils.isCallingAppPermitted( this, getActivityToken(), permission); } private String getHighlightMenuKey() { final Intent intent = getIntent(); if (intent != null && TextUtils.equals(intent.getAction(), Loading
tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java +35 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTE import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; Loading @@ -37,9 +39,11 @@ import androidx.fragment.app.Fragment; import com.android.settings.R; import com.android.settings.dashboard.suggestions.SuggestionFeatureProviderImpl; import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest; import com.android.settings.testutils.shadow.ShadowPasswordUtils; import com.android.settings.testutils.shadow.ShadowUserManager; import com.android.settingslib.core.lifecycle.HideNonSystemOverlayMixin; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; Loading @@ -66,6 +70,11 @@ public class SettingsHomepageActivityTest { MockitoAnnotations.initMocks(this); } @After public void tearDown() { ShadowPasswordUtils.reset(); } @Test public void launch_shouldHaveAnimationForIaFragment() { final SettingsHomepageActivity activity = Robolectric.buildActivity( Loading Loading @@ -195,6 +204,32 @@ public class SettingsHomepageActivityTest { & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0); } @Test @Config(shadows = {ShadowPasswordUtils.class}) public void isCallingAppPermitted_emptyPermission_returnTrue() { SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity()); assertTrue(homepageActivity.isCallingAppPermitted("")); } @Test @Config(shadows = {ShadowPasswordUtils.class}) public void isCallingAppPermitted_noGrantedPermission_returnFalse() { SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity()); assertFalse(homepageActivity.isCallingAppPermitted("android.permission.TEST")); } @Test @Config(shadows = {ShadowPasswordUtils.class}) public void isCallingAppPermitted_grantedPermission_returnTrue() { SettingsHomepageActivity homepageActivity = spy(new SettingsHomepageActivity()); String permission = "android.permission.TEST"; ShadowPasswordUtils.addGrantedPermission(permission); assertTrue(homepageActivity.isCallingAppPermitted(permission)); } @Implements(SuggestionFeatureProviderImpl.class) public static class ShadowSuggestionFeatureProviderImpl { Loading