Merge "Add Tapjacking Protection for SettingsHomepageActivity" into qt-qpr1-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
12510978c3
@@ -33,6 +33,7 @@ import androidx.fragment.app.FragmentTransaction;
|
|||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.accounts.AvatarViewMixin;
|
import com.android.settings.accounts.AvatarViewMixin;
|
||||||
|
import com.android.settings.core.HideNonSystemOverlayMixin;
|
||||||
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
|
import com.android.settings.homepage.contextualcards.ContextualCardsFragment;
|
||||||
import com.android.settings.overlay.FeatureFactory;
|
import com.android.settings.overlay.FeatureFactory;
|
||||||
|
|
||||||
@@ -54,8 +55,8 @@ public class SettingsHomepageActivity extends FragmentActivity {
|
|||||||
.initSearchToolbar(this /* activity */, toolbar, SettingsEnums.SETTINGS_HOMEPAGE);
|
.initSearchToolbar(this /* activity */, toolbar, SettingsEnums.SETTINGS_HOMEPAGE);
|
||||||
|
|
||||||
final ImageView avatarView = findViewById(R.id.account_avatar);
|
final ImageView avatarView = findViewById(R.id.account_avatar);
|
||||||
final AvatarViewMixin avatarViewMixin = new AvatarViewMixin(this, avatarView);
|
getLifecycle().addObserver(new AvatarViewMixin(this, avatarView));
|
||||||
getLifecycle().addObserver(avatarViewMixin);
|
getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
|
||||||
|
|
||||||
if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
|
if (!getSystemService(ActivityManager.class).isLowRamDevice()) {
|
||||||
// Only allow contextual feature on high ram devices.
|
// Only allow contextual feature on high ram devices.
|
||||||
|
@@ -32,6 +32,7 @@ import androidx.fragment.app.FragmentManager;
|
|||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.core.HideNonSystemOverlayMixin;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dialog Activity to host Settings Slices.
|
* Dialog Activity to host Settings Slices.
|
||||||
@@ -62,6 +63,7 @@ public class SettingsPanelActivity extends FragmentActivity {
|
|||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
createOrUpdatePanel(true /* shouldForceCreation */);
|
createOrUpdatePanel(true /* shouldForceCreation */);
|
||||||
|
getLifecycle().addObserver(new HideNonSystemOverlayMixin(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@@ -16,20 +16,42 @@
|
|||||||
|
|
||||||
package com.android.settings.homepage;
|
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 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.View;
|
||||||
|
import android.view.Window;
|
||||||
|
import android.view.WindowManager;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
import com.android.settings.R;
|
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.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.Robolectric;
|
import org.robolectric.Robolectric;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.android.controller.ActivityController;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class SettingsHomepageActivityTest {
|
public class SettingsHomepageActivityTest {
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setHomepageContainerPaddingTop_shouldBeSetPaddingTop() {
|
public void setHomepageContainerPaddingTop_shouldBeSetPaddingTop() {
|
||||||
@@ -55,4 +77,55 @@ public class SettingsHomepageActivityTest {
|
|||||||
|
|
||||||
assertThat(frameLayout.getLayoutTransition()).isNotNull();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.settings.panel;
|
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_MEDIA_PACKAGE_NAME;
|
||||||
import static com.android.settings.panel.SettingsPanelActivity.KEY_PANEL_TYPE_ARGUMENT;
|
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.verify;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.app.settings.SettingsEnums;
|
|
||||||
import android.content.Intent;
|
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 com.android.settings.testutils.FakeFeatureFactory;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.robolectric.Robolectric;
|
import org.robolectric.Robolectric;
|
||||||
import org.robolectric.RobolectricTestRunner;
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.android.controller.ActivityController;
|
||||||
|
import org.robolectric.util.ReflectionHelpers;
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
@RunWith(RobolectricTestRunner.class)
|
||||||
public class SettingsPanelActivityTest {
|
public class SettingsPanelActivityTest {
|
||||||
@@ -50,6 +58,7 @@ public class SettingsPanelActivityTest {
|
|||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
mFakeFeatureFactory = FakeFeatureFactory.setupForTest();
|
||||||
mSettingsPanelActivity = spy(
|
mSettingsPanelActivity = spy(
|
||||||
Robolectric.buildActivity(FakeSettingsPanelActivity.class).create().get());
|
Robolectric.buildActivity(FakeSettingsPanelActivity.class).create().get());
|
||||||
@@ -87,4 +96,47 @@ public class SettingsPanelActivityTest {
|
|||||||
assertThat(activity.mBundle.getString(KEY_PANEL_TYPE_ARGUMENT))
|
assertThat(activity.mBundle.getString(KEY_PANEL_TYPE_ARGUMENT))
|
||||||
.isEqualTo("com.android.settings.panel.action.MEDIA_OUTPUT");
|
.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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user