Merge "Provide enable property on phone accounts." into mnc-dev
diff --git a/src/com/android/server/telecom/TelecomServiceImpl.java b/src/com/android/server/telecom/TelecomServiceImpl.java
index bed6c6c..4784ba5 100644
--- a/src/com/android/server/telecom/TelecomServiceImpl.java
+++ b/src/com/android/server/telecom/TelecomServiceImpl.java
@@ -16,7 +16,13 @@
 
 package com.android.server.telecom;
 
-import android.Manifest;
+import static android.Manifest.permission.CALL_PHONE;
+import static android.Manifest.permission.MODIFY_PHONE_STATE;
+import static android.Manifest.permission.READ_PHONE_STATE;
+import static android.Manifest.permission.REGISTER_CALL_PROVIDER;
+import static android.Manifest.permission.REGISTER_CONNECTION_MANAGER;
+import static android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION;
+
 import android.app.AppOpsManager;
 import android.content.ComponentName;
 import android.content.Context;
@@ -376,8 +382,7 @@
         public boolean isVoiceMailNumber(PhoneAccountHandle accountHandle, String number,
                 String callingPackage) {
             synchronized (mLock) {
-                if (!isPrivilegedDialerCalling(callingPackage)
-                        && !canReadPhoneState(callingPackage, "isVoiceMailNumber")) {
+                if (!canReadPhoneState(callingPackage, "isVoiceMailNumber")) {
                     return false;
                 }
 
@@ -404,8 +409,7 @@
         @Override
         public String getVoiceMailNumber(PhoneAccountHandle accountHandle, String callingPackage) {
             synchronized (mLock) {
-                if (!isPrivilegedDialerCalling(callingPackage)
-                        && !canReadPhoneState(callingPackage, "getVoiceMailNumber")) {
+                if (!canReadPhoneState(callingPackage, "getVoiceMailNumber")) {
                     return null;
                 }
 
@@ -433,8 +437,7 @@
          */
         @Override
         public String getLine1Number(PhoneAccountHandle accountHandle, String callingPackage) {
-            if (!isPrivilegedDialerCalling(callingPackage)
-                    && !canReadPhoneState(callingPackage, "getLine1Number")) {
+            if (!canReadPhoneState(callingPackage, "getLine1Number")) {
                 return null;
             }
 
@@ -464,7 +467,7 @@
         @Override
         public void silenceRinger(String callingPackage) {
             synchronized (mLock) {
-                enforceModifyPermissionOrPrivilegedDialer(callingPackage);
+                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
 
                 long token = Binder.clearCallingIdentity();
                 try {
@@ -592,8 +595,7 @@
          */
         @Override
         public void showInCallScreen(boolean showDialpad, String callingPackage) {
-            if (!isPrivilegedDialerCalling(callingPackage)
-                    && !canReadPhoneState(callingPackage, "showInCallScreen")) {
+            if (!canReadPhoneState(callingPackage, "showInCallScreen")) {
                 return;
             }
 
@@ -614,7 +616,7 @@
         @Override
         public void cancelMissedCallsNotification(String callingPackage) {
             synchronized (mLock) {
-                enforceModifyPermissionOrPrivilegedDialer(callingPackage);
+                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
                 long token = Binder.clearCallingIdentity();
                 try {
                     mCallsManager.getMissedCallNotifier().clearMissedCalls();
@@ -630,7 +632,7 @@
         @Override
         public boolean handlePinMmi(String dialString, String callingPackage) {
             synchronized (mLock) {
-                enforceModifyPermissionOrPrivilegedDialer(callingPackage);
+                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
 
                 // Switch identity so that TelephonyManager checks Telecom's permissions instead.
                 long token = Binder.clearCallingIdentity();
@@ -654,7 +656,7 @@
                 String dialString,
                 String callingPackage) {
             synchronized (mLock) {
-                enforceModifyPermissionOrPrivilegedDialer(callingPackage);
+                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
 
                 if (!isVisibleToCaller(accountHandle)) {
                     Log.w(this, "%s is not visible for the calling user", accountHandle);
@@ -683,7 +685,7 @@
         public Uri getAdnUriForPhoneAccount(PhoneAccountHandle accountHandle,
                 String callingPackage) {
             synchronized (mLock) {
-                enforceModifyPermissionOrPrivilegedDialer(callingPackage);
+                enforcePermissionOrPrivilegedDialer(MODIFY_PHONE_STATE, callingPackage);
 
                 if (!isVisibleToCaller(accountHandle)) {
                     Log.w(this, "%s is not visible for the calling user", accountHandle);
@@ -812,6 +814,7 @@
                 throw new SecurityException("Package " + callingPackage
                         + " is not allowed to place phone calls");
             }
+
             synchronized (mLock) {
                 final UserHandle userHandle = Binder.getCallingUserHandle();
                 long token = Binder.clearCallingIdentity();
@@ -1026,7 +1029,7 @@
     private void enforcePhoneAccountModificationForPackage(String packageName) {
         // TODO: Use a new telecomm permission for this instead of reusing modify.
 
-        int result = mContext.checkCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE);
+        int result = mContext.checkCallingOrSelfPermission(MODIFY_PHONE_STATE);
 
         // Callers with MODIFY_PHONE_STATE can use the PhoneAccount mechanism to implement
         // built-in behavior even when PhoneAccounts are not exposed as a third-part API. They
@@ -1041,13 +1044,13 @@
         }
     }
 
-    private void enforceModifyPermissionOrPrivilegedDialer(String packageName) {
+    private void enforcePermissionOrPrivilegedDialer(String permission, String packageName) {
         if (!isPrivilegedDialerCalling(packageName)) {
             try {
-                enforceModifyPermission();
+                enforcePermission(permission);
             } catch (SecurityException e) {
-                Log.e(this, e, "Caller must be the default or system dialer, or have the system"
-                        + " only permission MODIFY_PHONE_STATE to perform this operation.");
+                Log.e(this, e, "Caller must be the default or system dialer, or have the permission"
+                        + " %s to perform this operation.", permission);
                 throw e;
             }
         }
@@ -1062,19 +1065,19 @@
     }
 
     private void enforceRegisterCallProviderPermission() {
-        enforcePermission(android.Manifest.permission.REGISTER_CALL_PROVIDER);
+        enforcePermission(REGISTER_CALL_PROVIDER);
     }
 
     private void enforceRegisterSimSubscriptionPermission() {
-        enforcePermission(android.Manifest.permission.REGISTER_SIM_SUBSCRIPTION);
+        enforcePermission(REGISTER_SIM_SUBSCRIPTION);
     }
 
     private void enforceRegisterConnectionManagerPermission() {
-        enforcePermission(android.Manifest.permission.REGISTER_CONNECTION_MANAGER);
+        enforcePermission(REGISTER_CONNECTION_MANAGER);
     }
 
     private void enforceModifyPermission() {
-        enforcePermission(Manifest.permission.MODIFY_PHONE_STATE);
+        enforcePermission(MODIFY_PHONE_STATE);
     }
 
     private void enforcePermission(String permission) {
@@ -1102,8 +1105,14 @@
     }
 
     private boolean canReadPhoneState(String callingPackage, String message) {
+        // The system/default dialer can always read phone state - so that emergency calls will
+        // still work.
+        if (isPrivilegedDialerCalling(callingPackage)) {
+            return true;
+        }
+
         // Accessing phone state is gated by a special permission.
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE, message);
+        mContext.enforceCallingOrSelfPermission(READ_PHONE_STATE, message);
 
         // Some apps that have the permission can be restricted via app ops.
         return mAppOpsManager.noteOp(AppOpsManager.OP_READ_PHONE_STATE,
@@ -1111,8 +1120,14 @@
     }
 
     private boolean canCallPhone(String callingPackage, String message) {
+        // The system/default dialer can always read phone state - so that emergency calls will
+        // still work.
+        if (isPrivilegedDialerCalling(callingPackage)) {
+            return true;
+        }
+
         // Accessing phone state is gated by a special permission.
-        mContext.enforceCallingOrSelfPermission(Manifest.permission.CALL_PHONE, message);
+        mContext.enforceCallingOrSelfPermission(CALL_PHONE, message);
 
         // Some apps that have the permission can be restricted via app ops.
         return mAppOpsManager.noteOp(AppOpsManager.OP_CALL_PHONE,