diff options
| -rw-r--r-- | api/current.txt | 5 | ||||
| -rw-r--r-- | core/java/android/content/Context.java | 10 | ||||
| -rw-r--r-- | non-updatable-api/current.txt | 5 | ||||
| -rw-r--r-- | telephony/java/android/telephony/SmsManager.java | 134 | ||||
| -rw-r--r-- | telephony/java/android/telephony/TelephonyFrameworkInitializer.java | 6 |
5 files changed, 130 insertions, 30 deletions
diff --git a/api/current.txt b/api/current.txt index da0b0da92a76..a59c7b85e608 100644 --- a/api/current.txt +++ b/api/current.txt @@ -47937,12 +47937,13 @@ package android.telephony { public final class SmsManager { method public String createAppSpecificSmsToken(android.app.PendingIntent); method @Nullable public String createAppSpecificSmsTokenWithPackageInfo(@Nullable String, @NonNull android.app.PendingIntent); + method @NonNull public android.telephony.SmsManager createForSubscriptionId(int); method public java.util.ArrayList<java.lang.String> divideMessage(String); method public void downloadMultimediaMessage(android.content.Context, String, android.net.Uri, android.os.Bundle, android.app.PendingIntent); method @NonNull public android.os.Bundle getCarrierConfigValues(); - method public static android.telephony.SmsManager getDefault(); + method @Deprecated public static android.telephony.SmsManager getDefault(); method public static int getDefaultSmsSubscriptionId(); - method public static android.telephony.SmsManager getSmsManagerForSubscriptionId(int); + method @Deprecated public static android.telephony.SmsManager getSmsManagerForSubscriptionId(int); method @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS) public void getSmsMessagesForFinancialApp(android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.SmsManager.FinancialSmsCallback); method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getSmscAddress(); method public int getSubscriptionId(); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 6f8923ffaf59..2385712a71d1 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -5174,6 +5174,16 @@ public abstract class Context { public static final String DREAM_SERVICE = "dream"; /** + * Use with {@link #getSystemService(String)} to retrieve a + * {@link android.telephony.SmsManager} for accessing Sms functionality. + * + * @see #getSystemService(String) + + * @hide + */ + public static final String SMS_SERVICE = "sms"; + + /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. * diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index d25a231ca750..5aaca435e71e 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -46087,12 +46087,13 @@ package android.telephony { public final class SmsManager { method public String createAppSpecificSmsToken(android.app.PendingIntent); method @Nullable public String createAppSpecificSmsTokenWithPackageInfo(@Nullable String, @NonNull android.app.PendingIntent); + method @NonNull public android.telephony.SmsManager createForSubscriptionId(int); method public java.util.ArrayList<java.lang.String> divideMessage(String); method public void downloadMultimediaMessage(android.content.Context, String, android.net.Uri, android.os.Bundle, android.app.PendingIntent); method @NonNull public android.os.Bundle getCarrierConfigValues(); - method public static android.telephony.SmsManager getDefault(); + method @Deprecated public static android.telephony.SmsManager getDefault(); method public static int getDefaultSmsSubscriptionId(); - method public static android.telephony.SmsManager getSmsManagerForSubscriptionId(int); + method @Deprecated public static android.telephony.SmsManager getSmsManagerForSubscriptionId(int); method @RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS) public void getSmsMessagesForFinancialApp(android.os.Bundle, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.SmsManager.FinancialSmsCallback); method @Nullable @RequiresPermission("android.permission.READ_PRIVILEGED_PHONE_STATE") public String getSmscAddress(); method public int getSubscriptionId(); diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index 183fdcce1ca4..06af04aea421 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -39,7 +39,9 @@ import android.os.RemoteException; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Log; +import android.util.Pair; +import com.android.internal.annotations.GuardedBy; import com.android.internal.telephony.IIntegerConsumer; import com.android.internal.telephony.ISms; import com.android.internal.telephony.ITelephony; @@ -74,11 +76,16 @@ import java.util.concurrent.Executor; public final class SmsManager { private static final String TAG = "SmsManager"; - /** Singleton object constructed during class initialization. */ - private static final SmsManager sInstance = new SmsManager( - SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); private static final Object sLockObject = new Object(); + @GuardedBy("sLockObject") + private static final Map<Pair<Context, Integer>, SmsManager> sSubInstances = + new ArrayMap<>(); + + /** Singleton object constructed during class initialization. */ + private static final SmsManager DEFAULT_INSTANCE = getSmsManagerForContextAndSubscriptionId( + null, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); + /** SMS record length from TS 51.011 10.5.3 * @hide */ @@ -89,13 +96,16 @@ public final class SmsManager { */ public static final int CDMA_SMS_RECORD_LENGTH = 255; - private static final Map<Integer, SmsManager> sSubInstances = - new ArrayMap<Integer, SmsManager>(); - /** A concrete subscription id, or the pseudo DEFAULT_SUBSCRIPTION_ID */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private int mSubId; + /** + * Context this SmsManager is for. Can be {@code null} in the case the manager was created via + * legacy APIs + */ + private final @Nullable Context mContext; + /* * Key for the various carrier-dependent configuration values. * Some of the values are used by the system in processing SMS or MMS messages. Others @@ -325,6 +335,34 @@ public final class SmsManager { } /** + * Get {@link Context#getOpPackageName()} if this manager has a context, otherwise a dummy + * value. + * + * @return The package name to be used for app-ops checks + */ + private @Nullable String getOpPackageName() { + if (mContext == null) { + return null; + } else { + return mContext.getOpPackageName(); + } + } + + /** + * Get {@link Context#getAttributionTag()} ()} if this manager has a context, otherwise get the + * default attribution tag. + * + * @return The attribution tag to be used for app-ops checks + */ + private @Nullable String getAttributionTag() { + if (mContext == null) { + return null; + } else { + return mContext.getAttributionTag(); + } + } + + /** * Send a text based SMS. * * <p class="note"><strong>Note:</strong> Using this method requires that your app has the @@ -424,7 +462,8 @@ public final class SmsManager { String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, - true /* persistMessage*/, null, null, 0L /* messageId */); + true /* persistMessage*/, getOpPackageName(), getAttributionTag(), + 0L /* messageId */); } @@ -443,7 +482,8 @@ public final class SmsManager { @Nullable PendingIntent sentIntent, @Nullable PendingIntent deliveryIntent, long messageId) { sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, - true /* persistMessage*/, null, null, messageId); + true /* persistMessage*/, getOpPackageName(), getAttributionTag(), + messageId); } /** @@ -653,8 +693,8 @@ public final class SmsManager { String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { sendTextMessageInternal(destinationAddress, scAddress, text, sentIntent, deliveryIntent, - false /* persistMessage */, null, null, - 0L /* messageId */); + false /* persistMessage */, getOpPackageName(), + getAttributionTag(), 0L /* messageId */); } private void sendTextMessageInternal( @@ -939,8 +979,8 @@ public final class SmsManager { String destinationAddress, String scAddress, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents) { sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, - deliveryIntents, true /* persistMessage*/, null, null, - 0L /* messageId */); + deliveryIntents, true /* persistMessage*/, getOpPackageName(), + getAttributionTag(), 0L /* messageId */); } /** @@ -957,8 +997,8 @@ public final class SmsManager { @NonNull List<String> parts, @Nullable List<PendingIntent> sentIntents, @Nullable List<PendingIntent> deliveryIntents, long messageId) { sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, - deliveryIntents, true /* persistMessage*/, null, null, - messageId); + deliveryIntents, true /* persistMessage*/, getOpPackageName(), + getAttributionTag(), messageId); } /** @@ -1088,8 +1128,8 @@ public final class SmsManager { String destinationAddress, String scAddress, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) { sendMultipartTextMessageInternal(destinationAddress, scAddress, parts, sentIntents, - deliveryIntents, false /* persistMessage*/, null, null, - 0L /* messageId */); + deliveryIntents, false /* persistMessage*/, getOpPackageName(), + getAttributionTag(), 0L /* messageId */); } /** @@ -1451,9 +1491,37 @@ public final class SmsManager { * @return the {@link SmsManager} associated with the default subscription id. * * @see SubscriptionManager#getDefaultSmsSubscriptionId() + * + * @deprecated Use {@link Context#getSystemService Context.getSystemService(SmsManager.class)} + * instead */ + @Deprecated public static SmsManager getDefault() { - return sInstance; + return DEFAULT_INSTANCE; + } + + /** + * Get the instance of the SmsManager associated with a particular context and subscription ID. + * + * @param context The context the manager belongs to + * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager} + * + * @return the instance of the SmsManager associated with subscription + * + * @hide + */ + public static @NonNull SmsManager getSmsManagerForContextAndSubscriptionId( + @Nullable Context context, int subId) { + synchronized(sLockObject) { + Pair<Context, Integer> key = new Pair<>(context, subId); + + SmsManager smsManager = sSubInstances.get(key); + if (smsManager == null) { + smsManager = new SmsManager(context, subId); + sSubInstances.put(key, smsManager); + } + return smsManager; + } } /** @@ -1468,19 +1536,33 @@ public final class SmsManager { * * @see SubscriptionManager#getActiveSubscriptionInfoList() * @see SubscriptionManager#getDefaultSmsSubscriptionId() + * @deprecated Use {@link Context#getSystemService Context.getSystemService(SmsManager.class)} + * .{@link #createForSubscriptionId createForSubscriptionId(subId)} instead */ + @Deprecated public static SmsManager getSmsManagerForSubscriptionId(int subId) { - synchronized(sLockObject) { - SmsManager smsManager = sSubInstances.get(subId); - if (smsManager == null) { - smsManager = new SmsManager(subId); - sSubInstances.put(subId, smsManager); - } - return smsManager; - } + return getSmsManagerForContextAndSubscriptionId(null, subId); + } + + /** + * Get the instance of the SmsManager associated with a particular subscription ID. + * + * <p class="note"><strong>Note:</strong> Constructing an {@link SmsManager} in this manner will + * never cause an SMS disambiguation dialog to appear, unlike {@link #getDefault()}. + * </p> + * + * @param subId an SMS subscription ID, typically accessed using {@link SubscriptionManager} + * @return the instance of the SmsManager associated with subscription + * + * @see SubscriptionManager#getActiveSubscriptionInfoList() + * @see SubscriptionManager#getDefaultSmsSubscriptionId() + */ + public @NonNull SmsManager createForSubscriptionId(int subId) { + return getSmsManagerForContextAndSubscriptionId(mContext, subId); } - private SmsManager(int subId) { + private SmsManager(@Nullable Context context, int subId) { + mContext = context; mSubId = subId; } diff --git a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java index c9540fb5f467..8308821b59ff 100644 --- a/telephony/java/android/telephony/TelephonyFrameworkInitializer.java +++ b/telephony/java/android/telephony/TelephonyFrameworkInitializer.java @@ -92,6 +92,12 @@ public class TelephonyFrameworkInitializer { ImsManager.class, context -> new ImsManager(context) ); + SystemServiceRegistry.registerContextAwareService( + Context.SMS_SERVICE, + SmsManager.class, + context -> SmsManager.getSmsManagerForContextAndSubscriptionId(context, + SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) + ); } /** @hide */ |