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);
     }