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

Commit 7a68be31 authored by Tom Taylor's avatar Tom Taylor
Browse files

Add two new intents

Add an ACTION_DEFAULT_SMS_PACKAGE_CHANGED intent to notify the old and
the new default sms app of the change. Add an ACTION_EXTERNAL_PROVIDER_CHANGE
intent used to notify the default SMS app when another whitelisted app
(such as AndroidAuto [via bluetooth] or the phone) changes the SmsProvider
or MmsProvider behind the default SMS's back.

Change-Id: Id036b1313124f08ff1d48b306e68b5f457d235c7
parent 6c806ef8
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -1070,6 +1070,39 @@ public final class Telephony {
            public static final String MMS_DOWNLOADED_ACTION =
                "android.provider.Telephony.MMS_DOWNLOADED";

            /**
             * Broadcast action: When the default SMS package changes,
             * the previous default SMS package and the new default SMS
             * package are sent this broadcast to notify them of the change.
             * A boolean is specified in {@link #EXTRA_IS_DEFAULT_SMS_APP} to
             * indicate whether the package is the new default SMS package.
            */
            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
            public static final String ACTION_DEFAULT_SMS_PACKAGE_CHANGED =
                            "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED";

            /**
             * The IsDefaultSmsApp boolean passed as an
             * extra for {@link #ACTION_DEFAULT_SMS_PACKAGE_CHANGED} to indicate whether the
             * SMS app is becoming the default SMS app or is no longer the default.
             *
             * @see #ACTION_DEFAULT_SMS_PACKAGE_CHANGED
             */
            public static final String EXTRA_IS_DEFAULT_SMS_APP =
                    "android.provider.extra.IS_DEFAULT_SMS_APP";

            /**
             * Broadcast action: When a change is made to the SmsProvider or
             * MmsProvider by a process other than the default SMS application,
             * this intent is broadcast to the default SMS application so it can
             * re-sync or update the change. The uri that was used to call the provider
             * can be retrieved from the intent with getData(). The actual affected uris
             * (which would depend on the selection specified) are not included.
            */
            @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
            public static final String ACTION_EXTERNAL_PROVIDER_CHANGE =
                          "android.provider.action.EXTERNAL_PROVIDER_CHANGE";

           /**
             * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
             * {@link #DATA_SMS_RECEIVED_ACTION} intent.
+142 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.os.Binder;
import android.os.Debug;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Telephony;
import android.provider.Telephony.Sms.Intents;
import android.telephony.Rlog;
import android.telephony.SmsManager;
@@ -97,6 +98,16 @@ public final class SmsApplication {
         */
        public String mSendToClass;

        /**
         * The class name of the ACTION_DEFAULT_SMS_PACKAGE_CHANGED receiver in this app.
         */
        public String mSmsAppChangedReceiverClass;

        /**
         * The class name of the ACTION_EXTERNAL_PROVIDER_CHANGE receiver in this app.
         */
        public String mProviderChangedReceiverClass;

        /**
         * The user-id for this application
         */
@@ -116,6 +127,19 @@ public final class SmsApplication {
            mPackageName = packageName;
            mUid = uid;
        }

        @Override
        public String toString() {
            return "mApplicationName: " + mApplicationName +
                    " mPackageName: " + mPackageName +
                    " mSmsReceiverClass: " + mSmsReceiverClass +
                    " mMmsReceiverClass: " + mMmsReceiverClass +
                    " mRespondViaMessageClass: " + mRespondViaMessageClass +
                    " mSendToClass: " + mSendToClass +
                    " mSmsAppChangedClass: " + mSmsAppChangedReceiverClass +
                    " mProviderChangedReceiverClass: " + mProviderChangedReceiverClass +
                    " mUid: " + mUid;
        }
    }

    /**
@@ -255,6 +279,56 @@ public final class SmsApplication {
            }
        }

        // Update any existing entries with the default sms changed handler.
        intent = new Intent(Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED);
        List<ResolveInfo> smsAppChangedReceivers = packageManager.queryBroadcastReceivers(intent,
                0, userId);
        if (DEBUG_MULTIUSER) {
            Log.i(LOG_TAG, "getApplicationCollectionInternal smsAppChangedActivities=" +
                    smsAppChangedReceivers);
        }
        for (ResolveInfo resolveInfo : smsAppChangedReceivers) {
            final ActivityInfo activityInfo = resolveInfo.activityInfo;
            if (activityInfo == null) {
                continue;
            }
            final String packageName = activityInfo.packageName;
            final SmsApplicationData smsApplicationData = receivers.get(packageName);
            if (DEBUG_MULTIUSER) {
                Log.i(LOG_TAG, "getApplicationCollectionInternal packageName=" +
                        packageName + " smsApplicationData: " + smsApplicationData +
                        " activityInfo.name: " + activityInfo.name);
            }
            if (smsApplicationData != null) {
                smsApplicationData.mSmsAppChangedReceiverClass = activityInfo.name;
            }
        }

        // Update any existing entries with the external provider changed handler.
        intent = new Intent(Telephony.Sms.Intents.ACTION_EXTERNAL_PROVIDER_CHANGE);
        List<ResolveInfo> providerChangedReceivers = packageManager.queryBroadcastReceivers(intent,
                0, userId);
        if (DEBUG_MULTIUSER) {
            Log.i(LOG_TAG, "getApplicationCollectionInternal providerChangedActivities=" +
                    providerChangedReceivers);
        }
        for (ResolveInfo resolveInfo : providerChangedReceivers) {
            final ActivityInfo activityInfo = resolveInfo.activityInfo;
            if (activityInfo == null) {
                continue;
            }
            final String packageName = activityInfo.packageName;
            final SmsApplicationData smsApplicationData = receivers.get(packageName);
            if (DEBUG_MULTIUSER) {
                Log.i(LOG_TAG, "getApplicationCollectionInternal packageName=" +
                        packageName + " smsApplicationData: " + smsApplicationData +
                        " activityInfo.name: " + activityInfo.name);
            }
            if (smsApplicationData != null) {
                smsApplicationData.mProviderChangedReceiverClass = activityInfo.name;
            }
        }

        // Remove any entries for which we did not find all required intents.
        for (ResolveInfo resolveInfo : smsReceivers) {
            final ActivityInfo activityInfo = resolveInfo.activityInfo;
@@ -427,6 +501,11 @@ public final class SmsApplication {
        String oldPackageName = Settings.Secure.getStringForUser(context.getContentResolver(),
                Settings.Secure.SMS_DEFAULT_APPLICATION, userId);

        if (DEBUG_MULTIUSER) {
            Log.i(LOG_TAG, "setDefaultApplicationInternal old=" + oldPackageName +
                    " new=" + packageName);
        }

        if (packageName != null && oldPackageName != null && packageName.equals(oldPackageName)) {
            // No change
            return;
@@ -435,6 +514,8 @@ public final class SmsApplication {
        // We only make the change if the new package is valid
        PackageManager packageManager = context.getPackageManager();
        Collection<SmsApplicationData> applications = getApplicationCollection(context);
        SmsApplicationData oldAppData = oldPackageName != null ?
                getApplicationForPackage(applications, oldPackageName) : null;
        SmsApplicationData applicationData = getApplicationForPackage(applications, packageName);
        if (applicationData != null) {
            // Ignore OP_WRITE_SMS for the previously configured default SMS app.
@@ -472,6 +553,41 @@ public final class SmsApplication {
                    MMS_SERVICE_PACKAGE_NAME);
            assignWriteSmsPermissionToSystemApp(context, packageManager, appOps,
                    TELEPHONY_PROVIDER_PACKAGE_NAME);

            if (DEBUG_MULTIUSER) {
                Log.i(LOG_TAG, "setDefaultApplicationInternal oldAppData=" + oldAppData);
            }
            if (oldAppData != null && oldAppData.mSmsAppChangedReceiverClass != null) {
                // Notify the old sms app that it's no longer the default
                final Intent oldAppIntent =
                        new Intent(Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED);
                final ComponentName component = new ComponentName(oldAppData.mPackageName,
                        oldAppData.mSmsAppChangedReceiverClass);
                oldAppIntent.setComponent(component);
                oldAppIntent.putExtra(Telephony.Sms.Intents.EXTRA_IS_DEFAULT_SMS_APP, false);
                if (DEBUG_MULTIUSER) {
                    Log.i(LOG_TAG, "setDefaultApplicationInternal old=" + oldAppData.mPackageName);
                }
                context.sendBroadcast(oldAppIntent);
            }
            // 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).
            if (DEBUG_MULTIUSER) {
                Log.i(LOG_TAG, "setDefaultApplicationInternal new applicationData=" +
                        applicationData);
            }
            if (applicationData.mSmsAppChangedReceiverClass != null) {
                final Intent intent =
                        new Intent(Telephony.Sms.Intents.ACTION_DEFAULT_SMS_PACKAGE_CHANGED);
                final ComponentName component = new ComponentName(applicationData.mPackageName,
                        applicationData.mSmsAppChangedReceiverClass);
                intent.setComponent(component);
                intent.putExtra(Telephony.Sms.Intents.EXTRA_IS_DEFAULT_SMS_APP, true);
                if (DEBUG_MULTIUSER) {
                    Log.i(LOG_TAG, "setDefaultApplicationInternal new=" + packageName);
                }
                context.sendBroadcast(intent);
            }
        }
    }

@@ -706,6 +822,32 @@ public final class SmsApplication {
        }
    }

    /**
     * Gets the default application that handles external changes to the SmsProvider and
     * MmsProvider.
     * @param context context from the calling app
     * @param updateIfNeeded update the default app if there is no valid default app configured.
     * @return component name of the app and class to deliver change intents to
     */
    public static ComponentName getDefaultExternalTelephonyProviderChangedApplication(
            Context context, boolean updateIfNeeded) {
        int userId = getIncomingUserId(context);
        final long token = Binder.clearCallingIdentity();
        try {
            ComponentName component = null;
            SmsApplicationData smsApplicationData = getApplication(context, updateIfNeeded,
                    userId);
            if (smsApplicationData != null
                    && smsApplicationData.mProviderChangedReceiverClass != null) {
                component = new ComponentName(smsApplicationData.mPackageName,
                        smsApplicationData.mProviderChangedReceiverClass);
            }
            return component;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    /**
     * Returns whether need to write the SMS message to SMS database for this package.
     * <p>