Merge "Post SUW Slot Change Receiver Migration" into sc-dev
This commit is contained in:
@@ -3661,6 +3661,14 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</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
|
<receiver
|
||||||
android:name=".sim.receivers.SimCompleteBootReceiver"
|
android:name=".sim.receivers.SimCompleteBootReceiver"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
@@ -12144,6 +12144,10 @@
|
|||||||
<string name="switch_to_removable_notification_no_carrier_name">Switched to another carrier</string>
|
<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] -->
|
<!-- 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>
|
<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 -->
|
<!-- Strings for choose SIM activity -->
|
||||||
<!-- The title text of choose SIM activity. [CHAR LIMIT=NONE] -->
|
<!-- The title text of choose SIM activity. [CHAR LIMIT=NONE] -->
|
||||||
|
@@ -66,12 +66,15 @@ public class SimActivationNotifier {
|
|||||||
value = {
|
value = {
|
||||||
NotificationType.NETWORK_CONFIG,
|
NotificationType.NETWORK_CONFIG,
|
||||||
NotificationType.SWITCH_TO_REMOVABLE_SLOT,
|
NotificationType.SWITCH_TO_REMOVABLE_SLOT,
|
||||||
|
NotificationType.ENABLE_DSDS,
|
||||||
})
|
})
|
||||||
public @interface NotificationType {
|
public @interface NotificationType {
|
||||||
// The notification to remind users to config network Settings.
|
// The notification to remind users to config network Settings.
|
||||||
int NETWORK_CONFIG = 1;
|
int NETWORK_CONFIG = 1;
|
||||||
// The notification to notify users that the device is switched to the removable slot.
|
// The notification to notify users that the device is switched to the removable slot.
|
||||||
int SWITCH_TO_REMOVABLE_SLOT = 2;
|
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;
|
private final Context mContext;
|
||||||
@@ -120,8 +123,8 @@ public class SimActivationNotifier {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CharSequence displayName = SubscriptionUtil.getUniqueSubscriptionDisplayName(
|
CharSequence displayName =
|
||||||
activeRemovableSub, mContext);
|
SubscriptionUtil.getUniqueSubscriptionDisplayName(activeRemovableSub, mContext);
|
||||||
String carrierName =
|
String carrierName =
|
||||||
TextUtils.isEmpty(displayName)
|
TextUtils.isEmpty(displayName)
|
||||||
? mContext.getString(R.string.sim_card_label)
|
? mContext.getString(R.string.sim_card_label)
|
||||||
@@ -135,7 +138,8 @@ public class SimActivationNotifier {
|
|||||||
TaskStackBuilder.create(mContext).addNextIntent(clickIntent);
|
TaskStackBuilder.create(mContext).addNextIntent(clickIntent);
|
||||||
PendingIntent contentIntent =
|
PendingIntent contentIntent =
|
||||||
stackBuilder.getPendingIntent(
|
stackBuilder.getPendingIntent(
|
||||||
0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT);
|
0 /* requestCode */,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||||
|
|
||||||
Notification.Builder builder =
|
Notification.Builder builder =
|
||||||
new Notification.Builder(mContext, SIM_SETUP_CHANNEL_ID)
|
new Notification.Builder(mContext, SIM_SETUP_CHANNEL_ID)
|
||||||
@@ -155,7 +159,8 @@ public class SimActivationNotifier {
|
|||||||
TaskStackBuilder.create(mContext).addNextIntent(clickIntent);
|
TaskStackBuilder.create(mContext).addNextIntent(clickIntent);
|
||||||
PendingIntent contentIntent =
|
PendingIntent contentIntent =
|
||||||
stackBuilder.getPendingIntent(
|
stackBuilder.getPendingIntent(
|
||||||
0 /* requestCode */, PendingIntent.FLAG_UPDATE_CURRENT);
|
0 /* requestCode */,
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
|
||||||
String titleText =
|
String titleText =
|
||||||
TextUtils.isEmpty(carrierName)
|
TextUtils.isEmpty(carrierName)
|
||||||
? mContext.getString(
|
? mContext.getString(
|
||||||
@@ -178,6 +183,33 @@ public class SimActivationNotifier {
|
|||||||
mNotificationManager.notify(SWITCH_TO_REMOVABLE_SLOT_NOTIFICATION_ID, builder.build());
|
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
|
@Nullable
|
||||||
private SubscriptionInfo getActiveRemovableSub() {
|
private SubscriptionInfo getActiveRemovableSub() {
|
||||||
SubscriptionManager subscriptionManager =
|
SubscriptionManager subscriptionManager =
|
||||||
|
@@ -71,6 +71,9 @@ public class SimNotificationService extends JobService {
|
|||||||
case SimActivationNotifier.NotificationType.SWITCH_TO_REMOVABLE_SLOT:
|
case SimActivationNotifier.NotificationType.SWITCH_TO_REMOVABLE_SLOT:
|
||||||
new SimActivationNotifier(this).sendSwitchedToRemovableSlotNotification();
|
new SimActivationNotifier(this).sendSwitchedToRemovableSlotNotification();
|
||||||
break;
|
break;
|
||||||
|
case SimActivationNotifier.NotificationType.ENABLE_DSDS:
|
||||||
|
new SimActivationNotifier(this).sendEnableDsdsNotification();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Log.e(TAG, "Invalid notification type: " + notificationType);
|
Log.e(TAG, "Invalid notification type: " + notificationType);
|
||||||
break;
|
break;
|
||||||
|
@@ -50,7 +50,13 @@ public class SimSlotChangeHandler {
|
|||||||
private static final String TAG = "SimSlotChangeHandler";
|
private static final String TAG = "SimSlotChangeHandler";
|
||||||
|
|
||||||
private static final String EUICC_PREFS = "euicc_prefs";
|
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_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;
|
private static volatile SimSlotChangeHandler sSlotChangeHandler;
|
||||||
|
|
||||||
@@ -107,6 +113,47 @@ public class SimSlotChangeHandler {
|
|||||||
Log.i(TAG, "Do nothing on slot status changes.");
|
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) {
|
private void init(Context context) {
|
||||||
mSubMgr =
|
mSubMgr =
|
||||||
(SubscriptionManager)
|
(SubscriptionManager)
|
||||||
@@ -116,11 +163,11 @@ public class SimSlotChangeHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleSimInsert(UiccSlotInfo removableSlotInfo) {
|
private void handleSimInsert(UiccSlotInfo removableSlotInfo) {
|
||||||
Log.i(TAG, "Detect SIM inserted.");
|
Log.i(TAG, "Handle SIM inserted.");
|
||||||
|
|
||||||
if (!isSuwFinished(mContext)) {
|
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");
|
Log.i(TAG, "Still in SUW. Handle SIM insertion after SUW is finished");
|
||||||
|
setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_INSERT);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,11 +203,11 @@ public class SimSlotChangeHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handleSimRemove(UiccSlotInfo removableSlotInfo) {
|
private void handleSimRemove(UiccSlotInfo removableSlotInfo) {
|
||||||
Log.i(TAG, "Detect SIM removed.");
|
Log.i(TAG, "Handle SIM removed.");
|
||||||
|
|
||||||
if (!isSuwFinished(mContext)) {
|
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");
|
Log.i(TAG, "Still in SUW. Handle SIM removal after SUW is finished");
|
||||||
|
setSuwRemovableSlotAction(mContext, LAST_USER_ACTION_IN_SUW_REMOVE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,6 +242,16 @@ public class SimSlotChangeHandler {
|
|||||||
prefs.edit().putInt(KEY_REMOVABLE_SLOT_STATE, state).apply();
|
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
|
@Nullable
|
||||||
private UiccSlotInfo getRemovableUiccSlotInfo() {
|
private UiccSlotInfo getRemovableUiccSlotInfo() {
|
||||||
UiccSlotInfo[] slotInfos = mTelMgr.getUiccSlotsInfo();
|
UiccSlotInfo[] slotInfos = mTelMgr.getUiccSlotsInfo();
|
||||||
|
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.settings.sim.receivers;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
|
/** The receiver when SUW is finished. */
|
||||||
|
public class SuwFinishReceiver extends BroadcastReceiver {
|
||||||
|
private static final String TAG = "SuwFinishReceiver";
|
||||||
|
|
||||||
|
private final SimSlotChangeHandler mSlotChangeHandler = SimSlotChangeHandler.get();
|
||||||
|
private final Object mLock = new Object();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (!context.getResources().getBoolean(R.bool.config_handle_sim_slot_change)) {
|
||||||
|
Log.i(TAG, "The flag is off. Ignore SUW finish event.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final BroadcastReceiver.PendingResult pendingResult = goAsync();
|
||||||
|
ThreadUtils.postOnBackgroundThread(
|
||||||
|
() -> {
|
||||||
|
synchronized (mLock) {
|
||||||
|
Log.i(TAG, "Detected SUW finished. Checking slot events.");
|
||||||
|
mSlotChangeHandler.onSuwFinish(context.getApplicationContext());
|
||||||
|
}
|
||||||
|
ThreadUtils.postOnMainThread(pendingResult::finish);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user