Merge "Plumb context object to PowerWhitelistBackend."
diff --git a/res/values/bools.xml b/res/values/bools.xml
index 29de06b..fa57b29 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -58,7 +58,7 @@
     <bool name="config_show_toggle_airplane">true</bool>
 
     <!-- Whether memory from app_info_settings is available or not. -->
-    <bool name="config_show_app_info_settings_memory">true</bool>
+    <bool name="config_show_app_info_settings_memory">false</bool>
 
     <!-- Whether battery from app_info_settings is available or not. -->
     <bool name="config_show_app_info_settings_battery">true</bool>
diff --git a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java
index 545b510..d29fc95 100644
--- a/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java
+++ b/src/com/android/settings/applications/ApplicationFeatureProviderImpl.java
@@ -17,6 +17,7 @@
 package com.android.settings.applications;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ComponentInfo;
@@ -26,8 +27,12 @@
 import android.content.pm.UserInfo;
 import android.os.RemoteException;
 import android.os.UserManager;
+import android.telecom.DefaultDialerManager;
+import android.text.TextUtils;
 import android.util.ArraySet;
 
+import com.android.internal.telephony.SmsApplication;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
@@ -122,7 +127,18 @@
 
     @Override
     public Set<String> getKeepEnabledPackages() {
-        return new ArraySet<>();
+        // Find current default phone/sms app. We should keep them enabled.
+        final Set<String> keepEnabledPackages = new ArraySet<>();
+        final String defaultDialer = DefaultDialerManager.getDefaultDialerApplication(mContext);
+        if (!TextUtils.isEmpty(defaultDialer)) {
+            keepEnabledPackages.add(defaultDialer);
+        }
+        final ComponentName defaultSms = SmsApplication.getDefaultSmsApplication(
+                mContext, true /* updateIfNeeded */);
+        if (defaultSms != null) {
+            keepEnabledPackages.add(defaultSms.getPackageName());
+        }
+        return keepEnabledPackages;
     }
 
     private static class CurrentUserAndManagedProfilePolicyInstalledAppCounter
diff --git a/src/com/android/settings/dashboard/RoundedHomepageIcon.java b/src/com/android/settings/dashboard/RoundedHomepageIcon.java
index 77acaf3..9848034 100644
--- a/src/com/android/settings/dashboard/RoundedHomepageIcon.java
+++ b/src/com/android/settings/dashboard/RoundedHomepageIcon.java
@@ -22,12 +22,16 @@
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
 import android.graphics.drawable.LayerDrawable;
-import androidx.annotation.VisibleForTesting;
+import android.util.Log;
 
 import com.android.settings.R;
 
+import androidx.annotation.VisibleForTesting;
+
 public class RoundedHomepageIcon extends LayerDrawable {
 
+    private static final String TAG = "RoundedHomepageIcon";
+
     @VisibleForTesting(otherwise = NONE)
     int mBackgroundColor = -1;
 
@@ -44,5 +48,6 @@
     public void setBackgroundColor(int color) {
         mBackgroundColor = color;
         getDrawable(0).setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
+        Log.d(TAG, "Setting background color " + mBackgroundColor);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
index add6023..a2ba9a9 100644
--- a/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/AppButtonsPreferenceController.java
@@ -48,6 +48,7 @@
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
 import com.android.settings.Utils;
+import com.android.settings.applications.ApplicationFeatureProvider;
 import com.android.settings.core.PreferenceControllerMixin;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.ActionButtonPreference;
@@ -73,7 +74,7 @@
  * An easy way to handle them is to delegate them to {@link #handleDialogClick(int)} and
  * {@link #handleActivityResult(int, int, Intent)} in this controller.
  */
-//TODO(b/35810915): Make AppInfoDashboardFragment use this controller
+//TODO(80312809): Merge this class into {@link AppActionButtonPreferenceController}
 public class AppButtonsPreferenceController extends AbstractPreferenceController implements
         PreferenceControllerMixin, LifecycleObserver, OnResume, OnDestroy,
         ApplicationsState.Callbacks {
@@ -100,17 +101,18 @@
 
     private final int mRequestUninstall;
     private final int mRequestRemoveDeviceAdmin;
+    private final DevicePolicyManager mDpm;
+    private final UserManager mUserManager;
+    private final PackageManager mPm;
+    private final SettingsActivity mActivity;
+    private final Fragment mFragment;
+    private final MetricsFeatureProvider mMetricsFeatureProvider;
+    private final ApplicationFeatureProvider mApplicationFeatureProvider;
+    private final int mUserId;
 
     private ApplicationsState.Session mSession;
-    private DevicePolicyManager mDpm;
-    private UserManager mUserManager;
-    private PackageManager mPm;
-    private SettingsActivity mActivity;
-    private Fragment mFragment;
     private RestrictedLockUtils.EnforcedAdmin mAppsControlDisallowedAdmin;
-    private MetricsFeatureProvider mMetricsFeatureProvider;
 
-    private int mUserId;
     private boolean mUpdatedSysApp = false;
     private boolean mListeningToPackageRemove = false;
     private boolean mFinishing = false;
@@ -127,8 +129,9 @@
                     "Fragment should implement AppButtonsDialogListener");
         }
 
-        mMetricsFeatureProvider = FeatureFactory.getFactory(activity).getMetricsFeatureProvider();
-
+        final FeatureFactory factory = FeatureFactory.getFactory(activity);
+        mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
+        mApplicationFeatureProvider = factory.getApplicationFeatureProvider(activity);
         mState = state;
         mDpm = dpm;
         mUserManager = userManager;
@@ -538,11 +541,11 @@
             // Disable button for core system applications.
             mButtonsPref.setButton1Text(R.string.disable_text)
                     .setButton1Positive(false);
-
         } else if (mAppEntry.info.enabled && !isDisabledUntilUsed()) {
             mButtonsPref.setButton1Text(R.string.disable_text)
                     .setButton1Positive(false);
-            disableable = true;
+            disableable = !mApplicationFeatureProvider.getKeepEnabledPackages()
+                    .contains(mAppEntry.info.packageName);
         } else {
             mButtonsPref.setButton1Text(R.string.enable_text)
                     .setButton1Positive(true);
diff --git a/tests/robotests/res/values-mcc999/config.xml b/tests/robotests/res/values-mcc999/config.xml
index 67628b0..c500bc6 100644
--- a/tests/robotests/res/values-mcc999/config.xml
+++ b/tests/robotests/res/values-mcc999/config.xml
@@ -23,7 +23,7 @@
     <bool name="config_additional_system_update_setting_enable">true</bool>
     <bool name="config_show_wifi_settings">false</bool>
     <bool name="config_show_toggle_airplane">false</bool>
-    <bool name="config_show_app_info_settings_memory">false</bool>
+    <bool name="config_show_app_info_settings_memory">true</bool>
     <bool name="config_show_app_info_settings_battery">false</bool>
     <bool name="config_show_high_power_apps">false</bool>
     <bool name="config_show_alarm_volume">false</bool>
diff --git a/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java
index 680dc07..1eb7fb8 100644
--- a/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/applications/ApplicationFeatureProviderImplTest.java
@@ -20,6 +20,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -34,17 +35,23 @@
 
 import com.android.settings.testutils.ApplicationTestUtils;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settings.testutils.shadow.ShadowDefaultDialerManager;
+import com.android.settings.testutils.shadow.ShadowSmsApplication;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
 import org.robolectric.shadows.ShadowApplication;
+import org.robolectric.util.ReflectionHelpers;
 
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
 
 /**
  * Tests for {@link ApplicationFeatureProviderImpl}.
@@ -246,8 +253,18 @@
     }
 
     @Test
-    public void getKeepEnabledPackages_shouldContainNothing() {
-        assertThat(mProvider.getKeepEnabledPackages()).isEmpty();
+    @Config(shadows = {ShadowSmsApplication.class, ShadowDefaultDialerManager.class})
+    public void getKeepEnabledPackages_shouldContainDefaultPhoneAndSms() {
+        final String testDialer = "com.android.test.defaultdialer";
+        final String testSms = "com.android.test.defaultsms";
+        ShadowSmsApplication.setDefaultSmsApplication(new ComponentName(testSms, "receiver"));
+        ShadowDefaultDialerManager.setDefaultDialerApplication(testDialer);
+        ReflectionHelpers.setField(mProvider, "mContext", RuntimeEnvironment.application);
+
+        final Set<String> keepEnabledPackages = mProvider.getKeepEnabledPackages();
+
+        final List<String> expectedPackages = Arrays.asList(testDialer, testSms);
+        assertThat(keepEnabledPackages).containsExactlyElementsIn(expectedPackages);
     }
 
     private void setUpUsersAndInstalledApps() {
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/AppMemoryPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/AppMemoryPreferenceControllerTest.java
index 1c0d897..cd53f8b 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/AppMemoryPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/AppMemoryPreferenceControllerTest.java
@@ -76,6 +76,7 @@
     }
 
     @Test
+    @Config(qualifiers = "mcc999")
     public void getAvailabilityStatus_developmentSettingsEnabled_shouldReturnAvailable() {
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
@@ -85,7 +86,6 @@
     }
 
     @Test
-    @Config(qualifiers = "mcc999")
     public void getAvailabilityStatus_devSettingsEnabled_butNotVisible_shouldReturnUnsupported() {
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 1);
@@ -95,7 +95,6 @@
     }
 
     @Test
-    @Config(qualifiers = "mcc999")
     public void getAvailabilityStatus_devSettingsDisabled_butNotVisible_shouldReturnUnsupported() {
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
@@ -105,6 +104,7 @@
     }
 
     @Test
+    @Config(qualifiers = "mcc999")
     public void getAvailabilityStatus_developmentSettingsDisabled_shouldReturnDisabled() {
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0);
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDefaultDialerManager.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDefaultDialerManager.java
new file mode 100644
index 0000000..ec4d788
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowDefaultDialerManager.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 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.testutils.shadow;
+
+import android.content.Context;
+import android.telecom.DefaultDialerManager;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(DefaultDialerManager.class)
+public class ShadowDefaultDialerManager {
+
+    private static String sDefaultDailer;
+
+    @Resetter
+    public void reset() {
+        sDefaultDailer = null;
+    }
+
+    @Implementation
+    public static String getDefaultDialerApplication(Context context) {
+        return sDefaultDailer;
+    }
+
+    public static void setDefaultDialerApplication(String dialer) {
+        sDefaultDailer = dialer;
+    }
+}
diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSmsApplication.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSmsApplication.java
new file mode 100644
index 0000000..8e0c013
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowSmsApplication.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 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.testutils.shadow;
+
+import android.content.ComponentName;
+import android.content.Context;
+
+import com.android.internal.telephony.SmsApplication;
+
+import org.robolectric.annotation.Implementation;
+import org.robolectric.annotation.Implements;
+import org.robolectric.annotation.Resetter;
+
+@Implements(SmsApplication.class)
+public class ShadowSmsApplication {
+
+    private static ComponentName sDefaultSmsApplication;
+
+    @Resetter
+    public void reset() {
+        sDefaultSmsApplication = null;
+    }
+
+    @Implementation
+    public static ComponentName getDefaultSmsApplication(Context context, boolean updateIfNeeded) {
+        return sDefaultSmsApplication;
+    }
+
+    public static void setDefaultSmsApplication(ComponentName cn) {
+        sDefaultSmsApplication = cn;
+    }
+}