Merge "Revert "[Provider Model] Replace WiFi panel to Internet panel"" into sc-dev
diff --git a/res/drawable/ic_no_internet_airplane.xml b/res/drawable/ic_no_internet_airplane.xml
deleted file mode 100644
index 3b22811..0000000
--- a/res/drawable/ic_no_internet_airplane.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
- Copyright (C) 2021 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24.0"
- android:viewportHeight="24.0">
- <path
- android:fillColor="#FF000000"
- android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10c0.34,0 0.68,-0.02 1.01,-0.05V20h-1v-0.04c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96H13v-2H9.66c-0.09,-0.66 -0.16,-1.32 -0.16,-2s0.07,-1.35 0.16,-2H21.8C20.87,5.44 16.83,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56C16.43,5.07 17.96,6.35 18.92,8zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82C10.52,6.57 11.17,5.24 12,4.04zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2s0.06,1.34 0.14,2H4.26zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56C7.57,18.93 6.04,17.66 5.08,16zM8.03,8H5.08c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8z"
- android:fillAlpha="0.3"/>
- <path
- android:fillColor="#FF000000"
- android:pathData="M22,19.3v-0.9l-3.37,-2.25v-2.47C18.63,13.3 18.35,13 18,13s-0.63,0.3 -0.63,0.68v2.47L14,18.4v0.9l3.37,-1.12v2.48l-0.84,0.68V22L18,21.55L19.47,22v-0.67l-0.84,-0.68v-2.48L22,19.3z"/>
-</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_no_internet_unavailable.xml b/res/drawable/ic_no_internet_unavailable.xml
new file mode 100644
index 0000000..049034a
--- /dev/null
+++ b/res/drawable/ic_no_internet_unavailable.xml
@@ -0,0 +1,28 @@
+<!--
+ Copyright (C) 2021 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M2,12C2,6.48 6.47,2 11.99,2C17.52,2 22,6.48 22,12c0,0.34 -0.02,0.67 -0.05,1h-2.02c0.04,-0.33 0.07,-0.66 0.07,-1c0,-0.69 -0.1,-1.36 -0.26,-2h-3.38c0.08,0.66 0.14,1.32 0.14,2c0,0.34 -0.01,0.67 -0.04,1h-2.01c0.03,-0.33 0.05,-0.66 0.05,-1c0,-0.68 -0.07,-1.35 -0.16,-2H9.66c-0.09,0.65 -0.16,1.32 -0.16,2s0.07,1.34 0.16,2H13v2h-2.91c0.43,1.43 1.08,2.76 1.91,3.96V20h1v1.95C12.67,21.98 12.33,22 11.99,22C6.47,22 2,17.52 2,12zM15.97,8h2.95c-0.96,-1.65 -2.49,-2.93 -4.33,-3.56C15.19,5.55 15.65,6.75 15.97,8zM13.91,8C13.48,6.57 12.83,5.24 12,4.04c-0.83,1.2 -1.48,2.53 -1.91,3.96H13.91zM4,12c0,0.69 0.1,1.36 0.26,2h3.38c-0.08,-0.66 -0.14,-1.32 -0.14,-2s0.06,-1.34 0.14,-2H4.26C4.1,10.64 4,11.31 4,12zM8.03,16H5.08c0.96,1.66 2.49,2.93 4.33,3.56C8.81,18.45 8.35,17.25 8.03,16zM5.08,8h2.95c0.32,-1.25 0.78,-2.45 1.38,-3.56C7.57,5.07 6.04,6.34 5.08,8z"
+ android:fillAlpha="0.3"/>
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09,-2.08L20.59,22L22,20.59l-2.08,-2.09L22,16.41z"/>
+</vector>
diff --git a/res/drawable/progress_horizontal.xml b/res/drawable/progress_horizontal.xml
deleted file mode 100644
index f2a4cc4..0000000
--- a/res/drawable/progress_horizontal.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2021 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.
--->
-
-<layer-list
- xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-
- <item
- android:id="@android:id/background">
- <shape>
- <corners android:radius="8dp" />
- <solid android:color="?androidprv:attr/colorSurfaceVariant" />
- </shape>
- </item>
-
- <item
- android:id="@android:id/progress">
- <clip>
- <shape>
- <corners android:radius="8dp" />
- <solid android:color="?android:attr/textColorPrimary" />
- </shape>
- </clip>
- </item>
-</layer-list>
diff --git a/res/layout/manage_apps_filter_spinner.xml b/res/layout/manage_apps_filter_spinner.xml
new file mode 100644
index 0000000..8283bb8
--- /dev/null
+++ b/res/layout/manage_apps_filter_spinner.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 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.
+-->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@android:color/transparent">
+
+ <com.android.settingslib.widget.settingsspinner.SettingsSpinner
+ android:id="@+id/filter_spinner"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginStart="24dp"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="8dp"
+ android:theme="@style/Widget.PopupWindow.Settings"/>
+</FrameLayout>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index c20b0dc..63ea86e 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -405,12 +405,6 @@
<item name="android:progressDrawable">@drawable/ring_progress</item>
</style>
- <style name="HorizontalProgressBarStyle"
- parent="android:style/Widget.Material.ProgressBar.Horizontal">
- <item name="android:progressDrawable">@drawable/progress_horizontal</item>
- <item name="android:scaleY">0.5</item>
- </style>
-
<style name="ActionPrimaryButton" parent="android:Widget.DeviceDefault.Button.Colored">
<item name="android:theme">@style/RoundedCornerThemeOverlay</item>
</style>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index df7d433..4c5cdb7 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -32,7 +32,6 @@
<item name="android:homeAsUpIndicator">@drawable/ic_arrow_back</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:datePickerDialogTheme">@style/PickerDialogTheme.Settings</item>
- <item name="android:progressBarStyleHorizontal">@style/HorizontalProgressBarStyle</item>
<item name="fingerprint_layout_theme">@style/FingerprintLayoutTheme</item>
<item name="face_layout_theme">@style/FaceLayoutTheme</item>
diff --git a/src/com/android/settings/accounts/EnterpriseDisclosurePreferenceController.java b/src/com/android/settings/accounts/EnterpriseDisclosurePreferenceController.java
index b4dbf3d..238e937 100644
--- a/src/com/android/settings/accounts/EnterpriseDisclosurePreferenceController.java
+++ b/src/com/android/settings/accounts/EnterpriseDisclosurePreferenceController.java
@@ -17,16 +17,19 @@
package com.android.settings.accounts;
import android.content.Context;
+import android.content.Intent;
+import android.provider.Settings;
import androidx.annotation.VisibleForTesting;
-import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
+import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
import com.android.settings.overlay.FeatureFactory;
+import com.android.settingslib.widget.FooterPreference;
public class EnterpriseDisclosurePreferenceController extends BasePreferenceController {
-
private final EnterprisePrivacyFeatureProvider mFeatureProvider;
public EnterpriseDisclosurePreferenceController(Context context, String key) {
@@ -37,6 +40,16 @@
}
@Override
+ public void displayPreference(PreferenceScreen screen) {
+ super.displayPreference(screen);
+ final CharSequence disclosure = getDisclosure();
+ if (disclosure == null) {
+ return;
+ }
+ updateFooterPreference(screen, disclosure);
+ }
+
+ @Override
public int getAvailabilityStatus() {
if (getDisclosure() == null) {
return UNSUPPORTED_ON_DEVICE;
@@ -49,12 +62,18 @@
return mFeatureProvider.getDeviceOwnerDisclosure();
}
- @Override
- public void updateState(Preference preference) {
- final CharSequence disclosure = getDisclosure();
- if (disclosure == null) {
- return;
- }
- preference.setTitle(disclosure);
+ void updateFooterPreference(PreferenceScreen screen, CharSequence disclosure) {
+ final FooterPreference footerPreference = screen.findPreference(getPreferenceKey());
+ footerPreference.setTitle(disclosure);
+ footerPreference.setLearnMoreAction(view -> {
+ mContext.startActivity(new Intent(Settings.ACTION_ENTERPRISE_PRIVACY_SETTINGS));
+ });
+ final String learnMoreContentDescription = mContext.getString(
+ R.string.footer_learn_more_content_description, getLabelName());
+ footerPreference.setLearnMoreContentDescription(learnMoreContentDescription);
+ }
+
+ private String getLabelName() {
+ return mContext.getString(R.string.header_add_an_account);
}
}
diff --git a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
index 79cae92..1f0777a 100644
--- a/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
+++ b/src/com/android/settings/applications/appinfo/AppBatteryPreferenceController.java
@@ -118,7 +118,8 @@
final UserManager userManager =
(UserManager) mContext.getSystemService(Context.USER_SERVICE);
final BatteryEntry entry = new BatteryEntry(mContext, /* handler */null, userManager,
- mUidBatteryConsumer, /* isHidden */ false, /* packages */ null, mPackageName);
+ mUidBatteryConsumer, /* isHidden */ false,
+ mUidBatteryConsumer.getUid(), /* packages */ null, mPackageName);
AdvancedPowerUsageDetail.startBatteryDetailPage(mParent.getActivity(), mParent,
entry, mBatteryPercent);
} else {
diff --git a/src/com/android/settings/applications/manageapplications/ManageApplications.java b/src/com/android/settings/applications/manageapplications/ManageApplications.java
index 62513db..7509a78 100644
--- a/src/com/android/settings/applications/manageapplications/ManageApplications.java
+++ b/src/com/android/settings/applications/manageapplications/ManageApplications.java
@@ -434,7 +434,7 @@
final Activity activity = getActivity();
final FrameLayout pinnedHeader = mRootView.findViewById(R.id.pinned_header);
mSpinnerHeader = activity.getLayoutInflater()
- .inflate(R.layout.apps_filter_spinner, pinnedHeader, false);
+ .inflate(R.layout.manage_apps_filter_spinner, pinnedHeader, false);
mFilterSpinner = mSpinnerHeader.findViewById(R.id.filter_spinner);
mFilterAdapter = new FilterSpinnerAdapter(this);
mFilterSpinner.setAdapter(mFilterAdapter);
diff --git a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
index 8c25a05..f8d5f96 100644
--- a/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
+++ b/src/com/android/settings/display/SmartAutoRotatePreferenceController.java
@@ -16,15 +16,25 @@
package com.android.settings.display;
+import static android.hardware.SensorPrivacyManager.Sensors.CAMERA;
import static android.provider.Settings.Secure.CAMERA_AUTOROTATE;
+import static com.android.settings.display.SmartAutoRotateController.hasSufficientPermission;
+import static com.android.settings.display.SmartAutoRotateController.isRotationResolverServiceAvailable;
+
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.SensorPrivacyManager;
+import android.os.PowerManager;
import android.os.UserHandle;
import android.provider.Settings;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.view.RotationPolicy;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
@@ -41,8 +51,21 @@
private RotationPolicy.RotationPolicyListener mRotationPolicyListener;
private Preference mPreference;
+ private final SensorPrivacyManager mPrivacyManager;
+ private final PowerManager mPowerManager;
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ refreshSummary(mPreference);
+ }
+ };
+
public SmartAutoRotatePreferenceController(Context context, String preferenceKey) {
super(context, preferenceKey);
+ mPrivacyManager = SensorPrivacyManager.getInstance(context);
+ mPrivacyManager
+ .addSensorPrivacyListener(CAMERA, (sensor, enabled) -> refreshSummary(mPreference));
+ mPowerManager = context.getSystemService(PowerManager.class);
}
@Override
@@ -59,6 +82,8 @@
@Override
public void onStart() {
+ mContext.registerReceiver(mReceiver,
+ new IntentFilter(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
if (mRotationPolicyListener == null) {
mRotationPolicyListener = new RotationPolicy.RotationPolicyListener() {
@Override
@@ -75,12 +100,27 @@
@Override
public void onStop() {
+ mContext.unregisterReceiver(mReceiver);
if (mRotationPolicyListener != null) {
RotationPolicy.unregisterRotationPolicyListener(mContext,
mRotationPolicyListener);
}
}
+ /**
+ * Need this because all controller tests use Roboelectric. No easy way to mock this service,
+ * so we mock the call we need
+ */
+ @VisibleForTesting
+ boolean isCameraLocked() {
+ return mPrivacyManager.isSensorPrivacyEnabled(SensorPrivacyManager.Sensors.CAMERA);
+ }
+
+ @VisibleForTesting
+ boolean isPowerSaveMode() {
+ return mPowerManager.isPowerSaveMode();
+ }
+
@Override
public CharSequence getSummary() {
int activeStringId = R.string.auto_rotate_option_off;
@@ -89,7 +129,11 @@
mContext.getContentResolver(),
CAMERA_AUTOROTATE,
0, UserHandle.USER_CURRENT);
- activeStringId = cameraRotate == 1 ? R.string.auto_rotate_option_face_based
+ activeStringId = cameraRotate == 1 && isRotationResolverServiceAvailable(mContext)
+ && hasSufficientPermission(mContext)
+ && !isCameraLocked()
+ && !isPowerSaveMode()
+ ? R.string.auto_rotate_option_face_based
: R.string.auto_rotate_option_on;
}
return mContext.getString(activeStringId);
diff --git a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
index f461fe1..7d722fc 100644
--- a/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
+++ b/src/com/android/settings/enterprise/EnterprisePrivacyFeatureProviderImpl.java
@@ -100,9 +100,6 @@
} else {
disclosure.append(mResources.getString(R.string.do_disclosure_generic));
}
- disclosure.append(mResources.getString(R.string.do_disclosure_learn_more_separator));
- disclosure.append(mResources.getString(R.string.learn_more),
- new EnterprisePrivacySpan(mContext), 0);
return disclosure;
}
diff --git a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
index 891b6d6..1dc572d 100644
--- a/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/BatteryAppListPreferenceController.java
@@ -55,6 +55,7 @@
import com.android.settingslib.utils.StringUtil;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
/**
@@ -66,6 +67,7 @@
static final boolean USE_FAKE_DATA = false;
private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 20;
private static final int MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP = 10;
+ private static final String MEDIASERVER_PACKAGE_NAME = "mediaserver";
private final String mPreferenceKey;
@VisibleForTesting
@@ -303,27 +305,17 @@
final ArrayList<BatteryEntry> results = new ArrayList<>();
final List<UidBatteryConsumer> uidBatteryConsumers =
mBatteryUsageStats.getUidBatteryConsumers();
+
+ // Sort to have all apps with "real" UIDs first, followed by apps that are supposed
+ // to be combined with the real ones.
+ uidBatteryConsumers.sort(Comparator.comparingInt(
+ consumer -> consumer.getUid() == getRealUid(consumer) ? 0 : 1));
+
for (int i = 0, size = uidBatteryConsumers.size(); i < size; i++) {
final UidBatteryConsumer consumer = uidBatteryConsumers.get(i);
- int realUid = consumer.getUid();
+ final int uid = getRealUid(consumer);
- // Check if this UID is a shared GID. If so, we combine it with the OWNER's
- // actual app UID.
- if (isSharedGid(consumer.getUid())) {
- realUid = UserHandle.getUid(UserHandle.USER_SYSTEM,
- UserHandle.getAppIdFromSharedAppGid(consumer.getUid()));
- }
-
- // Check if this UID is a system UID (mediaserver, logd, nfc, drm, etc).
- if (isSystemUid(realUid)
- && !"mediaserver".equals(consumer.getPackageWithHighestDrain())) {
- // Use the system UID for all UIDs running in their own sandbox that
- // are not apps. We exclude mediaserver because we already are expected to
- // report that as a separate item.
- realUid = Process.SYSTEM_UID;
- }
-
- final String[] packages = mPackageManager.getPackagesForUid(consumer.getUid());
+ final String[] packages = mPackageManager.getPackagesForUid(uid);
if (mBatteryUtils.shouldHideUidBatteryConsumerUnconditionally(consumer, packages)) {
continue;
}
@@ -333,11 +325,11 @@
continue;
}
- final int index = batteryEntryList.indexOfKey(realUid);
+ final int index = batteryEntryList.indexOfKey(uid);
if (index < 0) {
// New entry.
- batteryEntryList.put(realUid, new BatteryEntry(mContext, mHandler, mUserManager,
- consumer, isHidden, packages, null, loadDataInBackground));
+ batteryEntryList.put(uid, new BatteryEntry(mContext, mHandler, mUserManager,
+ consumer, isHidden, uid, packages, null, loadDataInBackground));
} else {
// Combine BatterySippers if we already have one with this UID.
final BatteryEntry existingSipper = batteryEntryList.valueAt(index);
@@ -385,7 +377,8 @@
for (int i = 0, size = userBatteryConsumers.size(); i < size; i++) {
final UserBatteryConsumer consumer = userBatteryConsumers.get(i);
results.add(new BatteryEntry(mContext, mHandler, mUserManager,
- consumer, /* isHidden */ true, null, null, loadDataInBackground));
+ consumer, /* isHidden */ true, Process.INVALID_UID, null, null,
+ loadDataInBackground));
}
}
@@ -400,6 +393,27 @@
return results;
}
+ private int getRealUid(UidBatteryConsumer consumer) {
+ int realUid = consumer.getUid();
+
+ // Check if this UID is a shared GID. If so, we combine it with the OWNER's
+ // actual app UID.
+ if (isSharedGid(consumer.getUid())) {
+ realUid = UserHandle.getUid(UserHandle.USER_SYSTEM,
+ UserHandle.getAppIdFromSharedAppGid(consumer.getUid()));
+ }
+
+ // Check if this UID is a system UID (mediaserver, logd, nfc, drm, etc).
+ if (isSystemUid(realUid)
+ && !MEDIASERVER_PACKAGE_NAME.equals(consumer.getPackageWithHighestDrain())) {
+ // Use the system UID for all UIDs running in their own sandbox that
+ // are not apps. We exclude mediaserver because we already are expected to
+ // report that as a separate item.
+ realUid = Process.SYSTEM_UID;
+ }
+ return realUid;
+ }
+
@VisibleForTesting
void setUsageSummary(Preference preference, BatteryEntry entry) {
// Only show summary when usage time is longer than one minute
diff --git a/src/com/android/settings/fuelgauge/BatteryEntry.java b/src/com/android/settings/fuelgauge/BatteryEntry.java
index 78ab962..0478c8b 100644
--- a/src/com/android/settings/fuelgauge/BatteryEntry.java
+++ b/src/com/android/settings/fuelgauge/BatteryEntry.java
@@ -159,12 +159,15 @@
private final Context mContext;
private final BatteryConsumer mBatteryConsumer;
+ private final int mUid;
private final boolean mIsHidden;
@ConvertUtils.ConsumerType
private final int mConsumerType;
@BatteryConsumer.PowerComponent
private final int mPowerComponentId;
private long mUsageDurationMs;
+ private long mTimeInForegroundMs;
+ private long mTimeInBackgroundMs;
public String name;
public Drawable icon;
@@ -180,13 +183,13 @@
}
public BatteryEntry(Context context, Handler handler, UserManager um,
- @NonNull BatteryConsumer batteryConsumer, boolean isHidden, String[] packages,
+ @NonNull BatteryConsumer batteryConsumer, boolean isHidden, int uid, String[] packages,
String packageName) {
- this(context, handler, um, batteryConsumer, isHidden, packages, packageName, true);
+ this(context, handler, um, batteryConsumer, isHidden, uid, packages, packageName, true);
}
public BatteryEntry(Context context, Handler handler, UserManager um,
- @NonNull BatteryConsumer batteryConsumer, boolean isHidden, String[] packages,
+ @NonNull BatteryConsumer batteryConsumer, boolean isHidden, int uid, String[] packages,
String packageName, boolean loadDataInBackground) {
sHandler = handler;
mContext = context;
@@ -196,11 +199,11 @@
mPowerComponentId = -1;
if (batteryConsumer instanceof UidBatteryConsumer) {
+ mUid = uid;
mConsumerType = ConvertUtils.CONSUMER_TYPE_UID_BATTERY;
mConsumedPower = batteryConsumer.getConsumedPower();
UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer;
- int uid = uidBatteryConsumer.getUid();
if (mDefaultPackageName == null) {
// Apps should only have one package
if (packages != null && packages.length == 1) {
@@ -222,7 +225,12 @@
}
}
getQuickNameIconForUid(uid, packages, loadDataInBackground);
+ mTimeInForegroundMs =
+ uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND);
+ mTimeInBackgroundMs =
+ uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND);
} else if (batteryConsumer instanceof UserBatteryConsumer) {
+ mUid = Process.INVALID_UID;
mConsumerType = ConvertUtils.CONSUMER_TYPE_USER_BATTERY;
mConsumedPower = batteryConsumer.getConsumedPower();
final NameAndIcon nameAndIcon = getNameAndIconFromUserId(
@@ -239,6 +247,7 @@
double appsPowerMah, long usageDurationMs) {
mContext = context;
mBatteryConsumer = null;
+ mUid = Process.INVALID_UID;
mIsHidden = false;
mPowerComponentId = powerComponentId;
mConsumedPower =
@@ -261,6 +270,7 @@
double devicePowerMah, double appsPowerMah) {
mContext = context;
mBatteryConsumer = null;
+ mUid = Process.INVALID_UID;
mIsHidden = false;
mPowerComponentId = powerComponentId;
@@ -438,7 +448,7 @@
*/
public String getKey() {
if (mBatteryConsumer instanceof UidBatteryConsumer) {
- return Integer.toString(((UidBatteryConsumer) mBatteryConsumer).getUid());
+ return Integer.toString(mUid);
} else if (mBatteryConsumer instanceof UserBatteryConsumer) {
return "U|" + ((UserBatteryConsumer) mBatteryConsumer).getUserId();
} else {
@@ -482,11 +492,7 @@
* Returns the UID of the app described by this entry.
*/
public int getUid() {
- if (mBatteryConsumer instanceof UidBatteryConsumer) {
- return ((UidBatteryConsumer) mBatteryConsumer).getUid();
- } else {
- return Process.INVALID_UID;
- }
+ return mUid;
}
/**
@@ -494,8 +500,7 @@
*/
public long getTimeInForegroundMs() {
if (mBatteryConsumer instanceof UidBatteryConsumer) {
- return ((UidBatteryConsumer) mBatteryConsumer).getTimeInStateMs(
- UidBatteryConsumer.STATE_FOREGROUND);
+ return mTimeInForegroundMs;
} else {
return mUsageDurationMs;
}
@@ -506,8 +511,7 @@
*/
public long getTimeInBackgroundMs() {
if (mBatteryConsumer instanceof UidBatteryConsumer) {
- return ((UidBatteryConsumer) mBatteryConsumer).getTimeInStateMs(
- UidBatteryConsumer.STATE_BACKGROUND);
+ return mTimeInBackgroundMs;
} else {
return 0;
}
@@ -526,9 +530,15 @@
*/
public void add(BatteryConsumer batteryConsumer) {
mConsumedPower += batteryConsumer.getConsumedPower();
- if (mDefaultPackageName == null && batteryConsumer instanceof UidBatteryConsumer) {
- mDefaultPackageName =
- ((UidBatteryConsumer) batteryConsumer).getPackageWithHighestDrain();
+ if (batteryConsumer instanceof UidBatteryConsumer) {
+ UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer;
+ mTimeInForegroundMs += uidBatteryConsumer.getTimeInStateMs(
+ UidBatteryConsumer.STATE_FOREGROUND);
+ mTimeInBackgroundMs += uidBatteryConsumer.getTimeInStateMs(
+ UidBatteryConsumer.STATE_BACKGROUND);
+ if (mDefaultPackageName == null) {
+ mDefaultPackageName = uidBatteryConsumer.getPackageWithHighestDrain();
+ }
}
}
diff --git a/src/com/android/settings/network/InternetPreferenceController.java b/src/com/android/settings/network/InternetPreferenceController.java
index 639bab5..a58e69a 100644
--- a/src/com/android/settings/network/InternetPreferenceController.java
+++ b/src/com/android/settings/network/InternetPreferenceController.java
@@ -65,7 +65,7 @@
@VisibleForTesting
static Map<Integer, Integer> sIconMap = new HashMap<>();
static {
- sIconMap.put(INTERNET_OFF, R.drawable.ic_no_internet_airplane);
+ sIconMap.put(INTERNET_OFF, R.drawable.ic_no_internet_unavailable);
sIconMap.put(INTERNET_NETWORKS_AVAILABLE, R.drawable.ic_no_internet_available);
sIconMap.put(INTERNET_WIFI, R.drawable.ic_wifi_signal_4);
sIconMap.put(INTERNET_CELLULAR, R.drawable.ic_network_cell);
diff --git a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
index ced198b..7bf680d 100644
--- a/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
+++ b/src/com/android/settings/wifi/details2/WifiDetailPreferenceController2.java
@@ -63,6 +63,7 @@
import androidx.preference.PreferenceCategory;
import androidx.preference.PreferenceFragmentCompat;
import androidx.preference.PreferenceScreen;
+import androidx.recyclerview.widget.RecyclerView;
import com.android.net.module.util.Inet4AddressUtils;
import com.android.settings.R;
@@ -513,6 +514,12 @@
@Override
public void onResume() {
+ // Disable the animation of the EntityHeaderController
+ final RecyclerView recyclerView = mFragment.getListView();
+ if (recyclerView != null) {
+ recyclerView.setItemAnimator(null);
+ }
+
// Ensure mNetwork is set before any callbacks above are delivered, since our
// NetworkCallback only looks at changes to mNetwork.
updateNetworkInfo();
diff --git a/tests/robotests/src/com/android/settings/accounts/EnterpriseDisclosurePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/accounts/EnterpriseDisclosurePreferenceControllerTest.java
index b10a729..8860cfe 100644
--- a/tests/robotests/src/com/android/settings/accounts/EnterpriseDisclosurePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/accounts/EnterpriseDisclosurePreferenceControllerTest.java
@@ -19,20 +19,25 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import android.content.Context;
-import androidx.preference.Preference;
+import androidx.preference.PreferenceScreen;
import com.android.settings.core.BasePreferenceController;
+import com.android.settingslib.widget.FooterPreference;
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;
@@ -42,13 +47,18 @@
private Context mContext;
private EnterpriseDisclosurePreferenceController mController;
- private Preference mPreference;
+ private FooterPreference mPreference;
+
+ @Mock
+ private PreferenceScreen mPreferenceScreen;
@Before
public void setUp() {
+ MockitoAnnotations.initMocks(this);
mContext = RuntimeEnvironment.application;
mController = spy(new EnterpriseDisclosurePreferenceController(mContext, "my_key"));
- mPreference = spy(new Preference(mContext));
+ mPreference = spy(new FooterPreference(mContext));
+ when(mPreferenceScreen.findPreference(anyString())).thenReturn(mPreference);
}
@Test
@@ -68,19 +78,19 @@
}
@Test
- public void updateState_hasDisclosure_shouldSetTitle() {
+ public void displayPreference_hasDisclosure_shouldSetTitle() {
doReturn(TEST_DISCLOSURE).when(mController).getDisclosure();
- mController.updateState(mPreference);
+ mController.displayPreference(mPreferenceScreen);
assertThat(mPreference.getTitle()).isEqualTo(TEST_DISCLOSURE);
}
@Test
- public void updateState_noDisclosure_shouldBeInvisible() {
+ public void displayPreference_noDisclosure_shouldBeInvisible() {
doReturn(null).when(mController).getDisclosure();
- mController.updateState(mPreference);
+ mController.displayPreference(mPreferenceScreen);
verify(mPreference, never()).setTitle(any());
}
diff --git a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
index cc3b20d..068de34 100644
--- a/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/display/SmartAutoRotatePreferenceControllerTest.java
@@ -20,46 +20,65 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
+import android.Manifest;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
import android.os.UserHandle;
import android.provider.Settings;
import com.android.settings.R;
import com.android.settings.core.BasePreferenceController;
import com.android.settings.testutils.FakeFeatureFactory;
+import com.android.settings.testutils.ResolveInfoBuilder;
+import com.android.settings.testutils.shadow.ShadowSensorPrivacyManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Answers;
import org.mockito.Mock;
+import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
@RunWith(RobolectricTestRunner.class)
+@Config(shadows = ShadowSensorPrivacyManager.class)
public class SmartAutoRotatePreferenceControllerTest {
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private Context mContext;
+ private static final String PACKAGE_NAME = "package_name";
@Mock
private PackageManager mPackageManager;
+ @Mock
+ private Resources mResources;
+ private Context mContext;
private ContentResolver mContentResolver;
private SmartAutoRotatePreferenceController mController;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ mContext = Mockito.spy(RuntimeEnvironment.application);
FakeFeatureFactory.setupForTest();
mContentResolver = RuntimeEnvironment.application.getContentResolver();
+
when(mContext.getPackageManager()).thenReturn(mPackageManager);
+ when(mContext.getResources()).thenReturn(mResources);
when(mContext.getContentResolver()).thenReturn(mContentResolver);
+
+ doReturn(PACKAGE_NAME).when(mPackageManager).getRotationResolverPackageName();
+ doReturn(PackageManager.PERMISSION_GRANTED).when(mPackageManager).checkPermission(
+ Manifest.permission.CAMERA, PACKAGE_NAME);
when(mContext.getString(R.string.auto_rotate_option_off))
.thenReturn("Off");
when(mContext.getString(R.string.auto_rotate_option_on))
@@ -68,8 +87,14 @@
.thenReturn("On - Face-based");
disableCameraBasedRotation();
+ final ResolveInfo resolveInfo = new ResolveInfoBuilder(PACKAGE_NAME).build();
+ resolveInfo.serviceInfo = new ServiceInfo();
+ when(mPackageManager.resolveService(any(), anyInt())).thenReturn(resolveInfo);
- mController = new SmartAutoRotatePreferenceController(mContext, "smart_auto_rotate");
+ mController = Mockito.spy(
+ new SmartAutoRotatePreferenceController(mContext, "smart_auto_rotate"));
+ when(mController.isCameraLocked()).thenReturn(false);
+ when(mController.isPowerSaveMode()).thenReturn(false);
}
@Test
@@ -82,33 +107,37 @@
}
@Test
- public void updatePreference_settingsIsOff_shouldTurnOffToggle() {
+ public void getSummary_settingsIsOff_returnsOff() {
disableAutoRotation();
assertThat(mController.getSummary()).isEqualTo("Off");
}
@Test
- public void updatePreference_settingsIsOn_shouldTurnOnToggle() {
+ public void getSummary_settingsIsOn_returnsOn() {
enableAutoRotation();
assertThat(mController.getSummary()).isEqualTo("On");
}
@Test
- public void updatePreference_settingsIsCameraBased_shouldTurnOnToggle() {
+ public void getSummary_autoRotateOffSmartAutoRotateOn_returnsOff() {
+ enableCameraBasedRotation();
+ disableAutoRotation();
+
+ assertThat(mController.getSummary()).isEqualTo("Off");
+ }
+
+ @Test
+ public void updatePreference_smartAutoRotateOn_returnsFaceBased() {
enableCameraBasedRotation();
enableAutoRotation();
assertThat(mController.getSummary()).isEqualTo("On - Face-based");
-
- disableAutoRotation();
-
- assertThat(mController.getSummary()).isEqualTo("Off");
}
@Test
- public void updatePreference_settingsIsOff_noSmartAuto_shouldTurnOffToggle() {
+ public void getSummary_noSmartAuto_returnsOff() {
disableAutoRotation();
Settings.Secure.putStringForUser(mContentResolver,
CAMERA_AUTOROTATE, null, UserHandle.USER_CURRENT);
@@ -118,7 +147,7 @@
}
@Test
- public void updatePreference_settingsIsOn_noSmartAuto_shouldTurnOnToggle() {
+ public void getSummary_noSmartAuto_returnsOn() {
enableAutoRotation();
Settings.Secure.putStringForUser(mContentResolver,
CAMERA_AUTOROTATE, null, UserHandle.USER_CURRENT);
@@ -127,6 +156,34 @@
}
@Test
+ public void getSummary_noCameraPermission_returnsOn() {
+ enableAutoRotation();
+ enableCameraBasedRotation();
+ doReturn(PackageManager.PERMISSION_DENIED).when(mPackageManager).checkPermission(
+ Manifest.permission.CAMERA, PACKAGE_NAME);
+
+ assertThat(mController.getSummary()).isEqualTo("On");
+ }
+
+ @Test
+ public void getSummary_cameraDisabled_returnsOn() {
+ enableAutoRotation();
+ enableCameraBasedRotation();
+ when(mController.isCameraLocked()).thenReturn(true);
+
+ assertThat(mController.getSummary()).isEqualTo("On");
+ }
+
+ @Test
+ public void getSummary_powerSaveEnabled_returnsOn() {
+ enableAutoRotation();
+ enableCameraBasedRotation();
+ when(mController.isPowerSaveMode()).thenReturn(true);
+
+ assertThat(mController.getSummary()).isEqualTo("On");
+ }
+
+ @Test
public void testGetAvailabilityStatus() {
assertThat(mController.getAvailabilityStatus()).isEqualTo(BasePreferenceController
.UNSUPPORTED_ON_DEVICE);
@@ -158,14 +215,14 @@
private void enableAutoRotationPreference() {
when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true);
- when(mContext.getResources().getBoolean(anyInt())).thenReturn(true);
+ when(mResources.getBoolean(anyInt())).thenReturn(true);
Settings.System.putInt(mContentResolver,
Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 0);
}
private void disableAutoRotationPreference() {
when(mPackageManager.hasSystemFeature(anyString())).thenReturn(true);
- when(mContext.getResources().getBoolean(anyInt())).thenReturn(true);
+ when(mResources.getBoolean(anyInt())).thenReturn(true);
Settings.System.putInt(mContentResolver,
Settings.System.HIDE_ROTATION_LOCK_TOGGLE_FOR_ACCESSIBILITY, 1);
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
index e0f8ba7..96f0ec7 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryEntryTest.java
@@ -93,7 +93,7 @@
when(consumer.getUid()).thenReturn(APP_UID);
when(consumer.getPackageWithHighestDrain()).thenReturn(highDrainPackage);
return new BatteryEntry(mMockContext, mockHandler, mockUserManager,
- consumer, false, packages, packageName);
+ consumer, false, APP_UID, packages, packageName);
}
private BatteryEntry createAggregateBatteryEntry(int powerComponentId) {
@@ -108,7 +108,7 @@
UserBatteryConsumer consumer = mock(UserBatteryConsumer.class);
when(consumer.getUserId()).thenReturn(userId);
return new BatteryEntry(mMockContext, mockHandler, mockUserManager,
- consumer, false, null, null);
+ consumer, false, 0, null, null);
}
@Test
@@ -169,12 +169,12 @@
@Test
public void getTimeInForegroundMs_app() {
- final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
- mockUserManager, mUidBatteryConsumer, false, null, null);
-
when(mUidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND))
.thenReturn(100L);
+ final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
+ mockUserManager, mUidBatteryConsumer, false, 0, null, null);
+
assertThat(entry.getTimeInForegroundMs()).isEqualTo(100L);
}
@@ -188,12 +188,12 @@
@Test
public void getTimeInBackgroundMs_app() {
- final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
- mockUserManager, mUidBatteryConsumer, false, null, null);
-
when(mUidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND))
.thenReturn(100L);
+ final BatteryEntry entry = new BatteryEntry(RuntimeEnvironment.application, mockHandler,
+ mockUserManager, mUidBatteryConsumer, false, 0, null, null);
+
assertThat(entry.getTimeInBackgroundMs()).isEqualTo(100L);
}