diff --git a/res/xml/privacy_dashboard_settings.xml b/res/xml/privacy_dashboard_settings.xml
index 3ac6f4233b4..1dd609e4c22 100644
--- a/res/xml/privacy_dashboard_settings.xml
+++ b/res/xml/privacy_dashboard_settings.xml
@@ -22,13 +22,6 @@
android:title="@string/privacy_dashboard_title"
settings:initialExpandedChildrenCount="4">
-
-
-
{
- mUiModeManager.setNightMode(
- isChecked ? UiModeManager.MODE_NIGHT_YES : UiModeManager.MODE_NIGHT_NO);
+ mUiModeManager.setNightModeActivated(isChecked);
}, DELAY_TIME_EXECUTING_DARK_THEME);
}
@@ -110,10 +123,15 @@ public class DarkThemeSlice implements CustomSliceable {
return null;
}
+ @Override
+ public Class getBackgroundWorkerClass() {
+ return DarkThemeWorker.class;
+ }
+
@VisibleForTesting
boolean isAvailable(Context context) {
// checking dark theme mode.
- if (mUiModeManager.getNightMode() == UiModeManager.MODE_NIGHT_YES) {
+ if (isDarkThemeMode(context)) {
return false;
}
@@ -121,7 +139,47 @@ public class DarkThemeSlice implements CustomSliceable {
final BatteryManager batteryManager = context.getSystemService(BatteryManager.class);
final int level = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
Log.d(TAG, "battery level=" + level);
-
return level <= BATTERY_LEVEL_THRESHOLD;
}
+
+ @VisibleForTesting
+ boolean isDarkThemeMode(Context context) {
+ final int currentNightMode =
+ context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
+ return currentNightMode == Configuration.UI_MODE_NIGHT_YES;
+ }
+
+ public static class DarkThemeWorker extends SliceBackgroundWorker {
+ private final Context mContext;
+ private final ContentObserver mContentObserver =
+ new ContentObserver(new Handler(Looper.getMainLooper())) {
+ @Override
+ public void onChange(boolean bChanged) {
+ if (mContext.getSystemService(PowerManager.class).isPowerSaveMode()) {
+ notifySliceChange();
+ }
+ }
+ };
+
+ public DarkThemeWorker(Context context, Uri uri) {
+ super(context, uri);
+ mContext = context;
+ }
+
+ @Override
+ protected void onSlicePinned() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(LOW_POWER_MODE), false /* notifyForDescendants */,
+ mContentObserver);
+ }
+
+ @Override
+ protected void onSliceUnpinned() {
+ mContext.getContentResolver().unregisterContentObserver(mContentObserver);
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+ }
}
diff --git a/src/com/android/settings/panel/SettingsPanelActivity.java b/src/com/android/settings/panel/SettingsPanelActivity.java
index 749a46e0cde..86931866afc 100644
--- a/src/com/android/settings/panel/SettingsPanelActivity.java
+++ b/src/com/android/settings/panel/SettingsPanelActivity.java
@@ -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
diff --git a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java b/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
deleted file mode 100644
index 28533df03a4..00000000000
--- a/src/com/android/settings/privacy/PermissionBarChartPreferenceController.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.privacy;
-
-import static android.Manifest.permission_group.CAMERA;
-import static android.Manifest.permission_group.LOCATION;
-import static android.Manifest.permission_group.MICROPHONE;
-
-import static java.util.concurrent.TimeUnit.DAYS;
-
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.permission.PermissionControllerManager;
-import android.permission.RuntimePermissionUsageInfo;
-import android.provider.DeviceConfig;
-import android.util.Log;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.VisibleForTesting;
-import androidx.preference.PreferenceScreen;
-
-import com.android.settings.R;
-import com.android.settings.core.BasePreferenceController;
-import com.android.settingslib.Utils;
-import com.android.settingslib.core.lifecycle.LifecycleObserver;
-import com.android.settingslib.core.lifecycle.events.OnCreate;
-import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
-import com.android.settingslib.core.lifecycle.events.OnStart;
-import com.android.settingslib.widget.BarChartInfo;
-import com.android.settingslib.widget.BarChartPreference;
-import com.android.settingslib.widget.BarViewInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-
-
-public class PermissionBarChartPreferenceController extends BasePreferenceController implements
- PermissionControllerManager.OnPermissionUsageResultCallback, LifecycleObserver, OnCreate,
- OnStart, OnSaveInstanceState {
-
- private static final String TAG = "BarChartPreferenceCtl";
- private static final String KEY_PERMISSION_USAGE = "usage_infos";
-
- @VisibleForTesting
- List mOldUsageInfos;
- private PackageManager mPackageManager;
- private PrivacyDashboardFragment mParent;
- private BarChartPreference mBarChartPreference;
-
- public PermissionBarChartPreferenceController(Context context, String preferenceKey) {
- super(context, preferenceKey);
- mOldUsageInfos = new ArrayList<>();
- mPackageManager = context.getPackageManager();
- }
-
- public void setFragment(PrivacyDashboardFragment fragment) {
- mParent = fragment;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- if (savedInstanceState != null) {
- mOldUsageInfos = savedInstanceState.getParcelableArrayList(KEY_PERMISSION_USAGE);
- }
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- outState.putParcelableList(KEY_PERMISSION_USAGE, mOldUsageInfos);
- }
-
- @Override
- public int getAvailabilityStatus() {
- return UNSUPPORTED_ON_DEVICE;
- }
-
- @Override
- public void displayPreference(PreferenceScreen screen) {
- super.displayPreference(screen);
- mBarChartPreference = screen.findPreference(getPreferenceKey());
-
- final BarChartInfo info = new BarChartInfo.Builder()
- .setTitle(R.string.permission_bar_chart_title)
- .setDetails(R.string.permission_bar_chart_details)
- .setEmptyText(R.string.permission_bar_chart_empty_text)
- .setDetailsOnClickListener((View v) -> {
- final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE);
- intent.putExtra(Intent.EXTRA_DURATION_MILLIS, DAYS.toMillis(1));
- mContext.startActivity(intent);
- })
- .build();
-
- mBarChartPreference.initializeBarChart(info);
- if (!mOldUsageInfos.isEmpty()) {
- mBarChartPreference.setBarViewInfos(createBarViews(mOldUsageInfos));
- }
- }
-
- @Override
- public void onStart() {
- if (!isAvailable()) {
- return;
- }
-
- // We don't hide chart when we have existing data.
- mBarChartPreference.updateLoadingState(mOldUsageInfos.isEmpty() /* isLoading */);
- // But we still need to hint user with progress bar that we are updating new usage data.
- mParent.setLoadingEnabled(true /* enabled */);
- retrievePermissionUsageData();
- }
-
- @Override
- public void onPermissionUsageResult(@NonNull List usageInfos) {
- usageInfos.sort((x, y) -> {
- int usageDiff = y.getAppAccessCount() - x.getAppAccessCount();
- if (usageDiff != 0) {
- return usageDiff;
- }
- String xName = x.getName();
- String yName = y.getName();
- if (xName.equals(LOCATION)) {
- return -1;
- } else if (yName.equals(LOCATION)) {
- return 1;
- } else if (xName.equals(MICROPHONE)) {
- return -1;
- } else if (yName.equals(MICROPHONE)) {
- return 1;
- } else if (xName.equals(CAMERA)) {
- return -1;
- } else if (yName.equals(CAMERA)) {
- return 1;
- }
- return x.getName().compareTo(y.getName());
- });
-
- // If the result is different, we need to update bar views.
- if (!areSamePermissionGroups(usageInfos)) {
- mBarChartPreference.setBarViewInfos(createBarViews(usageInfos));
- mOldUsageInfos = usageInfos;
- }
-
- mBarChartPreference.updateLoadingState(false /* isLoading */);
- mParent.setLoadingEnabled(false /* enabled */);
- }
-
- private void retrievePermissionUsageData() {
- mContext.getSystemService(PermissionControllerManager.class).getPermissionUsages(
- false /* countSystem */, (int) DAYS.toMillis(1),
- mContext.getMainExecutor() /* executor */, this /* callback */);
- }
-
- private BarViewInfo[] createBarViews(List usageInfos) {
- if (usageInfos.isEmpty()) {
- return null;
- }
-
- final BarViewInfo[] barViewInfos = new BarViewInfo[
- Math.min(BarChartPreference.MAXIMUM_BAR_VIEWS, usageInfos.size())];
-
- for (int index = 0; index < barViewInfos.length; index++) {
- final RuntimePermissionUsageInfo permissionGroupInfo = usageInfos.get(index);
- final int count = permissionGroupInfo.getAppAccessCount();
- final CharSequence permLabel = getPermissionGroupLabel(permissionGroupInfo.getName());
-
- barViewInfos[index] = new BarViewInfo(
- getPermissionGroupIcon(permissionGroupInfo.getName()), count, permLabel,
- mContext.getResources().getQuantityString(R.plurals.permission_bar_chart_label,
- count, count), permLabel);
-
- // Set the click listener for each bar view.
- // The listener will navigate user to permission usage app.
- barViewInfos[index].setClickListener((View v) -> {
- final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSION_USAGE);
- intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, permissionGroupInfo.getName());
- intent.putExtra(Intent.EXTRA_DURATION_MILLIS, DAYS.toMillis(1));
- mContext.startActivity(intent);
- });
- }
-
- return barViewInfos;
- }
-
- private Drawable getPermissionGroupIcon(String permissionGroup) {
- Drawable icon = null;
- try {
- icon = mPackageManager.getPermissionGroupInfo(permissionGroup, 0)
- .loadIcon(mPackageManager);
- icon.setTintList(Utils.getColorAttr(mContext, android.R.attr.textColorSecondary));
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Cannot find group icon for " + permissionGroup, e);
- }
-
- return icon;
- }
-
- private CharSequence getPermissionGroupLabel(String permissionGroup) {
- CharSequence label = null;
- try {
- label = mPackageManager.getPermissionGroupInfo(permissionGroup, 0)
- .loadLabel(mPackageManager);
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Cannot find group label for " + permissionGroup, e);
- }
-
- return label;
- }
-
- private boolean areSamePermissionGroups(List newUsageInfos) {
- if (newUsageInfos.size() != mOldUsageInfos.size()) {
- return false;
- }
-
- for (int index = 0; index < newUsageInfos.size(); index++) {
- final RuntimePermissionUsageInfo newInfo = newUsageInfos.get(index);
- final RuntimePermissionUsageInfo oldInfo = mOldUsageInfos.get(index);
-
- if (!newInfo.getName().equals(oldInfo.getName()) ||
- newInfo.getAppAccessCount() != oldInfo.getAppAccessCount()) {
- return false;
- }
- }
- return true;
- }
-}
diff --git a/src/com/android/settings/privacy/PrivacyDashboardFragment.java b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
index fa21f9dd444..1869cffa5df 100644
--- a/src/com/android/settings/privacy/PrivacyDashboardFragment.java
+++ b/src/com/android/settings/privacy/PrivacyDashboardFragment.java
@@ -18,14 +18,12 @@ package com.android.settings.privacy;
import android.app.settings.SettingsEnums;
import android.content.Context;
-import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.view.View;
import androidx.annotation.VisibleForTesting;
import com.android.settings.R;
-import com.android.settings.Utils;
import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.notification.LockScreenNotificationPreferenceController;
import com.android.settings.search.BaseSearchIndexProvider;
@@ -75,34 +73,6 @@ public class PrivacyDashboardFragment extends DashboardFragment {
return buildPreferenceControllers(context, getSettingsLifecycle());
}
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- use(PermissionBarChartPreferenceController.class).setFragment(this /* fragment */);
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- Utils.setActionBarShadowAnimation(getActivity(), getSettingsLifecycle(), getListView());
- initLoadingBar();
- }
-
- @VisibleForTesting
- void initLoadingBar() {
- mProgressHeader = setPinnedHeaderView(R.layout.progress_header);
- mProgressAnimation = mProgressHeader.findViewById(R.id.progress_bar_animation);
- setLoadingEnabled(false);
- }
-
- @VisibleForTesting
- void setLoadingEnabled(boolean enabled) {
- if (mProgressHeader != null && mProgressAnimation != null) {
- mProgressHeader.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
- mProgressAnimation.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
- }
- }
-
private static List buildPreferenceControllers(
Context context, Lifecycle lifecycle) {
final List controllers = new ArrayList<>();
diff --git a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
index dcb32c4c475..db12580e169 100644
--- a/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/SettingsHomepageActivityTest.java
@@ -16,20 +16,42 @@
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 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 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 paramCaptor = ArgumentCaptor.forClass(
+ WindowManager.LayoutParams.class);
+
+ verify(window).setAttributes(paramCaptor.capture());
+ assertThat(paramCaptor.getValue().privateFlags
+ & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java
index bb213329b79..1af7b2bfacd 100644
--- a/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java
+++ b/tests/robotests/src/com/android/settings/homepage/contextualcards/slices/DarkThemeSliceTest.java
@@ -22,10 +22,10 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
-import android.app.UiModeManager;
import android.content.Context;
import android.net.Uri;
import android.os.BatteryManager;
+import android.os.PowerManager;
import androidx.slice.Slice;
import androidx.slice.SliceMetadata;
@@ -47,10 +47,10 @@ import org.robolectric.RuntimeEnvironment;
@RunWith(RobolectricTestRunner.class)
public class DarkThemeSliceTest {
- @Mock
- private UiModeManager mUiModeManager;
@Mock
private BatteryManager mBatteryManager;
+ @Mock
+ private PowerManager mPowerManager;
private Context mContext;
private DarkThemeSlice mDarkThemeSlice;
@@ -63,11 +63,12 @@ public class DarkThemeSliceTest {
mFeatureFactory = FakeFeatureFactory.setupForTest();
mFeatureFactory.slicesFeatureProvider = new SlicesFeatureProviderImpl();
mFeatureFactory.slicesFeatureProvider.newUiSession();
- doReturn(mUiModeManager).when(mContext).getSystemService(UiModeManager.class);
+ doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
+ when(mPowerManager.isPowerSaveMode()).thenReturn(false);
// Set-up specs for SliceMetadata.
SliceProvider.setSpecs(SliceLiveData.SUPPORTED_SPECS);
- mDarkThemeSlice = new DarkThemeSlice(mContext);
+ mDarkThemeSlice = spy(new DarkThemeSlice(mContext));
mDarkThemeSlice.sKeepSliceShow = false;
}
@@ -80,7 +81,7 @@ public class DarkThemeSliceTest {
@Test
public void isAvailable_inDarkThemeMode_returnFalse() {
- when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+ doReturn(true).when(mDarkThemeSlice).isDarkThemeMode(mContext);
assertThat(mDarkThemeSlice.isAvailable(mContext)).isFalse();
}
@@ -100,23 +101,36 @@ public class DarkThemeSliceTest {
}
@Test
- public void getSlice_notAvailable_returnNull() {
- when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+ public void getSlice_batterySaver_returnErrorSlice() {
+ when(mPowerManager.isPowerSaveMode()).thenReturn(true);
- assertThat(mDarkThemeSlice.getSlice()).isNull();
+ final Slice mediaSlice = mDarkThemeSlice.getSlice();
+ final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice);
+ assertThat(metadata.isErrorSlice()).isTrue();
}
@Test
- public void getSlice_newSession_notAvailable_returnNull() {
+ public void getSlice_notAvailable_returnErrorSlice() {
+ doReturn(true).when(mDarkThemeSlice).isDarkThemeMode(mContext);
+
+ final Slice mediaSlice = mDarkThemeSlice.getSlice();
+ final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice);
+ assertThat(metadata.isErrorSlice()).isTrue();
+ }
+
+ @Test
+ public void getSlice_newSession_notAvailable_returnErrorSlice() {
// previous displayed: yes
mDarkThemeSlice.sKeepSliceShow = true;
// Session: use original value + 1 to become a new session
mDarkThemeSlice.sActiveUiSession =
mFeatureFactory.slicesFeatureProvider.getUiSessionToken() + 1;
- when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_YES);
+ doReturn(true).when(mDarkThemeSlice).isDarkThemeMode(mContext);
- assertThat(mDarkThemeSlice.getSlice()).isNull();
+ final Slice mediaSlice = mDarkThemeSlice.getSlice();
+ final SliceMetadata metadata = SliceMetadata.from(mContext, mediaSlice);
+ assertThat(metadata.isErrorSlice()).isTrue();
}
@Test
@@ -149,7 +163,7 @@ public class DarkThemeSliceTest {
}
private void setBatteryCapacityLevel(int power_level) {
- when(mUiModeManager.getNightMode()).thenReturn(UiModeManager.MODE_NIGHT_NO);
+ doReturn(false).when(mDarkThemeSlice).isDarkThemeMode(mContext);
doReturn(mBatteryManager).when(mContext).getSystemService(BatteryManager.class);
when(mBatteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY))
.thenReturn(power_level);
diff --git a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
index 8ad21569401..a4b7aa551bb 100644
--- a/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
+++ b/tests/robotests/src/com/android/settings/panel/SettingsPanelActivityTest.java
@@ -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 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 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 paramCaptor = ArgumentCaptor.forClass(
+ WindowManager.LayoutParams.class);
+
+ verify(window).setAttributes(paramCaptor.capture());
+ assertThat(paramCaptor.getValue().privateFlags
+ & SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS).isEqualTo(0);
+ }
}
diff --git a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
deleted file mode 100644
index 1335db5c5ed..00000000000
--- a/tests/robotests/src/com/android/settings/privacy/PermissionBarChartPreferenceControllerTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.privacy;
-
-import static android.Manifest.permission_group.CALENDAR;
-import static android.Manifest.permission_group.CAMERA;
-import static android.Manifest.permission_group.CONTACTS;
-import static android.Manifest.permission_group.LOCATION;
-import static android.Manifest.permission_group.MICROPHONE;
-import static android.Manifest.permission_group.PHONE;
-import static android.Manifest.permission_group.SMS;
-
-import static com.android.settings.core.BasePreferenceController.AVAILABLE_UNSEARCHABLE;
-import static com.android.settings.core.BasePreferenceController.UNSUPPORTED_ON_DEVICE;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.UserManager;
-import android.permission.RuntimePermissionUsageInfo;
-import android.provider.DeviceConfig;
-import android.view.accessibility.AccessibilityManager;
-
-import androidx.preference.PreferenceScreen;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.Utils;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowDeviceConfig;
-import com.android.settings.testutils.shadow.ShadowPermissionControllerManager;
-import com.android.settings.testutils.shadow.ShadowUserManager;
-import com.android.settingslib.widget.BarChartInfo;
-import com.android.settingslib.widget.BarChartPreference;
-import com.android.settingslib.widget.BarViewInfo;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowAccessibilityManager;
-import org.robolectric.shadows.androidx.fragment.FragmentController;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowDeviceConfig.class, ShadowUserManager.class,
- ShadowPermissionControllerManager.class})
-public class PermissionBarChartPreferenceControllerTest {
-
- @Mock
- private PreferenceScreen mScreen;
- @Mock
- private LockPatternUtils mLockPatternUtils;
-
- private PermissionBarChartPreferenceController mController;
- private BarChartPreference mPreference;
- private PrivacyDashboardFragment mFragment;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- final Context context = RuntimeEnvironment.application;
- final UserManager userManager = context.getSystemService(UserManager.class);
- final ShadowUserManager shadowUserManager = Shadow.extract(userManager);
- final ShadowAccessibilityManager accessibilityManager = Shadow.extract(
- AccessibilityManager.getInstance(context));
- accessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>());
- shadowUserManager.addProfile(new UserInfo(123, null, 0));
- when(FakeFeatureFactory.setupForTest().securityFeatureProvider.getLockPatternUtils(
- any(Context.class))).thenReturn(mLockPatternUtils);
-
- mController = spy(new PermissionBarChartPreferenceController(context, "test_key"));
- mFragment = spy(FragmentController.of(new PrivacyDashboardFragment())
- .create().start().get());
- mController.setFragment(mFragment);
- mPreference = spy(new BarChartPreference(context));
- when(mScreen.findPreference(mController.getPreferenceKey()))
- .thenReturn((BarChartPreference) mPreference);
- }
-
- @After
- public void tearDown() {
- ShadowDeviceConfig.reset();
- }
-
- @Test
- public void getAvailabilityStatus_permissionHubNotSet_shouldReturnUnsupported() {
- // We have not yet set the property to show the Permissions Hub.
- assertThat(mController.getAvailabilityStatus()).isEqualTo(UNSUPPORTED_ON_DEVICE);
- }
-}
diff --git a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java b/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
deleted file mode 100644
index 80f3900e00d..00000000000
--- a/tests/robotests/src/com/android/settings/privacy/PrivacyDashboardFragmentTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.settings.privacy;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.pm.UserInfo;
-import android.os.Bundle;
-import android.os.UserManager;
-import android.permission.PermissionControllerManager;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.settings.testutils.FakeFeatureFactory;
-import com.android.settings.testutils.shadow.ShadowPermissionControllerManager;
-import com.android.settings.testutils.shadow.ShadowUserManager;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
-import org.robolectric.annotation.Config;
-import org.robolectric.shadow.api.Shadow;
-import org.robolectric.shadows.ShadowAccessibilityManager;
-import org.robolectric.shadows.androidx.fragment.FragmentController;
-
-import java.util.ArrayList;
-
-
-@RunWith(RobolectricTestRunner.class)
-@Config(shadows = {ShadowUserManager.class, ShadowPermissionControllerManager.class})
-public class PrivacyDashboardFragmentTest {
-
- @Mock
- private LockPatternUtils mLockPatternUtils;
- @Mock
- private PermissionControllerManager mPCM;
-
- private Context mContext;
- private PrivacyDashboardFragment mFragment;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mContext = RuntimeEnvironment.application;
- final UserManager userManager = mContext.getSystemService(UserManager.class);
- final ShadowUserManager shadowUserManager = Shadow.extract(userManager);
- final ShadowAccessibilityManager accessibilityManager = Shadow.extract(
- AccessibilityManager.getInstance(mContext));
- accessibilityManager.setEnabledAccessibilityServiceList(new ArrayList<>());
- shadowUserManager.addProfile(new UserInfo(123, null, 0));
- when(FakeFeatureFactory.setupForTest().securityFeatureProvider.getLockPatternUtils(
- any(Context.class))).thenReturn(mLockPatternUtils);
- mFragment = spy(FragmentController.of(new PrivacyDashboardFragment())
- .create().start().get());
- }
-
- @Test
- public void onViewCreated_shouldSetActionBarShadowAnimation() {
- mFragment.onViewCreated(new View(mContext), new Bundle());
-
- assertThat(mFragment.getActivity().getActionBar().getElevation()).isEqualTo(0.f);
- }
-
- @Test
- public void onViewCreated_shouldInitLinearProgressBar() {
- mFragment.onViewCreated(new View(mContext), new Bundle());
-
- verify(mFragment).initLoadingBar();
- }
-
- @Test
- public void updateLinearProgressbar_isVisible_shouldShowProgressBar() {
- mFragment.setLoadingEnabled(true /* enabled */);
-
- assertThat(mFragment.mProgressHeader.getVisibility()).isEqualTo(View.VISIBLE);
- assertThat(mFragment.mProgressAnimation.getVisibility()).isEqualTo(View.VISIBLE);
- }
-
- @Test
- public void updateLinearProgressbar_isInVisible_shouldHideProgressBar() {
- mFragment.setLoadingEnabled(false /* enabled */);
-
- assertThat(mFragment.mProgressHeader.getVisibility()).isEqualTo(View.INVISIBLE);
- assertThat(mFragment.mProgressAnimation.getVisibility()).isEqualTo(View.INVISIBLE);
- }
-}