Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82b66a4f authored by Makoto Onuki's avatar Makoto Onuki Committed by Android (Google) Code Review
Browse files

Merge "Add telephony commands about SMS apps"

parents b981efa9 a042aaad
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -615,6 +615,8 @@
    <protected-broadcast android:name="com.android.server.jobscheduler.FORCE_IDLE" />
    <protected-broadcast android:name="com.android.server.jobscheduler.UNFORCE_IDLE" />

    <protected-broadcast android:name="android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL" />

    <!-- ====================================================================== -->
    <!--                          RUNTIME PERMISSIONS                           -->
    <!-- ====================================================================== -->
@@ -4136,6 +4138,12 @@
    <permission android:name="android.permission.DISABLE_HIDDEN_API_CHECKS"
                android:protectionLevel="signature" />

    <!-- @hide Permission that protects the
        {@link android.provider.Telephony.Intents#ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL}
        broadcast -->
    <permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE"
        android:protectionLevel="signature" />

    <application android:process="system"
                 android:persistent="true"
                 android:hasCode="false"
+11 −0
Original line number Diff line number Diff line
@@ -1232,6 +1232,17 @@ public final class Telephony {
            public static final String ACTION_EXTERNAL_PROVIDER_CHANGE =
                          "android.provider.action.EXTERNAL_PROVIDER_CHANGE";

            /**
             * Same as {@link #ACTION_DEFAULT_SMS_PACKAGE_CHANGED} but it's implicit (e.g. sent to
             * all apps) and requires
             * {@link android.Manifest.permission#MONITOR_DEFAULT_SMS_PACKAGE} to receive.
             *
             * @hide
             */
            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
            public static final String ACTION_DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL =
                    "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL";

            /**
             * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
             * {@link #DATA_SMS_RECEIVED_ACTION} intent.
+15 −0
Original line number Diff line number Diff line
@@ -1587,4 +1587,19 @@ interface ITelephony {
     * Return the network selection mode on the subscription with id {@code subId}.
     */
     int getNetworkSelectionMode(int subId);

    /**
     * Get a list of SMS apps on a user.
     */
    String[] getSmsApps(int userId);

    /**
     * Get the default SMS app on a given user.
     */
    String getDefaultSmsApp(int userId);

    /**
     * Set the default SMS app to a given package on a given user.
     */
    void setDefaultSmsApp(int userId, String packageName);
}
+40 −5
Original line number Diff line number Diff line
@@ -209,7 +209,14 @@ public final class SmsApplication {
     * Support smsto Uri scheme.
     */
    public static Collection<SmsApplicationData> 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<SmsApplicationData> 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;
+14 −0
Original line number Diff line number Diff line
@@ -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;
@@ -307,4 +308,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");
    }
}