From 86201db27e7585975bd59401b4b7d28198ecf3f5 Mon Sep 17 00:00:00 2001 From: Tom Taylor Date: Mon, 24 Nov 2014 09:36:43 -0800 Subject: [PATCH] Issues with messaging apps on non-primary user account Bug 18399514 Adjust the contentUri to contain the caller's userId so that when the phone process tries to open the Uri, it will open the provider on the correct user. Also make sure the Uri grants are properly qualified. We only need to grant permission for sending. Receiving an MMS is always done by the primary user and doesn't need special permissions. Move various permission grants from the SmsManager to here. Change-Id: Ib192f651ab05db9f07e9e6245bb343ed7a55b18e --- .../com/android/server/MmsServiceBroker.java | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java index da507519676e4..b1c4955397151 100644 --- a/services/core/java/com/android/server/MmsServiceBroker.java +++ b/services/core/java/com/android/server/MmsServiceBroker.java @@ -20,6 +20,7 @@ import android.Manifest; import android.app.AppOpsManager; import android.app.PendingIntent; import android.content.ComponentName; +import android.content.ContentProvider; import android.content.ContentValues; import android.content.Context; import android.content.Intent; @@ -33,11 +34,15 @@ import android.os.IBinder; import android.os.Message; import android.os.RemoteException; import android.os.SystemClock; +import android.os.UserHandle; +import android.provider.Telephony; import android.telephony.TelephonyManager; import android.util.Slog; import com.android.internal.telephony.IMms; +import java.util.List; + /** * This class is a proxy for MmsService APIs. We need this because MmsService runs * in phone process and may crash anytime. This manages a connection to the actual @@ -226,6 +231,8 @@ public class MmsServiceBroker extends SystemService { // Service API calls implementation, proxied to the real MmsService in "com.android.mms.service" private final class BinderService extends IMms.Stub { + private static final String PHONE_PACKAGE_NAME = "com.android.phone"; + @Override public void sendMessage(int subId, String callingPkg, Uri contentUri, String locationUrl, Bundle configOverrides, PendingIntent sentIntent) @@ -236,6 +243,9 @@ public class MmsServiceBroker extends SystemService { callingPkg) != AppOpsManager.MODE_ALLOWED) { return; } + contentUri = adjustUriForUserAndGrantPermission(contentUri, + Telephony.Mms.Intents.MMS_SEND_ACTION, + Intent.FLAG_GRANT_READ_URI_PERMISSION); getServiceGuarded().sendMessage(subId, callingPkg, contentUri, locationUrl, configOverrides, sentIntent); } @@ -251,6 +261,10 @@ public class MmsServiceBroker extends SystemService { callingPkg) != AppOpsManager.MODE_ALLOWED) { return; } + contentUri = adjustUriForUserAndGrantPermission(contentUri, + Telephony.Mms.Intents.MMS_DOWNLOAD_ACTION, + Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + getServiceGuarded().downloadMessage(subId, callingPkg, locationUrl, contentUri, configOverrides, downloadedIntent); } @@ -397,5 +411,40 @@ public class MmsServiceBroker extends SystemService { public boolean getAutoPersisting() throws RemoteException { return getServiceGuarded().getAutoPersisting(); } + + /** + * Modifies the Uri to contain the caller's userId, if necessary. + * Grants the phone package on primary user permission to access the contentUri, + * even if the caller is not in the primary user. + * + * @param contentUri The Uri to adjust + * @param action The intent action used to find the associated carrier app + * @param permission The permission to add + * @return The adjusted Uri containing the calling userId. + */ + private Uri adjustUriForUserAndGrantPermission(Uri contentUri, String action, + int permission) { + final int callingUserId = UserHandle.getCallingUserId(); + if (callingUserId != UserHandle.USER_OWNER) { + contentUri = ContentProvider.maybeAddUserId(contentUri, callingUserId); + } + long token = Binder.clearCallingIdentity(); + try { + mContext.grantUriPermission(PHONE_PACKAGE_NAME, contentUri, permission); + + // Grant permission for the carrier app. + Intent intent = new Intent(action); + TelephonyManager telephonyManager = + (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); + List carrierPackages = telephonyManager.getCarrierPackageNamesForIntent( + intent); + if (carrierPackages != null && carrierPackages.size() == 1) { + mContext.grantUriPermission(carrierPackages.get(0), contentUri, permission); + } + } finally { + Binder.restoreCallingIdentity(token); + } + return contentUri; + } } }