Support dynamically update IMSI
Currently, NetworkStatsSubscriptionsMonitor will skip the listener registration until the IMSI is available to deal with SIM PIN locked case. However, this solution can only handle the case that IMSI changes from/to null. And it also relies on the assumption that IMSI never changes for a subId. Thus, support dynamically update IMSI to handle IMSI changes more robustly. This patch also address leftover comments at ag/12400327. Test: enable SIM PIN and manually test Test: atest NetworkStatsSubscriptionsMonitorTest#testSubscriberIdUnavailable Test: atest NetworkStatsSubscriptionsMonitorTest#testSubscriberIdChanged Test: ./out/host/linux-x86/bin/statsd_testdrive 10082 Bug: 160941101 Change-Id: I625a5b10ee4806f6fee99c2d9d6c5e7977ff785e
This commit is contained in:
@@ -30,6 +30,7 @@ import android.telephony.SubscriptionManager;
|
|||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.util.Pair;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.util.CollectionUtils;
|
import com.android.internal.util.CollectionUtils;
|
||||||
@@ -94,41 +95,43 @@ public class NetworkStatsSubscriptionsMonitor extends
|
|||||||
// also needed to track CBRS.
|
// also needed to track CBRS.
|
||||||
final List<Integer> newSubs = getActiveSubIdList(mSubscriptionManager);
|
final List<Integer> newSubs = getActiveSubIdList(mSubscriptionManager);
|
||||||
|
|
||||||
for (final int subId : newSubs) {
|
// IMSI is needed for every newly added sub. Listener stores subscriberId into it to
|
||||||
final RatTypeListener match = CollectionUtils.find(mRatListeners,
|
// prevent binder call to telephony when querying RAT. Keep listener registration with empty
|
||||||
it -> it.mSubId == subId);
|
// IMSI is meaningless since the RAT type changed is ambiguous for multi-SIM if reported
|
||||||
if (match != null) continue;
|
// with empty IMSI. So filter the subs w/o a valid IMSI to prevent such registration.
|
||||||
|
final List<Pair<Integer, String>> filteredNewSubs =
|
||||||
// Create listener for every newly added sub. Also store subscriberId into it to
|
CollectionUtils.mapNotNull(newSubs, subId -> {
|
||||||
// prevent binder call to telephony when querying RAT. If the subscriberId is empty
|
|
||||||
// for any reason, such as SIM PIN locked, skip registration.
|
|
||||||
// SubscriberId will be unavailable again if 1. modem crashed 2. reboot
|
|
||||||
// 3. re-insert SIM. If that happens, the listeners will be eventually synchronized
|
|
||||||
// with active sub list once all subscriberIds are ready.
|
|
||||||
final String subscriberId = mTeleManager.getSubscriberId(subId);
|
final String subscriberId = mTeleManager.getSubscriberId(subId);
|
||||||
if (TextUtils.isEmpty(subscriberId)) {
|
return TextUtils.isEmpty(subscriberId) ? null : new Pair(subId, subscriberId);
|
||||||
Log.d(NetworkStatsService.TAG, "Empty subscriberId for newly added sub "
|
});
|
||||||
+ subId + ", skip listener registration");
|
|
||||||
|
for (final Pair<Integer, String> sub : filteredNewSubs) {
|
||||||
|
// Fully match listener with subId and IMSI, since in some rare cases, IMSI might be
|
||||||
|
// suddenly change regardless of subId, such as switch IMSI feature in modem side.
|
||||||
|
// If that happens, register new listener with new IMSI and remove old one later.
|
||||||
|
if (CollectionUtils.find(mRatListeners,
|
||||||
|
it -> it.equalsKey(sub.first, sub.second)) != null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final RatTypeListener listener =
|
final RatTypeListener listener =
|
||||||
new RatTypeListener(mExecutor, this, subId, subscriberId);
|
new RatTypeListener(mExecutor, this, sub.first, sub.second);
|
||||||
mRatListeners.add(listener);
|
mRatListeners.add(listener);
|
||||||
|
|
||||||
// Register listener to the telephony manager that associated with specific sub.
|
// Register listener to the telephony manager that associated with specific sub.
|
||||||
mTeleManager.createForSubscriptionId(subId)
|
mTeleManager.createForSubscriptionId(sub.first)
|
||||||
.listen(listener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
.listen(listener, PhoneStateListener.LISTEN_SERVICE_STATE);
|
||||||
Log.d(NetworkStatsService.TAG, "RAT type listener registered for sub " + subId);
|
Log.d(NetworkStatsService.TAG, "RAT type listener registered for sub " + sub.first);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) {
|
for (final RatTypeListener listener : new ArrayList<>(mRatListeners)) {
|
||||||
// If the new list contains the subId of the listener, keeps it.
|
// If there is no subId and IMSI matched the listener, removes it.
|
||||||
final Integer match = CollectionUtils.find(newSubs, it -> it == listener.mSubId);
|
if (CollectionUtils.find(filteredNewSubs,
|
||||||
if (match != null) continue;
|
it -> listener.equalsKey(it.first, it.second)) == null) {
|
||||||
|
|
||||||
handleRemoveRatTypeListener(listener);
|
handleRemoveRatTypeListener(listener);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private List<Integer> getActiveSubIdList(@NonNull SubscriptionManager subscriptionManager) {
|
private List<Integer> getActiveSubIdList(@NonNull SubscriptionManager subscriptionManager) {
|
||||||
@@ -232,5 +235,9 @@ public class NetworkStatsSubscriptionsMonitor extends
|
|||||||
public int getSubId() {
|
public int getSubId() {
|
||||||
return mSubId;
|
return mSubId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean equalsKey(int subId, @NonNull String subscriberId) {
|
||||||
|
return mSubId == subId && TextUtils.equals(mSubscriberId, subscriberId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user