OSDN Git Service

Add Tapjacking Protection for SettingsHomepageActivity
authorSunny Shao <sunnyshao@google.com>
Wed, 31 Jul 2019 05:19:23 +0000 (13:19 +0800)
committerSunny Shao <sunnyshao@google.com>
Thu, 19 Dec 2019 02:59:10 +0000 (02:59 +0000)
Add/remove the SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS flag into/from
SettingsHomepageActivity and SettingsPanelActivity with lifecycle.

Bug: 138442483
Test: make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.homepage
      make RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.panel
      manual test
Change-Id: I72f9a947f57f74a8c09127d6c39173594c248ddc
Merged-In: I72f9a947f57f74a8c09127d6c39173594c248ddc

src/com/android/settings/homepage/SettingsHomepageActivity.java
src/com/android/settings/panel/SettingsPanelActivity.java
tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java

index fa23101..5e6c54b 100644 (file)
@@ -33,6 +33,7 @@ import androidx.fragment.app.FragmentTransaction;
 
 import com.android.settings.R;
 import com.android.settings.accounts.AvatarViewMixin;
+import com.android.settings.core.HideNonSystemOverlayMixin;
 import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
 import com.android.settings.overlay.FeatureFactory;
 
@@ -54,8 +55,8 @@ public class SettingsHomepageActivity extends FragmentActivity {
                 .initSearchToolbar(this /* activity */, toolbar, SettingsEnums.SETTINGS_HOMEPAGE);
 
         final ImageView avatarView = findViewById(R.id.account_avatar);
-        final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(this, avatarView);
-        getLifecycle().addObserver(avatarViewMixin);
+        getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
+        getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
 
         if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
             // Only allow contextual feature on high ram devices.
index 749a46e..8693186 100644 (file)
@@ -32,6 +32,7 @@ import androidx.fragment.app.FragmentManager;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
+import com.android.settings.core.HideNonSystemOverlayMixin;
 
 /**
  * Dialog Activity to host Settings Slices.
@@ -62,6 +63,7 @@ public class SettingsPanelActivity extends FragmentActivity {
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         createOrUpdatePanel(true /* shouldForceCreation */);
+        getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
     }
 
     @Override
index dcb32c4..db12580 100644 (file)
 
 package com.android.settings.homepage;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Build;
 import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
 import android.widget.FrameLayout;
 
 import com.android.settings.R;
+import com.android.settings.core.HideNonSystemOverlayMixin;
+import com.android.settings.homepage.contextualcards.slices.BatteryFixSliceTest;
 
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.annotation.Config;
+import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
 public class SettingsHomepageActivityTest {
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
 
     @Test
     public void setHomepageContainerPaddingTop_shouldBeSetPaddingTop() {
@@ -55,4 +77,55 @@ public class SettingsHomepageActivityTest {
 
         assertThat(frameLayout.getLayoutTransition()).isNotNull();
     }
+
+    @Test
+    @Config(shadows = {
+            BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
+            BatteryFixSliceTest.ShadowBatteryTipLoader.class
+    })
+    public void onStart_isNotDebuggable_shouldHideSystemOverlay() {
+        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
+
+        final ActivityController<SettingsHomepageActivity> activityController =
+                Robolectric.buildActivity(SettingsHomepageActivity.class).create();
+        final SettingsHomepageActivity activity = spy(activityController.get());
+        final Window window = mock(Window.class);
+        when(activity.getWindow()).thenReturn(window);
+        activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
+
+        activityController.start();
+
+        verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+    }
+
+    @Test
+    @Config(shadows = {
+            BatteryFixSliceTest.ShadowBatteryStatsHelperLoader.class,
+            BatteryFixSliceTest.ShadowBatteryTipLoader.class,
+    })
+    public void onStop_isNotDebuggable_shouldRemoveHideSystemOverlay() {
+        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
+
+        final ActivityController<SettingsHomepageActivity> activityController =
+                Robolectric.buildActivity(SettingsHomepageActivity.class).create();
+        final SettingsHomepageActivity activity = spy(activityController.get());
+        final Window window = mock(Window.class);
+        when(activity.getWindow()).thenReturn(window);
+        activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
+
+        activityController.start();
+
+        verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+
+        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+        when(window.getAttributes()).thenReturn(layoutParams);
+
+        activityController.stop();
+        final ArgumentCaptor<WindowManager.LayoutParams> paramCaptor = ArgumentCaptor.forClass(
+                WindowManager.LayoutParams.class);
+
+        verify(window).setAttributes(paramCaptor.capture());
+        assertThat(paramCaptor.getValue().privateFlags
+                & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
+    }
 }
index 8ad2156..a4b7aa5 100644 (file)
@@ -16,6 +16,8 @@
 
 package com.android.settings.panel;
 
+import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
+
 import static com.android.settings.panel.SettingsPanelActivity.KEY_MEDIA_PACKAGE_NAME;
 import static com.android.settings.panel.SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT;
 
@@ -28,17 +30,23 @@ import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-import android.app.settings.SettingsEnums;
 import android.content.Intent;
-import android.view.MotionEvent;
+import android.os.Build;
+import android.view.Window;
+import android.view.WindowManager;
 
+import com.android.settings.core.HideNonSystemOverlayMixin;
 import com.android.settings.testutils.FakeFeatureFactory;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.MockitoAnnotations;
 import org.robolectric.Robolectric;
 import org.robolectric.RobolectricTestRunner;
+import org.robolectric.android.controller.ActivityController;
+import org.robolectric.util.ReflectionHelpers;
 
 @RunWith(RobolectricTestRunner.class)
 public class SettingsPanelActivityTest {
@@ -50,6 +58,7 @@ public class SettingsPanelActivityTest {
 
     @Before
     public void setUp() {
+        MockitoAnnotations.initMocks(this);
         mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
         mSettingsPanelActivity = spy(
                 Robolectric.buildActivity(FakeSettingsPanelActivity.class).create().get());
@@ -87,4 +96,47 @@ public class SettingsPanelActivityTest {
         assertThat(activity.mBundle.getString(KEY_PANEL_TYPE_ARGUMENT))
                 .isEqualTo("com.android.settings.panel.action.MEDIA_OUTPUT");
     }
+
+    @Test
+    public void onStart_isNotDebuggable_shouldHideSystemOverlay() {
+        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
+
+        final ActivityController<SettingsPanelActivity> activityController =
+                Robolectric.buildActivity(SettingsPanelActivity.class).create();
+        final SettingsPanelActivity activity = spy(activityController.get());
+        final Window window = mock(Window.class);
+        when(activity.getWindow()).thenReturn(window);
+        activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
+
+        activityController.start();
+
+        verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+    }
+
+    @Test
+    public void onStop_isNotDebuggable_shouldRemoveHideSystemOverlay() {
+        ReflectionHelpers.setStaticField(Build.class, "IS_DEBUGGABLE", false);
+
+        final ActivityController<SettingsPanelActivity> activityController =
+                Robolectric.buildActivity(SettingsPanelActivity.class).create();
+        final SettingsPanelActivity activity = spy(activityController.get());
+        final Window window = mock(Window.class);
+        when(activity.getWindow()).thenReturn(window);
+        activity.getLifecycle().addObserver(new HideNonSystemOverlayMixin(activity));
+
+        activityController.start();
+
+        verify(window).addSystemFlags(SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
+
+        final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
+        when(window.getAttributes()).thenReturn(layoutParams);
+
+        activityController.stop();
+        final ArgumentCaptor<WindowManager.LayoutParams> paramCaptor = ArgumentCaptor.forClass(
+                WindowManager.LayoutParams.class);
+
+        verify(window).setAttributes(paramCaptor.capture());
+        assertThat(paramCaptor.getValue().privateFlags
+                & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
+    }
 }