Loading AndroidManifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -3661,6 +3661,14 @@ </intent-filter> </receiver> <receiver android:name=".sim.receivers.SuwFinishReceiver" android:exported="true"> <intent-filter> <action android:name="com.google.android.setupwizard.SETUP_WIZARD_FINISHED" /> </intent-filter> </receiver> <receiver android:name=".sim.receivers.SimCompleteBootReceiver" android:exported="true"> Loading res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -12144,6 +12144,10 @@ <string name="switch_to_removable_notification_no_carrier_name">Switched to another carrier</string> <!-- Message in a push notification indicating that the user's phone has connected to a different mobile network. [CHAR LIMIT=NONE] --> <string name="network_changed_notification_text">Your mobile network has changed</string> <!-- Title on a push notification indicating that the user's device is capable of DSDS. [CHAR LIMIT=NONE] --> <string name="dsds_notification_after_suw_title">Set up your other SIM</string> <!-- Message in a push notification indicating that the user's device is capable of DSDS. [CHAR LIMIT=NONE] --> <string name="dsds_notification_after_suw_text">Choose your active SIM or use 2 SIMs at once</string> <!-- Strings for choose SIM activity --> <!-- The title text of choose SIM activity. [CHAR LIMIT=NONE] --> src/com/android/settings/sim/SimActivationNotifier.java +36 −4 Original line number Diff line number Diff line Loading @@ -66,12 +66,15 @@ public class SimActivationNotifier { value = { NotificationType.NETWORK_CONFIG, NotificationType.SWITCH_TO_REMOVABLE_SLOT, NotificationType.ENABLE_DSDS, }) public @interface NotificationType { // The notification to remind users to config network Settings. int NETWORK_CONFIG = 1; // The notification to notify users that the device is switched to the removable slot. int SWITCH_TO_REMOVABLE_SLOT = 2; // The notification to notify users that the device is capable of DSDS. int ENABLE_DSDS = 3; } private final Context mContext; Loading Loading @@ -120,8 +123,8 @@ public class SimActivationNotifier { return; } CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName( activeRemovableSub, mContext); CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName(activeRemovableSub, mContext); String carrierName = TextUtils.isEmpty(displayName) ? mContext.getString(R.string.sim_card_label) Loading @@ -135,7 +138,8 @@ public class SimActivationNotifier { TaskStackBuilder.create(mContext).addNextIntent(clickIntent); PendingIntent contentIntent = stackBuilder.getPendingIntent( 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT); 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); Notification.Builder builder = new Notification.Builder(mContext, SIM_SETUP_CHANNEL_ID) Loading @@ -155,7 +159,8 @@ public class SimActivationNotifier { TaskStackBuilder.create(mContext).addNextIntent(clickIntent); PendingIntent contentIntent = stackBuilder.getPendingIntent( 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT); 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); String titleText = TextUtils.isEmpty(carrierName) ? mContext.getString( Loading @@ -178,6 +183,33 @@ public class SimActivationNotifier { mNotificationManager.notify(SWITCH_TO_REMOVABLE_SLOT_NOTIFICATION_ID, builder.build()); } /** Sends a push notification for enabling DSDS. */ public void sendEnableDsdsNotification() { Intent parentIntent = new Intent(mContext, Settings.MobileNetworkListActivity.class); Intent clickIntent = new Intent(mContext, DsdsDialogActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(mContext) .addNextIntentWithParentStack(parentIntent) .addNextIntent(clickIntent); PendingIntent contentIntent = stackBuilder.getPendingIntent( 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); Notification.Builder builder = new Notification.Builder(mContext, SIM_SETUP_CHANNEL_ID) .setContentTitle( mContext.getString(R.string.dsds_notification_after_suw_title)) .setContentText( mContext.getString(R.string.dsds_notification_after_suw_text)) .setContentIntent(contentIntent) .setSmallIcon(R.drawable.ic_sim_alert) .setAutoCancel(true); mNotificationManager.notify(SIM_ACTIVATION_NOTIFICATION_ID, builder.build()); } @Nullable private SubscriptionInfo getActiveRemovableSub() { SubscriptionManager subscriptionManager = Loading src/com/android/settings/sim/SimNotificationService.java +3 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,9 @@ public class SimNotificationService extends JobService { case SimActivationNotifier.NotificationType.SWITCH_TO_REMOVABLE_SLOT: new SimActivationNotifier(this).sendSwitchedToRemovableSlotNotification(); break; case SimActivationNotifier.NotificationType.ENABLE_DSDS: new SimActivationNotifier(this).sendEnableDsdsNotification(); break; default: Log.e(TAG, "Invalid notification type: " + notificationType); break; Loading src/com/android/settings/sim/receivers/SimSlotChangeHandler.java +61 −4 Original line number Diff line number Diff line Loading @@ -50,7 +50,13 @@ public class SimSlotChangeHandler { private static final String TAG = "SimSlotChangeHandler"; private static final String EUICC_PREFS = "euicc_prefs"; // Shared preference keys private static final String KEY_REMOVABLE_SLOT_STATE = "removable_slot_state"; private static final String KEY_SUW_PSIM_ACTION = "suw_psim_action"; // User's last removable SIM insertion / removal action during SUW. private static final int LAST_USER_ACTION_IN_SUW_NONE = 0; private static final int LAST_USER_ACTION_IN_SUW_INSERT = 1; private static final int LAST_USER_ACTION_IN_SUW_REMOVE = 2; private static volatile SimSlotChangeHandler sSlotChangeHandler; Loading Loading @@ -107,6 +113,47 @@ public class SimSlotChangeHandler { Log.i(TAG, "Do nothing on slot status changes."); } void onSuwFinish(Context context) { init(context); if (Looper.myLooper() == Looper.getMainLooper()) { throw new IllegalStateException("Cannot be called from main thread."); } if (mTelMgr.getActiveModemCount() > 1) { Log.i(TAG, "The device is already in DSDS mode. Do nothing."); return; } UiccSlotInfo removableSlotInfo = getRemovableUiccSlotInfo(); if (removableSlotInfo == null) { Log.e(TAG, "Unable to find the removable slot. Do nothing."); return; } boolean embeddedSimExist = getGroupedEmbeddedSubscriptions().size() != 0; int removableSlotAction = getSuwRemovableSlotAction(mContext); setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_NONE); if (embeddedSimExist && removableSlotInfo.getCardStateInfo() == UiccSlotInfo.CARD_STATE_INFO_PRESENT) { if (mTelMgr.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) { Log.i(TAG, "DSDS condition satisfied. Show notification."); SimNotificationService.scheduleSimNotification( mContext, SimActivationNotifier.NotificationType.ENABLE_DSDS); } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_INSERT) { Log.i( TAG, "Both removable SIM and eSIM are present. DSDS condition doesn't" + " satisfied. User inserted pSIM during SUW. Show choose SIM" + " screen."); startChooseSimActivity(true); } } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_REMOVE) { handleSimRemove(removableSlotInfo); } } private void init(Context context) { mSubMgr = (SubscriptionManager) Loading @@ -116,11 +163,11 @@ public class SimSlotChangeHandler { } private void handleSimInsert(UiccSlotInfo removableSlotInfo) { Log.i(TAG, "Detect SIM inserted."); Log.i(TAG, "Handle SIM inserted."); if (!isSuwFinished(mContext)) { // TODO(b/170508680): Store the action and handle it after SUW is finished. Log.i(TAG, "Still in SUW. Handle SIM insertion after SUW is finished"); setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_INSERT); return; } Loading Loading @@ -156,11 +203,11 @@ public class SimSlotChangeHandler { } private void handleSimRemove(UiccSlotInfo removableSlotInfo) { Log.i(TAG, "Detect SIM removed."); Log.i(TAG, "Handle SIM removed."); if (!isSuwFinished(mContext)) { // TODO(b/170508680): Store the action and handle it after SUW is finished. Log.i(TAG, "Still in SUW. Handle SIM removal after SUW is finished"); setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_REMOVE); return; } Loading Loading @@ -195,6 +242,16 @@ public class SimSlotChangeHandler { prefs.edit().putInt(KEY_REMOVABLE_SLOT_STATE, state).apply(); } private int getSuwRemovableSlotAction(Context context) { final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE); return prefs.getInt(KEY_SUW_PSIM_ACTION, LAST_USER_ACTION_IN_SUW_NONE); } private void setSuwRemovableSlotAction(Context context, int action) { final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE); prefs.edit().putInt(KEY_SUW_PSIM_ACTION, action).apply(); } @Nullable private UiccSlotInfo getRemovableUiccSlotInfo() { UiccSlotInfo[] slotInfos = mTelMgr.getUiccSlotsInfo(); Loading Loading
AndroidManifest.xml +8 −0 Original line number Diff line number Diff line Loading @@ -3661,6 +3661,14 @@ </intent-filter> </receiver> <receiver android:name=".sim.receivers.SuwFinishReceiver" android:exported="true"> <intent-filter> <action android:name="com.google.android.setupwizard.SETUP_WIZARD_FINISHED" /> </intent-filter> </receiver> <receiver android:name=".sim.receivers.SimCompleteBootReceiver" android:exported="true"> Loading
res/values/strings.xml +4 −0 Original line number Diff line number Diff line Loading @@ -12144,6 +12144,10 @@ <string name="switch_to_removable_notification_no_carrier_name">Switched to another carrier</string> <!-- Message in a push notification indicating that the user's phone has connected to a different mobile network. [CHAR LIMIT=NONE] --> <string name="network_changed_notification_text">Your mobile network has changed</string> <!-- Title on a push notification indicating that the user's device is capable of DSDS. [CHAR LIMIT=NONE] --> <string name="dsds_notification_after_suw_title">Set up your other SIM</string> <!-- Message in a push notification indicating that the user's device is capable of DSDS. [CHAR LIMIT=NONE] --> <string name="dsds_notification_after_suw_text">Choose your active SIM or use 2 SIMs at once</string> <!-- Strings for choose SIM activity --> <!-- The title text of choose SIM activity. [CHAR LIMIT=NONE] -->
src/com/android/settings/sim/SimActivationNotifier.java +36 −4 Original line number Diff line number Diff line Loading @@ -66,12 +66,15 @@ public class SimActivationNotifier { value = { NotificationType.NETWORK_CONFIG, NotificationType.SWITCH_TO_REMOVABLE_SLOT, NotificationType.ENABLE_DSDS, }) public @interface NotificationType { // The notification to remind users to config network Settings. int NETWORK_CONFIG = 1; // The notification to notify users that the device is switched to the removable slot. int SWITCH_TO_REMOVABLE_SLOT = 2; // The notification to notify users that the device is capable of DSDS. int ENABLE_DSDS = 3; } private final Context mContext; Loading Loading @@ -120,8 +123,8 @@ public class SimActivationNotifier { return; } CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName( activeRemovableSub, mContext); CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName(activeRemovableSub, mContext); String carrierName = TextUtils.isEmpty(displayName) ? mContext.getString(R.string.sim_card_label) Loading @@ -135,7 +138,8 @@ public class SimActivationNotifier { TaskStackBuilder.create(mContext).addNextIntent(clickIntent); PendingIntent contentIntent = stackBuilder.getPendingIntent( 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT); 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); Notification.Builder builder = new Notification.Builder(mContext, SIM_SETUP_CHANNEL_ID) Loading @@ -155,7 +159,8 @@ public class SimActivationNotifier { TaskStackBuilder.create(mContext).addNextIntent(clickIntent); PendingIntent contentIntent = stackBuilder.getPendingIntent( 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT); 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); String titleText = TextUtils.isEmpty(carrierName) ? mContext.getString( Loading @@ -178,6 +183,33 @@ public class SimActivationNotifier { mNotificationManager.notify(SWITCH_TO_REMOVABLE_SLOT_NOTIFICATION_ID, builder.build()); } /** Sends a push notification for enabling DSDS. */ public void sendEnableDsdsNotification() { Intent parentIntent = new Intent(mContext, Settings.MobileNetworkListActivity.class); Intent clickIntent = new Intent(mContext, DsdsDialogActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(mContext) .addNextIntentWithParentStack(parentIntent) .addNextIntent(clickIntent); PendingIntent contentIntent = stackBuilder.getPendingIntent( 0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE); Notification.Builder builder = new Notification.Builder(mContext, SIM_SETUP_CHANNEL_ID) .setContentTitle( mContext.getString(R.string.dsds_notification_after_suw_title)) .setContentText( mContext.getString(R.string.dsds_notification_after_suw_text)) .setContentIntent(contentIntent) .setSmallIcon(R.drawable.ic_sim_alert) .setAutoCancel(true); mNotificationManager.notify(SIM_ACTIVATION_NOTIFICATION_ID, builder.build()); } @Nullable private SubscriptionInfo getActiveRemovableSub() { SubscriptionManager subscriptionManager = Loading
src/com/android/settings/sim/SimNotificationService.java +3 −0 Original line number Diff line number Diff line Loading @@ -71,6 +71,9 @@ public class SimNotificationService extends JobService { case SimActivationNotifier.NotificationType.SWITCH_TO_REMOVABLE_SLOT: new SimActivationNotifier(this).sendSwitchedToRemovableSlotNotification(); break; case SimActivationNotifier.NotificationType.ENABLE_DSDS: new SimActivationNotifier(this).sendEnableDsdsNotification(); break; default: Log.e(TAG, "Invalid notification type: " + notificationType); break; Loading
src/com/android/settings/sim/receivers/SimSlotChangeHandler.java +61 −4 Original line number Diff line number Diff line Loading @@ -50,7 +50,13 @@ public class SimSlotChangeHandler { private static final String TAG = "SimSlotChangeHandler"; private static final String EUICC_PREFS = "euicc_prefs"; // Shared preference keys private static final String KEY_REMOVABLE_SLOT_STATE = "removable_slot_state"; private static final String KEY_SUW_PSIM_ACTION = "suw_psim_action"; // User's last removable SIM insertion / removal action during SUW. private static final int LAST_USER_ACTION_IN_SUW_NONE = 0; private static final int LAST_USER_ACTION_IN_SUW_INSERT = 1; private static final int LAST_USER_ACTION_IN_SUW_REMOVE = 2; private static volatile SimSlotChangeHandler sSlotChangeHandler; Loading Loading @@ -107,6 +113,47 @@ public class SimSlotChangeHandler { Log.i(TAG, "Do nothing on slot status changes."); } void onSuwFinish(Context context) { init(context); if (Looper.myLooper() == Looper.getMainLooper()) { throw new IllegalStateException("Cannot be called from main thread."); } if (mTelMgr.getActiveModemCount() > 1) { Log.i(TAG, "The device is already in DSDS mode. Do nothing."); return; } UiccSlotInfo removableSlotInfo = getRemovableUiccSlotInfo(); if (removableSlotInfo == null) { Log.e(TAG, "Unable to find the removable slot. Do nothing."); return; } boolean embeddedSimExist = getGroupedEmbeddedSubscriptions().size() != 0; int removableSlotAction = getSuwRemovableSlotAction(mContext); setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_NONE); if (embeddedSimExist && removableSlotInfo.getCardStateInfo() == UiccSlotInfo.CARD_STATE_INFO_PRESENT) { if (mTelMgr.isMultiSimSupported() == TelephonyManager.MULTISIM_ALLOWED) { Log.i(TAG, "DSDS condition satisfied. Show notification."); SimNotificationService.scheduleSimNotification( mContext, SimActivationNotifier.NotificationType.ENABLE_DSDS); } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_INSERT) { Log.i( TAG, "Both removable SIM and eSIM are present. DSDS condition doesn't" + " satisfied. User inserted pSIM during SUW. Show choose SIM" + " screen."); startChooseSimActivity(true); } } else if (removableSlotAction == LAST_USER_ACTION_IN_SUW_REMOVE) { handleSimRemove(removableSlotInfo); } } private void init(Context context) { mSubMgr = (SubscriptionManager) Loading @@ -116,11 +163,11 @@ public class SimSlotChangeHandler { } private void handleSimInsert(UiccSlotInfo removableSlotInfo) { Log.i(TAG, "Detect SIM inserted."); Log.i(TAG, "Handle SIM inserted."); if (!isSuwFinished(mContext)) { // TODO(b/170508680): Store the action and handle it after SUW is finished. Log.i(TAG, "Still in SUW. Handle SIM insertion after SUW is finished"); setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_INSERT); return; } Loading Loading @@ -156,11 +203,11 @@ public class SimSlotChangeHandler { } private void handleSimRemove(UiccSlotInfo removableSlotInfo) { Log.i(TAG, "Detect SIM removed."); Log.i(TAG, "Handle SIM removed."); if (!isSuwFinished(mContext)) { // TODO(b/170508680): Store the action and handle it after SUW is finished. Log.i(TAG, "Still in SUW. Handle SIM removal after SUW is finished"); setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_REMOVE); return; } Loading Loading @@ -195,6 +242,16 @@ public class SimSlotChangeHandler { prefs.edit().putInt(KEY_REMOVABLE_SLOT_STATE, state).apply(); } private int getSuwRemovableSlotAction(Context context) { final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE); return prefs.getInt(KEY_SUW_PSIM_ACTION, LAST_USER_ACTION_IN_SUW_NONE); } private void setSuwRemovableSlotAction(Context context, int action) { final SharedPreferences prefs = context.getSharedPreferences(EUICC_PREFS, MODE_PRIVATE); prefs.edit().putInt(KEY_SUW_PSIM_ACTION, action).apply(); } @Nullable private UiccSlotInfo getRemovableUiccSlotInfo() { UiccSlotInfo[] slotInfos = mTelMgr.getUiccSlotsInfo(); Loading