Add API to SmsManager to allow apps to authenticate user account through
sms without requesting sms permissions.
Bug: 111210542
Test: atest android.telephony.cts.SmsManagerTest
Change-Id: I9b176032d7b2bf578dd1a64745bf4a1e13008a7a
diff --git a/api/current.txt b/api/current.txt
index bb6dbeb..2d615f5 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -44662,6 +44662,7 @@
public final class SmsManager {
method public String createAppSpecificSmsToken(android.app.PendingIntent);
+ method @Nullable public String createAppSpecificSmsTokenWithPackageInfo(@Nullable String, @NonNull android.app.PendingIntent);
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 public android.os.Bundle getCarrierConfigValues();
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index d777bf1..aaca18a 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -16,6 +16,8 @@
package android.telephony;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressAutoDoc;
import android.annotation.SystemApi;
@@ -2145,6 +2147,79 @@
}
/**
+ * @see #createAppSpecificSmsTokenWithPackageInfo().
+ * The prefixes is a list of prefix {@code String} separated by this delimiter.
+ * @hide
+ */
+ public static final String REGEX_PREFIX_DELIMITER = ",";
+ /**
+ * @see #createAppSpecificSmsTokenWithPackageInfo().
+ * The success status to be added into the intent to be sent to the calling package.
+ * @hide
+ */
+ public static final int RESULT_STATUS_SUCCESS = 0;
+ /**
+ * @see #createAppSpecificSmsTokenWithPackageInfo().
+ * The timeout status to be added into the intent to be sent to the calling package.
+ * @hide
+ */
+ public static final int RESULT_STATUS_TIMEOUT = 1;
+ /**
+ * @see #createAppSpecificSmsTokenWithPackageInfo().
+ * Intent extra key of the retrieved SMS message as a {@code String}.
+ * @hide
+ */
+ public static final String EXTRA_SMS_MESSAGE = "android.telephony.extra.SMS_MESSAGE";
+ /**
+ * @see #createAppSpecificSmsTokenWithPackageInfo().
+ * Intent extra key of SMS retriever status, which indicates whether the request for the
+ * coming SMS message is SUCCESS or TIMEOUT
+ * @hide
+ */
+ public static final String EXTRA_STATUS = "android.telephony.extra.STATUS";
+ /**
+ * @see #createAppSpecificSmsTokenWithPackageInfo().
+ * [Optional] Intent extra key of the retrieved Sim card subscription Id if any. {@code int}
+ * @hide
+ */
+ public static final String EXTRA_SIM_SUBSCRIPTION_ID =
+ "android.telephony.extra.SIM_SUBSCRIPTION_ID";
+
+ /**
+ * Create a single use app specific incoming SMS request for the calling package.
+ *
+ * This method returns a token that if included in a subsequent incoming SMS message, and the
+ * SMS message has a prefix from the given prefixes list, the provided {@code intent} will be
+ * sent with the SMS data to the calling package.
+ *
+ * The token is only good for one use within a reasonable amount of time. After an SMS has been
+ * received containing the token all subsequent SMS messages with the token will be routed as
+ * normal.
+ *
+ * An app can only have one request at a time, if the app already has a request pending it will
+ * be replaced with a new request.
+ *
+ * @param prefixes this is a list of prefixes string separated by REGEX_PREFIX_DELIMITER. The
+ * matching SMS message should have at least one of the prefixes in the beginning of the
+ * message.
+ * @param intent this intent is sent when the matching SMS message is received.
+ * @return Token to include in an SMS message.
+ */
+ @Nullable
+ public String createAppSpecificSmsTokenWithPackageInfo(
+ @Nullable String prefixes, @NonNull PendingIntent intent) {
+ try {
+ ISms iccSms = getISmsServiceOrThrow();
+ return iccSms.createAppSpecificSmsTokenWithPackageInfo(getSubscriptionId(),
+ ActivityThread.currentPackageName(), prefixes, intent);
+
+ } catch (RemoteException ex) {
+ ex.rethrowFromSystemServer();
+ return null;
+ }
+ }
+
+ /**
* Filters a bundle to only contain MMS config variables.
*
* This is for use with bundles returned by {@link CarrierConfigManager} which contain MMS
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index a4eb424..58ebb15 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -560,4 +560,19 @@
* @param intent PendingIntent to be sent when an SMS is received containing the token.
*/
String createAppSpecificSmsToken(int subId, String callingPkg, in PendingIntent intent);
+
+ /**
+ * Create an app-only incoming SMS request for the calling package.
+ *
+ * If an incoming text contains the token returned by this method the provided
+ * <code>PendingIntent</code> will be sent containing the SMS data.
+ *
+ * @param subId the SIM id.
+ * @param callingPkg the package name of the calling app.
+ * @param prefixes the caller provided prefixes
+ * @param intent PendingIntent to be sent when a SMS is received containing the token and one
+ * of the prefixes
+ */
+ String createAppSpecificSmsTokenWithPackageInfo(
+ int subId, String callingPkg, String prefixes, in PendingIntent intent);
}
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index 1cdf44d..f2f2960 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -188,4 +188,10 @@
public String createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent) {
throw new UnsupportedOperationException();
}
+
+ @Override
+ public String createAppSpecificSmsTokenWithPackageInfo(
+ int subId, String callingPkg, String prefixes, PendingIntent intent) {
+ throw new UnsupportedOperationException();
+ }
}