[Settings] Fix the inconsistent data/entity when switch the app/fragment

Bug: 271524675
Bug: 273825889
Test: local test
Change-Id: I7ec6d824c5154422aaad056dc3f4dcd365fef5e1
This commit is contained in:
Zoey Chen
2023-03-16 18:40:08 +00:00
parent ce77de4240
commit b9f6bb7958

View File

@@ -20,6 +20,7 @@ import static android.telephony.UiccSlotInfo.CARD_STATE_INFO_PRESENT;
import static com.android.internal.telephony.TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED; import static com.android.internal.telephony.TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED;
import android.annotation.NonNull;
import android.app.settings.SettingsEnums; import android.app.settings.SettingsEnums;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
@@ -56,10 +57,12 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import androidx.annotation.GuardedBy;
import androidx.lifecycle.Lifecycle; import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleObserver;
import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LifecycleOwner;
@@ -72,14 +75,17 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static ExecutorService sExecutor = Executors.newSingleThreadExecutor(); private static ExecutorService sExecutor = Executors.newSingleThreadExecutor();
private static Map<String, SubscriptionInfoEntity> sCacheSubscriptionInfoEntityMap = private static Map<Integer, SubscriptionInfoEntity> sCacheSubscriptionInfoEntityMap =
new ArrayMap<>(); new ArrayMap<>();
private static Map<String, MobileNetworkInfoEntity> sCacheMobileNetworkInfoEntityMap = private static Map<Integer, MobileNetworkInfoEntity> sCacheMobileNetworkInfoEntityMap =
new ArrayMap<>(); new ArrayMap<>();
private static Map<String, UiccInfoEntity> sCacheUiccInfoEntityMap = new ArrayMap<>(); private static Map<Integer, UiccInfoEntity> sCacheUiccInfoEntityMap = new ArrayMap<>();
private static Collection<MobileNetworkCallback> sCallbacks = new CopyOnWriteArrayList<>();
private static final Object sInstanceLock = new Object();
@GuardedBy("sInstanceLock")
private static MobileNetworkRepository sInstance;
private SubscriptionManager mSubscriptionManager; private SubscriptionManager mSubscriptionManager;
private TelephonyManager mTelephonyManager;
private MobileNetworkDatabase mMobileNetworkDatabase; private MobileNetworkDatabase mMobileNetworkDatabase;
private SubscriptionInfoDao mSubscriptionInfoDao; private SubscriptionInfoDao mSubscriptionInfoDao;
private UiccInfoDao mUiccInfoDao; private UiccInfoDao mUiccInfoDao;
@@ -88,7 +94,6 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
private List<SubscriptionInfoEntity> mActiveSubInfoEntityList = new ArrayList<>(); private List<SubscriptionInfoEntity> mActiveSubInfoEntityList = new ArrayList<>();
private List<UiccInfoEntity> mUiccInfoEntityList = new ArrayList<>(); private List<UiccInfoEntity> mUiccInfoEntityList = new ArrayList<>();
private List<MobileNetworkInfoEntity> mMobileNetworkInfoEntityList = new ArrayList<>(); private List<MobileNetworkInfoEntity> mMobileNetworkInfoEntityList = new ArrayList<>();
private MobileNetworkCallback mCallback;
private Context mContext; private Context mContext;
private AirplaneModeObserver mAirplaneModeObserver; private AirplaneModeObserver mAirplaneModeObserver;
private Uri mAirplaneModeSettingUri; private Uri mAirplaneModeSettingUri;
@@ -100,35 +105,34 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
private int mCardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT; private int mCardState = UiccSlotInfo.CARD_STATE_INFO_ABSENT;
private int mPortIndex = TelephonyManager.INVALID_PORT_INDEX; private int mPortIndex = TelephonyManager.INVALID_PORT_INDEX;
private int mCardId = TelephonyManager.UNINITIALIZED_CARD_ID; private int mCardId = TelephonyManager.UNINITIALIZED_CARD_ID;
private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
private boolean mIsEuicc = false; private boolean mIsEuicc = false;
private boolean mIsRemovable = false; private boolean mIsRemovable = false;
private boolean mIsActive = false; private boolean mIsActive = false;
private Map<Integer, SubscriptionInfo> mSubscriptionInfoMap = new ArrayMap<>(); private Map<Integer, SubscriptionInfo> mSubscriptionInfoMap = new ArrayMap<>();
private Map<Integer, TelephonyManager> mTelephonyManagerMap = new HashMap<>(); private Map<Integer, TelephonyManager> mTelephonyManagerMap = new HashMap<>();
private Map<Integer, PhoneCallStateTelephonyCallback> mTelephonyCallbackMap = new HashMap<>(); private Map<Integer, PhoneCallStateTelephonyCallback> mTelephonyCallbackMap = new HashMap<>();
private BroadcastReceiver mDataSubscriptionChangedReceiver = null;
public static MobileNetworkRepository create(Context context, @NonNull
MobileNetworkCallback mobileNetworkCallback) { public static MobileNetworkRepository getInstance(Context context) {
return new MobileNetworkRepository(context, mobileNetworkCallback, synchronized (sInstanceLock) {
SubscriptionManager.INVALID_SUBSCRIPTION_ID); if (sInstance != null) {
return sInstance;
}
if (DEBUG) {
Log.d(TAG, "Init the instance.");
}
sInstance = new MobileNetworkRepository(context);
return sInstance;
}
} }
public static MobileNetworkRepository createBySubId(Context context, private MobileNetworkRepository(Context context) {
MobileNetworkCallback mobileNetworkCallback, int subId) {
return new MobileNetworkRepository(context, mobileNetworkCallback, subId);
}
private MobileNetworkRepository(Context context, MobileNetworkCallback mobileNetworkCallback,
int subId) {
mSubId = subId;
mContext = context; mContext = context;
mMobileNetworkDatabase = MobileNetworkDatabase.getInstance(context); mMobileNetworkDatabase = MobileNetworkDatabase.getInstance(context);
mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider(); mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_CREATED, mMetricsFeatureProvider.action(mContext, SettingsEnums.ACTION_MOBILE_NETWORK_DB_CREATED);
subId);
mSubscriptionManager = context.getSystemService(SubscriptionManager.class); mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
mCallback = mobileNetworkCallback;
mSubscriptionInfoDao = mMobileNetworkDatabase.mSubscriptionInfoDao(); mSubscriptionInfoDao = mMobileNetworkDatabase.mSubscriptionInfoDao();
mUiccInfoDao = mMobileNetworkDatabase.mUiccInfoDao(); mUiccInfoDao = mMobileNetworkDatabase.mUiccInfoDao();
mMobileNetworkInfoDao = mMobileNetworkDatabase.mMobileNetworkInfoDao(); mMobileNetworkInfoDao = mMobileNetworkDatabase.mMobileNetworkInfoDao();
@@ -138,6 +142,8 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED); mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SUBSCRIPTION_CHANGED);
mFilter.addAction(ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED); mFilter.addAction(ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED); mFilter.addAction(SubscriptionManager.ACTION_DEFAULT_SMS_SUBSCRIPTION_CHANGED);
mDataSubscriptionChangedReceiver = new DataSubscriptionChangedReceiver();
mContext.registerReceiver(mDataSubscriptionChangedReceiver, mFilter);
} }
private class AirplaneModeObserver extends ContentObserver { private class AirplaneModeObserver extends ContentObserver {
@@ -157,56 +163,98 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
@Override @Override
public void onChange(boolean selfChange, Uri uri) { public void onChange(boolean selfChange, Uri uri) {
if (uri.equals(mAirplaneModeSettingUri)) { if (uri.equals(mAirplaneModeSettingUri)) {
mCallback.onAirplaneModeChanged(isAirplaneModeOn()); boolean isAirplaneModeOn = isAirplaneModeOn();
for (MobileNetworkCallback callback : sCallbacks) {
callback.onAirplaneModeChanged(isAirplaneModeOn);
}
} }
} }
} }
private final BroadcastReceiver mDataSubscriptionChangedReceiver = new BroadcastReceiver() { private class DataSubscriptionChangedReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
onSubscriptionsChanged(); onSubscriptionsChanged();
} }
}; }
public void addRegister(LifecycleOwner lifecycleOwner) { /**
* Register all callbacks and listener.
*
* @param lifecycleOwner The lifecycle owner.
* @param mobileNetworkCallback A callback to receive all MobileNetwork's changes.
* @param subId The subscription ID to register relevant changes and listener for specific
* subscription.
*/
public void addRegister(LifecycleOwner lifecycleOwner,
MobileNetworkCallback mobileNetworkCallback, int subId) {
sCallbacks.add(mobileNetworkCallback);
mSubscriptionManager.addOnSubscriptionsChangedListener(mContext.getMainExecutor(), this); mSubscriptionManager.addOnSubscriptionsChangedListener(mContext.getMainExecutor(), this);
mAirplaneModeObserver.register(mContext); mAirplaneModeObserver.register(mContext);
mContext.registerReceiver(mDataSubscriptionChangedReceiver, mFilter);
observeAllSubInfo(lifecycleOwner); observeAllSubInfo(lifecycleOwner);
observeAllUiccInfo(lifecycleOwner); observeAllUiccInfo(lifecycleOwner);
observeAllMobileNetworkInfo(lifecycleOwner); observeAllMobileNetworkInfo(lifecycleOwner);
if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
addRegisterBySubId(subId);
createTelephonyManagerBySubId(subId);
}
} }
private void addRegisterBySubId(int subId) { private void addRegisterBySubId(int subId) {
if (!mTelephonyCallbackMap.containsKey(subId) || !mTelephonyManagerMap.containsKey(subId)) { MobileDataContentObserver dataContentObserver = new MobileDataContentObserver(
PhoneCallStateTelephonyCallback new Handler(Looper.getMainLooper()));
telephonyCallback = new PhoneCallStateTelephonyCallback(); dataContentObserver.setOnMobileDataChangedListener(() -> {
mTelephonyManager.registerTelephonyCallback(mContext.getMainExecutor(), sExecutor.execute(() -> {
telephonyCallback); insertMobileNetworkInfo(mContext, subId,
mTelephonyCallbackMap.put(subId, telephonyCallback); getTelephonyManagerBySubId(mContext, subId));
mTelephonyManagerMap.put(subId, mTelephonyManager);
}
if (!mDataContentObserverMap.containsKey(subId)) {
MobileDataContentObserver dataContentObserver = new MobileDataContentObserver(
new Handler(Looper.getMainLooper()));
dataContentObserver.register(mContext, subId);
dataContentObserver.setOnMobileDataChangedListener(() -> {
sExecutor.execute(() -> {
insertMobileNetworkInfo(mContext, String.valueOf(subId));
});
}); });
mDataContentObserverMap.put(subId, dataContentObserver); });
dataContentObserver.register(mContext, subId);
mDataContentObserverMap.put(subId, dataContentObserver);
}
private void createTelephonyManagerBySubId(int subId) {
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
return;
} }
PhoneCallStateTelephonyCallback
telephonyCallback = new PhoneCallStateTelephonyCallback();
TelephonyManager telephonyManager = mContext.getSystemService(
TelephonyManager.class).createForSubscriptionId(subId);
telephonyManager.registerTelephonyCallback(mContext.getMainExecutor(),
telephonyCallback);
mTelephonyCallbackMap.put(subId, telephonyCallback);
mTelephonyManagerMap.put(subId, telephonyManager);
}
private TelephonyManager getTelephonyManagerBySubId(Context context, int subId) {
TelephonyManager telephonyManager = mTelephonyManagerMap.get(subId);
if (telephonyManager != null) {
return telephonyManager;
}
if (context != null) {
telephonyManager = context.getSystemService(TelephonyManager.class);
if (telephonyManager != null) {
telephonyManager = telephonyManager.createForSubscriptionId(subId);
} else if (DEBUG) {
Log.d(TAG, "Can not get TelephonyManager for subId " + subId);
}
}
return telephonyManager;
} }
private void removerRegisterBySubId(int subId) { private void removerRegisterBySubId(int subId) {
if (mTelephonyCallbackMap.containsKey(subId)) { if (mTelephonyCallbackMap.containsKey(subId)) {
TelephonyManager tm = mTelephonyManagerMap.get(subId); TelephonyManager telephonyManager = getTelephonyManagerBySubId(mContext, subId);
PhoneCallStateTelephonyCallback callback = mTelephonyCallbackMap.get(subId); if (telephonyManager != null) {
if (callback != null) { PhoneCallStateTelephonyCallback callback = mTelephonyCallbackMap.get(subId);
tm.unregisterTelephonyCallback(callback); if (callback != null) {
mTelephonyCallbackMap.remove(subId); telephonyManager.unregisterTelephonyCallback(callback);
mTelephonyCallbackMap.remove(subId);
}
} }
} }
if (mDataContentObserverMap.containsKey(subId)) { if (mDataContentObserverMap.containsKey(subId)) {
@@ -215,25 +263,43 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
} }
} }
public void removeRegister() { public void removeRegister(MobileNetworkCallback mobileNetworkCallback) {
mSubscriptionManager.removeOnSubscriptionsChangedListener(this); sCallbacks.remove(mobileNetworkCallback);
mAirplaneModeObserver.unRegister(mContext); if (sCallbacks.isEmpty()) {
if (mDataSubscriptionChangedReceiver != null) { mSubscriptionManager.removeOnSubscriptionsChangedListener(this);
mContext.unregisterReceiver(mDataSubscriptionChangedReceiver); mAirplaneModeObserver.unRegister(mContext);
} if (mDataSubscriptionChangedReceiver != null) {
mDataContentObserverMap.forEach((id, observer) -> { mContext.unregisterReceiver(mDataSubscriptionChangedReceiver);
observer.unRegister(mContext); mDataSubscriptionChangedReceiver = null;
});
mDataContentObserverMap.clear();
mTelephonyManagerMap.forEach((id, manager) -> {
TelephonyCallback callback = mTelephonyCallbackMap.get(manager.getSubscriptionId());
if (callback != null) {
manager.unregisterTelephonyCallback(callback);
} }
}); mDataContentObserverMap.forEach((id, observer) -> {
mTelephonyCallbackMap.clear(); observer.unRegister(mContext);
mTelephonyManagerMap.clear(); });
mDataContentObserverMap.clear();
mTelephonyManagerMap.forEach((id, manager) -> {
TelephonyCallback callback = mTelephonyCallbackMap.get(id);
if (callback != null) {
manager.unregisterTelephonyCallback(callback);
}
});
mTelephonyCallbackMap.clear();
mTelephonyManagerMap.clear();
}
}
public void updateEntity() {
// Check the latest state after back to the UI.
if (sCacheSubscriptionInfoEntityMap != null || !sCacheSubscriptionInfoEntityMap.isEmpty()) {
sExecutor.execute(() -> {
onSubscriptionsChanged();
});
}
boolean isAirplaneModeOn = isAirplaneModeOn();
for (MobileNetworkCallback callback : sCallbacks) {
callback.onAirplaneModeChanged(isAirplaneModeOn);
}
} }
private void observeAllSubInfo(LifecycleOwner lifecycleOwner) { private void observeAllSubInfo(LifecycleOwner lifecycleOwner) {
@@ -284,18 +350,6 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
return mMobileNetworkInfoDao.queryMobileNetworkInfoBySubId(subId); return mMobileNetworkInfoDao.queryMobileNetworkInfoBySubId(subId);
} }
public int getSubInfosCount() {
return mSubscriptionInfoDao.count();
}
public int getUiccInfosCount() {
return mUiccInfoDao.count();
}
public int getMobileNetworkInfosCount() {
return mMobileNetworkInfoDao.count();
}
private void getUiccInfoBySubscriptionInfo(UiccSlotInfo[] uiccSlotInfos, private void getUiccInfoBySubscriptionInfo(UiccSlotInfo[] uiccSlotInfos,
SubscriptionInfo subInfo) { SubscriptionInfo subInfo) {
for (int i = 0; i < uiccSlotInfos.length; i++) { for (int i = 0; i < uiccSlotInfos.length; i++) {
@@ -317,7 +371,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
mPortIndex = portInfo.getPortIndex(); mPortIndex = portInfo.getPortIndex();
} else if (DEBUG) { } else if (DEBUG) {
Log.d(TAG, "Can not get port index and physicalSlotIndex for subId " Log.d(TAG, "Can not get port index and physicalSlotIndex for subId "
+ mSubId); + subInfo.getSubscriptionId());
} }
}); });
if (mPhysicalSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) { if (mPhysicalSlotIndex != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
@@ -334,70 +388,82 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
private void onAvailableSubInfoChanged( private void onAvailableSubInfoChanged(
List<SubscriptionInfoEntity> availableSubInfoEntityList) { List<SubscriptionInfoEntity> availableSubInfoEntityList) {
mAvailableSubInfoEntityList = availableSubInfoEntityList; mAvailableSubInfoEntityList = new ArrayList<>(availableSubInfoEntityList);
mActiveSubInfoEntityList = mAvailableSubInfoEntityList.stream()
.filter(SubscriptionInfoEntity::isActiveSubscription)
.filter(SubscriptionInfoEntity::isSubscriptionVisible)
.collect(Collectors.toList());
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "onAvailableSubInfoChanged, availableSubInfoEntityList = " Log.d(TAG, "onAvailableSubInfoChanged, availableSubInfoEntityList = "
+ availableSubInfoEntityList); + availableSubInfoEntityList);
} }
mCallback.onAvailableSubInfoChanged(availableSubInfoEntityList); for (MobileNetworkCallback callback : sCallbacks) {
callback.onAvailableSubInfoChanged(availableSubInfoEntityList);
}
mMetricsFeatureProvider.action(mContext, mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_SUB_INFO_IS_CHANGED, 0); SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_SUB_INFO_IS_CHANGED, 0);
setActiveSubInfoList(mActiveSubInfoEntityList); onActiveSubInfoListChanged(mAvailableSubInfoEntityList);
} }
private void setActiveSubInfoList(List<SubscriptionInfoEntity> activeSubInfoEntityList) { private void onActiveSubInfoListChanged(
List<SubscriptionInfoEntity> availableSubInfoEntityList) {
mActiveSubInfoEntityList = availableSubInfoEntityList.stream()
.filter(SubscriptionInfoEntity::isActiveSubscription)
.filter(SubscriptionInfoEntity::isSubscriptionVisible)
.collect(Collectors.toList());
if (DEBUG) { if (DEBUG) {
Log.d(TAG, Log.d(TAG, "onActiveSubInfoChanged, activeSubInfoEntityList = "
"onActiveSubInfoChanged, activeSubInfoEntityList = " + activeSubInfoEntityList); + mActiveSubInfoEntityList);
}
List<SubscriptionInfoEntity> activeSubInfoEntityList = new ArrayList<>(
mActiveSubInfoEntityList);
for (MobileNetworkCallback callback : sCallbacks) {
callback.onActiveSubInfoChanged(activeSubInfoEntityList);
} }
mCallback.onActiveSubInfoChanged(mActiveSubInfoEntityList);
} }
private void onAllUiccInfoChanged(List<UiccInfoEntity> uiccInfoEntityList) { private void onAllUiccInfoChanged(List<UiccInfoEntity> uiccInfoEntityList) {
mUiccInfoEntityList = uiccInfoEntityList; mUiccInfoEntityList = new ArrayList<>(uiccInfoEntityList);
mCallback.onAllUiccInfoChanged(uiccInfoEntityList); for (MobileNetworkCallback callback : sCallbacks) {
callback.onAllUiccInfoChanged(uiccInfoEntityList);
}
mMetricsFeatureProvider.action(mContext, mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_UICC_INFO_IS_CHANGED, 0); SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_UICC_INFO_IS_CHANGED, 0);
} }
private void onAllMobileNetworkInfoChanged( private void onAllMobileNetworkInfoChanged(
List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList) { List<MobileNetworkInfoEntity> mobileNetworkInfoEntityList) {
mMobileNetworkInfoEntityList = mobileNetworkInfoEntityList; mMobileNetworkInfoEntityList = new ArrayList<>(mobileNetworkInfoEntityList);
mCallback.onAllMobileNetworkInfoChanged(mobileNetworkInfoEntityList); for (MobileNetworkCallback callback : sCallbacks) {
callback.onAllMobileNetworkInfoChanged(mobileNetworkInfoEntityList);
}
mMetricsFeatureProvider.action(mContext, mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_MOBILE_NETWORK_INFO_IS_CHANGED, 0); SettingsEnums.ACTION_MOBILE_NETWORK_DB_NOTIFY_MOBILE_NETWORK_INFO_IS_CHANGED, 0);
} }
public void insertSubInfo(Context context, SubscriptionInfo info) { private void insertSubInfo(Context context, SubscriptionInfo info) {
int subId = info.getSubscriptionId();
createTelephonyManagerBySubId(subId);
TelephonyManager telephonyManager = getTelephonyManagerBySubId(context, subId);
SubscriptionInfoEntity subInfoEntity = SubscriptionInfoEntity subInfoEntity =
convertToSubscriptionInfoEntity(context, info); convertToSubscriptionInfoEntity(context, info, telephonyManager);
String subId = String.valueOf(mSubId);
if (subInfoEntity != null) { if (subInfoEntity != null) {
if (!sCacheSubscriptionInfoEntityMap.containsKey(subId) if (!sCacheSubscriptionInfoEntityMap.containsKey(subId)
|| (sCacheSubscriptionInfoEntityMap.get(subId) != null || (sCacheSubscriptionInfoEntityMap.get(subId) != null
&& !sCacheSubscriptionInfoEntityMap.get(subId).equals(subInfoEntity))) { && !sCacheSubscriptionInfoEntityMap.get(subId).equals(subInfoEntity))) {
sCacheSubscriptionInfoEntityMap.put(subId, subInfoEntity); sCacheSubscriptionInfoEntityMap.put(subId, subInfoEntity);
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "convert subId " + subId + "to SubscriptionInfoEntity: " Log.d(TAG, "Convert subId " + subId + " to SubscriptionInfoEntity: "
+ subInfoEntity); + subInfoEntity);
} }
mMobileNetworkDatabase.insertSubsInfo(subInfoEntity); mMobileNetworkDatabase.insertSubsInfo(subInfoEntity);
addRegisterBySubId(mSubId);
insertUiccInfo(subId);
insertMobileNetworkInfo(context, subId);
mMetricsFeatureProvider.action(mContext, mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_SUB_INFO, mSubId); SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_SUB_INFO, subId);
} else if (DEBUG) { insertUiccInfo(subId, telephonyManager);
Log.d(TAG, "Can not insert subInfo, the entity is null"); insertMobileNetworkInfo(context, subId, telephonyManager);
} }
} else if (DEBUG) {
Log.d(TAG, "Can not insert subInfo, the entity is null");
} }
} }
public void deleteAllInfoBySubId(String subId) { private void deleteAllInfoBySubId(String subId) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "deleteAllInfoBySubId, subId = " + subId); Log.d(TAG, "deleteAllInfoBySubId, subId = " + subId);
} }
@@ -412,20 +478,23 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
removerRegisterBySubId(id); removerRegisterBySubId(id);
mSubscriptionInfoMap.remove(id); mSubscriptionInfoMap.remove(id);
mTelephonyManagerMap.remove(id); mTelephonyManagerMap.remove(id);
sCacheSubscriptionInfoEntityMap.remove(subId); sCacheSubscriptionInfoEntityMap.remove(id);
sCacheUiccInfoEntityMap.remove(subId); sCacheUiccInfoEntityMap.remove(id);
sCacheMobileNetworkInfoEntityMap.remove(subId); sCacheMobileNetworkInfoEntityMap.remove(id);
mMetricsFeatureProvider.action(mContext, mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_DELETE_DATA, id); SettingsEnums.ACTION_MOBILE_NETWORK_DB_DELETE_DATA, id);
} }
public SubscriptionInfoEntity convertToSubscriptionInfoEntity(Context context, private SubscriptionInfoEntity convertToSubscriptionInfoEntity(Context context,
SubscriptionInfo subInfo) { SubscriptionInfo subInfo, TelephonyManager telephonyManager) {
mSubId = subInfo.getSubscriptionId(); int subId = subInfo.getSubscriptionId();
mTelephonyManager = context.getSystemService( if (telephonyManager == null) {
TelephonyManager.class).createForSubscriptionId(mSubId); if (DEBUG) {
Log.d(TAG, "Can not get TelephonyManager for subId " + subId);
UiccSlotInfo[] uiccSlotInfos = mTelephonyManager.getUiccSlotsInfo(); }
return null;
}
UiccSlotInfo[] uiccSlotInfos = telephonyManager.getUiccSlotsInfo();
if (uiccSlotInfos == null || uiccSlotInfos.length == 0) { if (uiccSlotInfos == null || uiccSlotInfos.length == 0) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "uiccSlotInfos = null or empty"); Log.d(TAG, "uiccSlotInfos = null or empty");
@@ -435,10 +504,10 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
getUiccInfoBySubscriptionInfo(uiccSlotInfos, subInfo); getUiccInfoBySubscriptionInfo(uiccSlotInfos, subInfo);
SubscriptionInfo firstRemovableSubInfo = SubscriptionUtil.getFirstRemovableSubscription( SubscriptionInfo firstRemovableSubInfo = SubscriptionUtil.getFirstRemovableSubscription(
context); context);
if(DEBUG){ if (DEBUG) {
Log.d(TAG, "convert subscriptionInfo to entity for subId = " + mSubId); Log.d(TAG, "convert subscriptionInfo to entity for subId = " + subId);
} }
return new SubscriptionInfoEntity(String.valueOf(mSubId), return new SubscriptionInfoEntity(String.valueOf(subId),
subInfo.getSimSlotIndex(), subInfo.getSimSlotIndex(),
subInfo.getCarrierId(), subInfo.getDisplayName().toString(), subInfo.getCarrierId(), subInfo.getDisplayName().toString(),
subInfo.getCarrierName() != null ? subInfo.getCarrierName().toString() : "", subInfo.getCarrierName() != null ? subInfo.getCarrierName().toString() : "",
@@ -451,23 +520,23 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
SubscriptionUtil.isSubscriptionVisible(mSubscriptionManager, context, subInfo), SubscriptionUtil.isSubscriptionVisible(mSubscriptionManager, context, subInfo),
SubscriptionUtil.getFormattedPhoneNumber(context, subInfo), SubscriptionUtil.getFormattedPhoneNumber(context, subInfo),
firstRemovableSubInfo == null ? false firstRemovableSubInfo == null ? false
: firstRemovableSubInfo.getSubscriptionId() == mSubId, : firstRemovableSubInfo.getSubscriptionId() == subId,
String.valueOf(SubscriptionUtil.getDefaultSimConfig(context, mSubId)), String.valueOf(SubscriptionUtil.getDefaultSimConfig(context, subId)),
SubscriptionUtil.isDefaultSubscription(context, mSubId), SubscriptionUtil.isDefaultSubscription(context, subId),
mSubscriptionManager.isValidSubscriptionId(mSubId), mSubscriptionManager.isValidSubscriptionId(subId),
mSubscriptionManager.isUsableSubscriptionId(mSubId), mSubscriptionManager.isUsableSubscriptionId(subId),
mSubscriptionManager.isActiveSubscriptionId(mSubId), mSubscriptionManager.isActiveSubscriptionId(subId),
true /*availableSubInfo*/, true /*availableSubInfo*/,
mSubscriptionManager.getDefaultVoiceSubscriptionId() == mSubId, mSubscriptionManager.getDefaultVoiceSubscriptionId() == subId,
mSubscriptionManager.getDefaultSmsSubscriptionId() == mSubId, mSubscriptionManager.getDefaultSmsSubscriptionId() == subId,
mSubscriptionManager.getDefaultDataSubscriptionId() == mSubId, mSubscriptionManager.getDefaultDataSubscriptionId() == subId,
mSubscriptionManager.getDefaultSubscriptionId() == mSubId, mSubscriptionManager.getDefaultSubscriptionId() == subId,
mSubscriptionManager.getActiveDataSubscriptionId() == mSubId); mSubscriptionManager.getActiveDataSubscriptionId() == subId);
} }
} }
public void insertUiccInfo(String subId) { private void insertUiccInfo(int subId, TelephonyManager telephonyManager) {
UiccInfoEntity uiccInfoEntity = convertToUiccInfoEntity(); UiccInfoEntity uiccInfoEntity = convertToUiccInfoEntity(subId, telephonyManager);
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "uiccInfoEntity = " + uiccInfoEntity); Log.d(TAG, "uiccInfoEntity = " + uiccInfoEntity);
} }
@@ -476,51 +545,76 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
sCacheUiccInfoEntityMap.put(subId, uiccInfoEntity); sCacheUiccInfoEntityMap.put(subId, uiccInfoEntity);
mMobileNetworkDatabase.insertUiccInfo(uiccInfoEntity); mMobileNetworkDatabase.insertUiccInfo(uiccInfoEntity);
mMetricsFeatureProvider.action(mContext, mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_UICC_INFO, SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_UICC_INFO, subId);
Integer.parseInt(subId));
} }
} }
public void insertMobileNetworkInfo(Context context, String subId) { private void insertMobileNetworkInfo(Context context, int subId,
MobileNetworkInfoEntity mobileNetworkInfoEntity = convertToMobileNetworkInfoEntity(context); TelephonyManager telephonyManager) {
MobileNetworkInfoEntity mobileNetworkInfoEntity = convertToMobileNetworkInfoEntity(context,
subId, telephonyManager);
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "mobileNetworkInfoEntity = " + mobileNetworkInfoEntity); Log.d(TAG, "insertMobileNetworkInfo, mobileNetworkInfoEntity = "
+ mobileNetworkInfoEntity);
} }
if (mobileNetworkInfoEntity == null) {
return;
}
if (!sCacheMobileNetworkInfoEntityMap.containsKey(subId) if (!sCacheMobileNetworkInfoEntityMap.containsKey(subId)
|| !sCacheMobileNetworkInfoEntityMap.get(subId).equals(mobileNetworkInfoEntity)) { || !sCacheMobileNetworkInfoEntityMap.get(subId).equals(mobileNetworkInfoEntity)) {
sCacheMobileNetworkInfoEntityMap.put(subId, mobileNetworkInfoEntity); sCacheMobileNetworkInfoEntityMap.put(subId, mobileNetworkInfoEntity);
mMobileNetworkDatabase.insertMobileNetworkInfo(mobileNetworkInfoEntity); mMobileNetworkDatabase.insertMobileNetworkInfo(mobileNetworkInfoEntity);
mMetricsFeatureProvider.action(mContext, mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_MOBILE_NETWORK_INFO, SettingsEnums.ACTION_MOBILE_NETWORK_DB_INSERT_MOBILE_NETWORK_INFO, subId);
Integer.parseInt(subId));
} }
} }
public MobileNetworkInfoEntity convertToMobileNetworkInfoEntity(Context context) { private MobileNetworkInfoEntity convertToMobileNetworkInfoEntity(Context context, int subId,
return new MobileNetworkInfoEntity(String.valueOf(mSubId), TelephonyManager telephonyManager) {
MobileNetworkUtils.isContactDiscoveryEnabled(context, mSubId), boolean isDataEnabled = false;
MobileNetworkUtils.isContactDiscoveryVisible(context, mSubId), boolean isDataRoamingEnabled = false;
mTelephonyManager.isDataEnabled(), if (telephonyManager != null) {
MobileNetworkUtils.isCdmaOptions(context, mSubId), isDataEnabled = telephonyManager.isDataEnabled();
MobileNetworkUtils.isGsmOptions(context, mSubId), isDataRoamingEnabled = telephonyManager.isDataRoamingEnabled();
MobileNetworkUtils.isWorldMode(context, mSubId), } else if (DEBUG) {
MobileNetworkUtils.shouldDisplayNetworkSelectOptions(context, mSubId), Log.d(TAG, "TelephonyManager is null, subId = " + subId);
MobileNetworkUtils.isTdscdmaSupported(context, mSubId), }
return new MobileNetworkInfoEntity(String.valueOf(subId),
MobileNetworkUtils.isContactDiscoveryEnabled(context, subId),
MobileNetworkUtils.isContactDiscoveryVisible(context, subId),
isDataEnabled,
MobileNetworkUtils.isCdmaOptions(context, subId),
MobileNetworkUtils.isGsmOptions(context, subId),
MobileNetworkUtils.isWorldMode(context, subId),
MobileNetworkUtils.shouldDisplayNetworkSelectOptions(context, subId),
MobileNetworkUtils.isTdscdmaSupported(context, subId),
MobileNetworkUtils.activeNetworkIsCellular(context), MobileNetworkUtils.activeNetworkIsCellular(context),
SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager), SubscriptionUtil.showToggleForPhysicalSim(mSubscriptionManager),
mTelephonyManager.isDataRoamingEnabled() isDataRoamingEnabled
); );
} }
private UiccInfoEntity convertToUiccInfoEntity() { private UiccInfoEntity convertToUiccInfoEntity(int subId, TelephonyManager telephonyManager) {
return new UiccInfoEntity(String.valueOf(mSubId), String.valueOf(mPhysicalSlotIndex), return new UiccInfoEntity(String.valueOf(subId), String.valueOf(mPhysicalSlotIndex),
mLogicalSlotIndex, mCardId, mIsEuicc, isMultipleEnabledProfilesSupported(), mLogicalSlotIndex, mCardId, mIsEuicc,
mCardState, mIsRemovable, mIsActive, mPortIndex isMultipleEnabledProfilesSupported(telephonyManager), mCardState, mIsRemovable,
mIsActive, mPortIndex
); );
} }
private boolean isMultipleEnabledProfilesSupported() { private boolean isMultipleEnabledProfilesSupported(TelephonyManager telephonyManager) {
List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo(); if (telephonyManager == null) {
if (DEBUG) {
Log.d(TAG, "TelephonyManager is null");
}
return false;
}
List<UiccCardInfo> cardInfos = telephonyManager.getUiccCardsInfo();
if (cardInfos == null) { if (cardInfos == null) {
if (DEBUG) { if (DEBUG) {
Log.d(TAG, "UICC card info list is empty."); Log.d(TAG, "UICC card info list is empty.");
@@ -574,7 +668,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
// the database, if the subInfo is not existed in the new list, delete it // the database, if the subInfo is not existed in the new list, delete it
// from the database. // from the database.
for (SubscriptionInfoEntity info : availableInfoArray) { for (SubscriptionInfoEntity info : availableInfoArray) {
if (sCacheSubscriptionInfoEntityMap.containsKey(info.subId)) { if (sCacheSubscriptionInfoEntityMap.containsKey(info.getSubId())) {
deleteAllInfoBySubId(info.subId); deleteAllInfoBySubId(info.subId);
} }
} }
@@ -593,7 +687,7 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
} }
continue; continue;
} }
mSubscriptionInfoMap.put(mSubId, subInfo); mSubscriptionInfoMap.put(subInfo.getSubscriptionId(), subInfo);
insertSubInfo(mContext, subInfo); insertSubInfo(mContext, subInfo);
} }
} }
@@ -610,7 +704,9 @@ public class MobileNetworkRepository extends SubscriptionManager.OnSubscriptions
@Override @Override
public void onCallStateChanged(int state) { public void onCallStateChanged(int state) {
mCallback.onCallStateChanged(state); for (MobileNetworkCallback callback : sCallbacks) {
callback.onCallStateChanged(state);
}
} }
} }