Do not check runtime READ_PHONE_STATE if caller has the privileged one.

Also removed READ_PHONE_STATE from SystemUI since it has
READ_PRIVILEGED_PHONE_STATE.

Bug: 22376654
Change-Id: I437f9bf324950cb70bae5be76699824da5897a6f
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index b41e1ac..6e5dc3f 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -51,7 +51,6 @@
     <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
     <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 36d64aa..a06bb30 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -16,6 +16,7 @@
 
 package com.android.server;
 
+import android.Manifest;
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
@@ -360,12 +361,20 @@
                 + " callback.asBinder=" + callback.asBinder());
         }
 
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.READ_PHONE_STATE, null);
+        try {
+            mContext.enforceCallingPermission(
+                    android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE,
+                    "addOnSubscriptionsChangedListener");
+            // SKIP checking for run-time permission since obtained PRIVILEGED
+        } catch (SecurityException e) {
+            mContext.enforceCallingOrSelfPermission(
+                    android.Manifest.permission.READ_PHONE_STATE,
+                    "addOnSubscriptionsChangedListener");
 
-        if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
-                callingPackage) != AppOpsManager.MODE_ALLOWED) {
-            return;
+            if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
+                    callingPackage) != AppOpsManager.MODE_ALLOWED) {
+                return;
+            }
         }
 
         Record r;
@@ -471,9 +480,15 @@
             checkListenerPermission(events);
 
             if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
-                if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
-                        callingPackage) != AppOpsManager.MODE_ALLOWED) {
-                    return;
+                try {
+                    mContext.enforceCallingPermission(
+                            android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
+                    // SKIP checking for run-time permission since obtained PRIVILEGED
+                } catch (SecurityException e) {
+                    if (mAppOps.noteOp(AppOpsManager.OP_READ_PHONE_STATE, Binder.getCallingUid(),
+                            callingPackage) != AppOpsManager.MODE_ALLOWED) {
+                        return;
+                    }
                 }
             }
 
@@ -646,6 +661,12 @@
     }
 
     private boolean canReadPhoneState(String callingPackage) {
+        if (mContext.checkCallingPermission(
+                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) ==
+                PackageManager.PERMISSION_GRANTED) {
+            // SKIP checking for run-time permission since obtained PRIVILEGED
+            return true;
+        }
         boolean canReadPhoneState = mContext.checkCallingOrSelfPermission(
                 android.Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
         if (canReadPhoneState &&
@@ -1432,6 +1453,10 @@
             intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
         }
 
+        // Send broadcast twice, once for apps that have PRIVILEGED permission and once for those
+        // that have the runtime one
+        mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
+                android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
         mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
                 android.Manifest.permission.READ_PHONE_STATE,
                 AppOpsManager.OP_READ_PHONE_STATE);
@@ -1563,8 +1588,14 @@
         }
 
         if ((events & ENFORCE_PHONE_STATE_PERMISSION_MASK) != 0) {
-            mContext.enforceCallingOrSelfPermission(
-                    android.Manifest.permission.READ_PHONE_STATE, null);
+            try {
+                mContext.enforceCallingPermission(
+                        android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null);
+                // SKIP checking for run-time permission since obtained PRIVILEGED
+            } catch (SecurityException e) {
+                mContext.enforceCallingOrSelfPermission(
+                        android.Manifest.permission.READ_PHONE_STATE, null);
+            }
         }
 
         if ((events & PRECISE_PHONE_STATE_PERMISSION_MASK) != 0) {