Merge branch 'security-aosp-tm-release' into int/13/fp3

* security-aosp-tm-release:
  RESTRICT AUTOMERGE: Catch exceptions from setLockCredential()
  [RESTRICT AUTOMERGE] Restrict ApnEditor settings

Change-Id: Ie5cbf12ca685b26ea5d02ca2bed6cc4a6f9db1ab
diff --git a/src/com/android/settings/network/apn/ApnEditor.java b/src/com/android/settings/network/apn/ApnEditor.java
index 7da6e35..e316c51 100644
--- a/src/com/android/settings/network/apn/ApnEditor.java
+++ b/src/com/android/settings/network/apn/ApnEditor.java
@@ -25,6 +25,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.PersistableBundle;
+import android.os.UserManager;
 import android.provider.Telephony;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
@@ -281,6 +282,11 @@
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
+        if (isUserRestricted()) {
+            Log.e(TAG, "This setting isn't available due to user restriction.");
+            finish();
+            return;
+        }
 
         setLifecycleForAllControllers();
 
@@ -1459,6 +1465,23 @@
     }
 
     @VisibleForTesting
+    boolean isUserRestricted() {
+        UserManager userManager = getContext().getSystemService(UserManager.class);
+        if (userManager == null) {
+            return false;
+        }
+        if (!userManager.isAdminUser()) {
+            Log.e(TAG, "User is not an admin");
+            return true;
+        }
+        if (userManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
+            Log.e(TAG, "User is not allowed to configure mobile network");
+            return true;
+        }
+        return false;
+    }
+
+    @VisibleForTesting
     static class ApnData {
         /**
          * The uri correspond to a database row of the apn data. This should be null if the apn
diff --git a/src/com/android/settings/password/ChooseLockPassword.java b/src/com/android/settings/password/ChooseLockPassword.java
index c4a3159..613388b 100644
--- a/src/com/android/settings/password/ChooseLockPassword.java
+++ b/src/com/android/settings/password/ChooseLockPassword.java
@@ -1048,8 +1048,13 @@
 
         @Override
         protected Pair<Boolean, Intent> saveAndVerifyInBackground() {
-            final boolean success = mUtils.setLockCredential(
-                    mChosenPassword, mCurrentCredential, mUserId);
+            boolean success;
+            try {
+                success = mUtils.setLockCredential(mChosenPassword, mCurrentCredential, mUserId);
+            } catch (RuntimeException e) {
+                Log.e(TAG, "Failed to set lockscreen credential", e);
+                success = false;
+            }
             if (success) {
                 unifyProfileCredentialIfRequested();
             }
diff --git a/src/com/android/settings/password/ChooseLockPattern.java b/src/com/android/settings/password/ChooseLockPattern.java
index c0342d1..40d6ecc 100644
--- a/src/com/android/settings/password/ChooseLockPattern.java
+++ b/src/com/android/settings/password/ChooseLockPattern.java
@@ -909,8 +909,13 @@
         @Override
         protected Pair<Boolean, Intent> saveAndVerifyInBackground() {
             final int userId = mUserId;
-            final boolean success = mUtils.setLockCredential(mChosenPattern, mCurrentCredential,
-                    userId);
+            boolean success;
+            try {
+                success = mUtils.setLockCredential(mChosenPattern, mCurrentCredential, userId);
+            } catch (RuntimeException e) {
+                Log.e(TAG, "Failed to set lockscreen credential", e);
+                success = false;
+            }
             if (success) {
                 unifyProfileCredentialIfRequested();
             }
diff --git a/tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java b/tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java
index f03b6d8..d73b58d 100644
--- a/tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java
+++ b/tests/robotests/src/com/android/settings/network/apn/ApnEditorTest.java
@@ -36,6 +36,7 @@
 import android.database.Cursor;
 import android.net.Uri;
 import android.os.PersistableBundle;
+import android.os.UserManager;
 import android.telephony.CarrierConfigManager;
 import android.view.KeyEvent;
 import android.view.Menu;
@@ -102,6 +103,8 @@
     @Mock
     private FragmentActivity mActivity;
     @Mock
+    private UserManager mUserManager;
+    @Mock
     private ProxySubscriptionManager mProxySubscriptionMgr;
     @Mock
     private CarrierConfigManager mCarrierConfigManager;
@@ -133,6 +136,11 @@
                 .getSystemService(Context.CARRIER_CONFIG_SERVICE);
         doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
 
+        doReturn(mUserManager).when(mContext).getSystemService(UserManager.class);
+        doReturn(true).when(mUserManager).isAdminUser();
+        doReturn(false).when(mUserManager)
+                .hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
+
         setMockPreference(mContext);
         mApnEditorUT.mApnData = new FakeApnData(APN_DATA);
         mApnEditorUT.sNotSet = "Not Set";
@@ -473,6 +481,27 @@
 
     @Test
     @Config(shadows = ShadowFragment.class)
+    public void onCreate_notAdminUser_shouldFinish() {
+        doReturn(false).when(mUserManager).isAdminUser();
+
+        mApnEditorUT.onCreate(null);
+
+        verify(mApnEditorUT).finish();
+    }
+
+    @Test
+    @Config(shadows = ShadowFragment.class)
+    public void onCreate_hasUserRestriction_shouldFinish() {
+        doReturn(true).when(mUserManager)
+                .hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS);
+
+        mApnEditorUT.onCreate(null);
+
+        verify(mApnEditorUT).finish();
+    }
+
+    @Test
+    @Config(shadows = ShadowFragment.class)
     public void onCreate_noAction_shouldFinishAndNoCrash() {
         ProxySubscriptionManager proxySubscriptionMgr = mock(ProxySubscriptionManager.class);
         mApnEditorUT.mProxySubscriptionMgr = proxySubscriptionMgr;