Merge "Read the subtext of notif importance field on selection" into qt-dev
diff --git a/src/com/android/settings/applications/appinfo/ExternalSourcesDetails.java b/src/com/android/settings/applications/appinfo/ExternalSourcesDetails.java
index b723274..fe1d81c 100644
--- a/src/com/android/settings/applications/appinfo/ExternalSourcesDetails.java
+++ b/src/com/android/settings/applications/appinfo/ExternalSourcesDetails.java
@@ -18,6 +18,7 @@
 import static android.app.Activity.RESULT_CANCELED;
 import static android.app.Activity.RESULT_OK;
 
+import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.settings.SettingsEnums;
 import android.content.Context;
@@ -29,6 +30,7 @@
 import androidx.preference.Preference;
 import androidx.preference.Preference.OnPreferenceChangeListener;
 
+import com.android.internal.annotations.VisibleForTesting;
 import com.android.settings.R;
 import com.android.settings.Settings;
 import com.android.settings.applications.AppInfoWithHeader;
@@ -44,6 +46,7 @@
 
     private AppStateInstallAppsBridge mAppBridge;
     private AppOpsManager mAppOpsManager;
+    private ActivityManager mActivityManager;
     private UserManager mUserManager;
     private RestrictedSwitchPreference mSwitchPref;
     private InstallAppsState mInstallAppsState;
@@ -55,6 +58,7 @@
         final Context context = getActivity();
         mAppBridge = new AppStateInstallAppsBridge(context, mState, null);
         mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        mActivityManager = context.getSystemService(ActivityManager.class);
         mUserManager = UserManager.get(context);
 
         addPreferencesFromResource(R.xml.external_sources_details);
@@ -99,10 +103,21 @@
                 : R.string.app_permission_summary_not_allowed);
     }
 
-    private void setCanInstallApps(boolean newState) {
+    @VisibleForTesting
+    void setCanInstallApps(boolean newState) {
         mAppOpsManager.setMode(AppOpsManager.OP_REQUEST_INSTALL_PACKAGES,
                 mPackageInfo.applicationInfo.uid, mPackageName,
                 newState ? AppOpsManager.MODE_ALLOWED : AppOpsManager.MODE_ERRORED);
+        if (!newState) {
+            killApp(mPackageInfo.applicationInfo.uid);
+        }
+    }
+
+    private void killApp(int uid) {
+        if (UserHandle.isCore(uid)) {
+            return;
+        }
+        mActivityManager.killUid(uid, "User denied OP_REQUEST_INSTALL_PACKAGES");
     }
 
     @Override
diff --git a/tests/robotests/src/com/android/settings/applications/appinfo/ExternalSourcesDetailsTest.java b/tests/robotests/src/com/android/settings/applications/appinfo/ExternalSourcesDetailsTest.java
index 10c2675..002a0bc 100644
--- a/tests/robotests/src/com/android/settings/applications/appinfo/ExternalSourcesDetailsTest.java
+++ b/tests/robotests/src/com/android/settings/applications/appinfo/ExternalSourcesDetailsTest.java
@@ -19,11 +19,17 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.app.ActivityManager;
+import android.app.AppOpsManager;
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.content.pm.ApplicationInfo;
@@ -55,6 +61,10 @@
     @Mock
     private UserManager mUserManager;
     @Mock
+    private ActivityManager mActivityManager;
+    @Mock
+    private AppOpsManager mAppOpsManager;
+    @Mock
     private RestrictedSwitchPreference mSwitchPref;
     @Mock
     private RestrictedPreferenceHelper mHelper;
@@ -69,10 +79,47 @@
 
         mFragment = new ExternalSourcesDetails();
         ReflectionHelpers.setField(mFragment, "mUserManager", mUserManager);
+        ReflectionHelpers.setField(mFragment, "mActivityManager", mActivityManager);
+        ReflectionHelpers.setField(mFragment, "mAppOpsManager", mAppOpsManager);
         ReflectionHelpers.setField(mFragment, "mSwitchPref", mSwitchPref);
     }
 
     @Test
+    public void setCanInstallApps_false_shouldKillNonCoreUid() {
+        int mockUid = 23456;
+        ReflectionHelpers.setField(mFragment, "mPackageInfo", mPackageInfo);
+
+        mPackageInfo.applicationInfo = new ApplicationInfo();
+        mPackageInfo.applicationInfo.uid = mockUid;
+        assertThat(UserHandle.isCore(mockUid)).isFalse();
+        mFragment.setCanInstallApps(false);
+        verify(mActivityManager).killUid(eq(mockUid), anyString());
+    }
+
+    @Test
+    public void setCanInstallApps_false_shouldNotKillCoreUid() {
+        int mockUid = 1234;
+        ReflectionHelpers.setField(mFragment, "mPackageInfo", mPackageInfo);
+
+        mPackageInfo.applicationInfo = new ApplicationInfo();
+        mPackageInfo.applicationInfo.uid = mockUid;
+        assertThat(UserHandle.isCore(mockUid)).isTrue();
+        mFragment.setCanInstallApps(false);
+        verify(mActivityManager, never()).killUid(eq(mockUid), anyString());
+    }
+
+    @Test
+    public void setCanInstallApps_true_shouldNotKillUid() {
+        int mockUid = 23456;
+        ReflectionHelpers.setField(mFragment, "mPackageInfo", mPackageInfo);
+
+        mPackageInfo.applicationInfo = new ApplicationInfo();
+        mPackageInfo.applicationInfo.uid = mockUid;
+        mFragment.setCanInstallApps(true);
+        verify(mActivityManager, never()).killUid(eq(mockUid), anyString());
+    }
+
+    @Test
     public void refreshUi_noPackageInfo_shouldReturnFalseAndNoCrash() {
         mFragment.refreshUi();