From 1ed547ee3e28fddeaabf29fb3d9a418b0403c9eb Mon Sep 17 00:00:00 2001 From: sqian Date: Mon, 5 Nov 2018 14:28:49 -0800 Subject: Add telephony commands about SMS apps See the other CL on the same topic for the details Bug: 109809543 Test: See the other CL Change-Id: I9f750a72edfc282c80f7547647bcddaf2da51d9b Merged-In: I9f750a72edfc282c80f7547647bcddaf2da51d9b --- core/res/AndroidManifest.xml | 8 ++++ telephony/java/android/provider/Telephony.java | 11 ++++++ .../com/android/internal/telephony/ITelephony.aidl | 15 ++++++++ .../android/internal/telephony/SmsApplication.java | 45 +++++++++++++++++++--- .../internal/telephony/TelephonyPermissions.java | 14 +++++++ 5 files changed, 88 insertions(+), 5 deletions(-) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 93cb57dd2459..1f3a8fce8ef1 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -603,6 +603,8 @@ + + @@ -3995,6 +3997,12 @@ + + + getApplicationCollection(Context context) { - int userId = getIncomingUserId(context); + return getApplicationCollectionAsUser(context, getIncomingUserId(context)); + } + + /** + * Same as {@link #getApplicationCollection} but it takes a target user ID. + */ + public static Collection getApplicationCollectionAsUser(Context context, + int userId) { final long token = Binder.clearCallingIdentity(); try { return getApplicationCollectionInternal(context, userId); @@ -535,13 +542,20 @@ public final class SmsApplication { * needs to have permission to set AppOps and write to secure settings. */ public static void setDefaultApplication(String packageName, Context context) { + setDefaultApplicationAsUser(packageName, context, getIncomingUserId(context)); + } + + /** + * Same as {@link #setDefaultApplication} but takes a target user id. + */ + public static void setDefaultApplicationAsUser(String packageName, Context context, + int userId) { TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); if (!tm.isSmsCapable()) { // No phone, no SMS return; } - final int userId = getIncomingUserId(context); final long token = Binder.clearCallingIdentity(); try { setDefaultApplicationInternal(packageName, context, userId); @@ -552,6 +566,8 @@ public final class SmsApplication { private static void setDefaultApplicationInternal(String packageName, Context context, int userId) { + final UserHandle userHandle = UserHandle.of(userId); + // Get old package name String oldPackageName = Settings.Secure.getStringForUser(context.getContentResolver(), Settings.Secure.SMS_DEFAULT_APPLICATION, userId); @@ -628,7 +644,7 @@ public final class SmsApplication { if (DEBUG_MULTIUSER) { Log.i(LOG_TAG, "setDefaultApplicationInternal old=" + oldAppData.mPackageName); } - context.sendBroadcast(oldAppIntent); + context.sendBroadcastAsUser(oldAppIntent, userHandle); } // Notify the new sms app that it's now the default (if the new sms app has a receiver // to handle the changed default sms intent). @@ -646,8 +662,16 @@ public final class SmsApplication { if (DEBUG_MULTIUSER) { Log.i(LOG_TAG, "setDefaultApplicationInternal new=" + packageName); } - context.sendBroadcast(intent); + context.sendBroadcastAsUser(intent, userHandle); } + + // Send an implicit broadcast for the system server. + // (or anyone with MONITOR_DEFAULT_SMS_PACKAGE, really.) + final Intent intent = + new Intent(Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL); + context.sendBroadcastAsUser(intent, userHandle, + permission.MONITOR_DEFAULT_SMS_PACKAGE); + MetricsLogger.action(context, MetricsEvent.ACTION_DEFAULT_SMS_APP_CHANGED, applicationData.mPackageName); } @@ -799,7 +823,18 @@ public final class SmsApplication { * @return component name of the app and class to deliver SMS messages to */ public static ComponentName getDefaultSmsApplication(Context context, boolean updateIfNeeded) { - int userId = getIncomingUserId(context); + return getDefaultSmsApplicationAsUser(context, updateIfNeeded, getIncomingUserId(context)); + } + + /** + * Gets the default SMS application on a given user + * @param context context from the calling app + * @param updateIfNeeded update the default app if there is no valid default app configured. + * @param userId target user ID. + * @return component name of the app and class to deliver SMS messages to + */ + public static ComponentName getDefaultSmsApplicationAsUser(Context context, + boolean updateIfNeeded, int userId) { final long token = Binder.clearCallingIdentity(); try { ComponentName component = null; diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java index 3822cbe8402e..2c8b908abbec 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java +++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java @@ -21,6 +21,7 @@ import android.Manifest; import android.app.AppOpsManager; import android.content.Context; import android.os.Binder; +import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.Rlog; @@ -328,4 +329,17 @@ public final class TelephonyPermissions { Rlog.e(LOG_TAG, "Phone process is down, cannot check carrier privileges"); return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS; } + + /** + * Throws if the caller is not of a shell (or root) UID. + * + * @param callingUid pass Binder.callingUid(). + */ + public static void enforceShellOnly(int callingUid, String message) { + if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID) { + return; // okay + } + + throw new SecurityException(message + ": Only shell user can call it"); + } } -- cgit v1.2.3-59-g8ed1b