Merge "[Settings] Hide subscriptions not existed within device"
This commit is contained in:
@@ -486,7 +486,7 @@ public class SubscriptionUtil {
|
|||||||
* @param info the subscriptionInfo to check against.
|
* @param info the subscriptionInfo to check against.
|
||||||
* @return true if this subscription should be visible to the API caller.
|
* @return true if this subscription should be visible to the API caller.
|
||||||
*/
|
*/
|
||||||
private static boolean isSubscriptionVisible(
|
public static boolean isSubscriptionVisible(
|
||||||
SubscriptionManager subscriptionManager, Context context, SubscriptionInfo info) {
|
SubscriptionManager subscriptionManager, Context context, SubscriptionInfo info) {
|
||||||
if (info == null) return false;
|
if (info == null) return false;
|
||||||
// If subscription is NOT grouped opportunistic subscription, it's visible.
|
// If subscription is NOT grouped opportunistic subscription, it's visible.
|
||||||
|
58
src/com/android/settings/network/helper/QueryEsimCardId.java
Normal file
58
src/com/android/settings/network/helper/QueryEsimCardId.java
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.helper;
|
||||||
|
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.telephony.UiccCardInfo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a Callable class which queries valid card ID for eSIM
|
||||||
|
*/
|
||||||
|
public class QueryEsimCardId implements Callable<AtomicIntegerArray> {
|
||||||
|
private static final String TAG = "QueryEsimCardId";
|
||||||
|
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of class
|
||||||
|
* @param TelephonyManager
|
||||||
|
*/
|
||||||
|
public QueryEsimCardId(TelephonyManager telephonyManager) {
|
||||||
|
mTelephonyManager = telephonyManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of Callable
|
||||||
|
* @return card ID(s) in AtomicIntegerArray
|
||||||
|
*/
|
||||||
|
public AtomicIntegerArray call() {
|
||||||
|
List<UiccCardInfo> cardInfos = mTelephonyManager.getUiccCardsInfo();
|
||||||
|
if (cardInfos == null) {
|
||||||
|
return new AtomicIntegerArray(0);
|
||||||
|
}
|
||||||
|
return new AtomicIntegerArray(cardInfos.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(cardInfo -> (!cardInfo.isRemovable()
|
||||||
|
&& (cardInfo.getCardId() != TelephonyManager.UNSUPPORTED_CARD_ID)))
|
||||||
|
.mapToInt(UiccCardInfo::getCardId)
|
||||||
|
.toArray());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.helper;
|
||||||
|
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.telephony.UiccSlotInfo;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a Callable class which query slot index within device
|
||||||
|
*/
|
||||||
|
public class QuerySimSlotIndex implements Callable<AtomicIntegerArray> {
|
||||||
|
private static final String TAG = "QuerySimSlotIndex";
|
||||||
|
|
||||||
|
private TelephonyManager mTelephonyManager;
|
||||||
|
private boolean mDisabledSlotsIncluded;
|
||||||
|
private boolean mOnlySlotWithSim;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of class
|
||||||
|
* @param TelephonyManager
|
||||||
|
* @param disabledSlotsIncluded query both active and inactive slots when true,
|
||||||
|
* only query active slot when false.
|
||||||
|
* @param onlySlotWithSim query slot index with SIM available when true,
|
||||||
|
* include absent ones when false.
|
||||||
|
*/
|
||||||
|
public QuerySimSlotIndex(TelephonyManager telephonyManager,
|
||||||
|
boolean disabledSlotsIncluded, boolean onlySlotWithSim) {
|
||||||
|
mTelephonyManager = telephonyManager;
|
||||||
|
mDisabledSlotsIncluded = disabledSlotsIncluded;
|
||||||
|
mOnlySlotWithSim = onlySlotWithSim;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of Callable
|
||||||
|
* @return slot index in AtomicIntegerArray
|
||||||
|
*/
|
||||||
|
public AtomicIntegerArray call() {
|
||||||
|
UiccSlotInfo [] slotInfo = mTelephonyManager.getUiccSlotsInfo();
|
||||||
|
if (slotInfo == null) {
|
||||||
|
return new AtomicIntegerArray(0);
|
||||||
|
}
|
||||||
|
int slotIndexFilter = mOnlySlotWithSim ? 0 : SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||||
|
return new AtomicIntegerArray(Arrays.stream(slotInfo)
|
||||||
|
.filter(slot -> filterSlot(slot))
|
||||||
|
.mapToInt(slot -> mapToSlotIndex(slot))
|
||||||
|
.filter(slotIndex -> (slotIndex >= slotIndexFilter))
|
||||||
|
.toArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean filterSlot(UiccSlotInfo slotInfo) {
|
||||||
|
if (mDisabledSlotsIncluded) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (slotInfo == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return slotInfo.getIsActive();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int mapToSlotIndex(UiccSlotInfo slotInfo) {
|
||||||
|
if (slotInfo == null) {
|
||||||
|
return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||||
|
}
|
||||||
|
if (slotInfo.getCardStateInfo() == UiccSlotInfo.CARD_STATE_INFO_ABSENT) {
|
||||||
|
return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
|
||||||
|
}
|
||||||
|
return slotInfo.getLogicalSlotIdx();
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.helper;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.ParcelUuid;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.Keep;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import com.android.settings.network.helper.SubscriptionAnnotation;
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a Callable class to query user selectable subscription list.
|
||||||
|
*/
|
||||||
|
public class SelectableSubscriptions implements Callable<List<SubscriptionAnnotation>> {
|
||||||
|
private static final String TAG = "SelectableSubscriptions";
|
||||||
|
|
||||||
|
private static final ParcelUuid mEmptyUuid = ParcelUuid.fromString("0-0-0-0-0");
|
||||||
|
|
||||||
|
private Context mContext;
|
||||||
|
private Supplier<List<SubscriptionInfo>> mSubscriptions;
|
||||||
|
private Predicate<SubscriptionAnnotation> mFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of class
|
||||||
|
* @param context
|
||||||
|
* @param disabledSlotsIncluded query both active and inactive slots when true,
|
||||||
|
* only query active slot when false.
|
||||||
|
*/
|
||||||
|
public SelectableSubscriptions(Context context, boolean disabledSlotsIncluded) {
|
||||||
|
mContext = context;
|
||||||
|
mSubscriptions = disabledSlotsIncluded ? (() -> getAvailableSubInfoList(context)) :
|
||||||
|
(() -> getActiveSubInfoList(context));
|
||||||
|
mFilter = disabledSlotsIncluded ? (subAnno -> subAnno.isExisted()) :
|
||||||
|
(subAnno -> subAnno.isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of Callable
|
||||||
|
* @return a list of SubscriptionAnnotation which is user selectable
|
||||||
|
*/
|
||||||
|
public List<SubscriptionAnnotation> call() {
|
||||||
|
TelephonyManager telMgr = mContext.getSystemService(TelephonyManager.class);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// query in background thread
|
||||||
|
Future<AtomicIntegerArray> eSimCardId =
|
||||||
|
ThreadUtils.postOnBackgroundThread(new QueryEsimCardId(telMgr));
|
||||||
|
|
||||||
|
// query in background thread
|
||||||
|
Future<AtomicIntegerArray> simSlotIndex =
|
||||||
|
ThreadUtils.postOnBackgroundThread(
|
||||||
|
new QuerySimSlotIndex(telMgr, true, true));
|
||||||
|
|
||||||
|
// query in background thread
|
||||||
|
Future<AtomicIntegerArray> activeSimSlotIndex =
|
||||||
|
ThreadUtils.postOnBackgroundThread(
|
||||||
|
new QuerySimSlotIndex(telMgr, false, true));
|
||||||
|
|
||||||
|
List<SubscriptionInfo> subInfoList = mSubscriptions.get();
|
||||||
|
|
||||||
|
// wait for result from background thread
|
||||||
|
List<Integer> eSimCardIdList = atomicToList(eSimCardId.get());
|
||||||
|
List<Integer> simSlotIndexList = atomicToList(simSlotIndex.get());
|
||||||
|
List<Integer> activeSimSlotIndexList = atomicToList(activeSimSlotIndex.get());
|
||||||
|
|
||||||
|
// group by GUID
|
||||||
|
Map<ParcelUuid, List<SubscriptionAnnotation>> groupedSubInfoList =
|
||||||
|
IntStream.range(0, subInfoList.size())
|
||||||
|
.mapToObj(subInfoIndex ->
|
||||||
|
new SubscriptionAnnotation.Builder(subInfoList, subInfoIndex))
|
||||||
|
.map(annoBdr -> annoBdr.build(mContext,
|
||||||
|
eSimCardIdList, simSlotIndexList, activeSimSlotIndexList))
|
||||||
|
.filter(mFilter)
|
||||||
|
.collect(Collectors.groupingBy(subAnno -> getGroupUuid(subAnno)));
|
||||||
|
|
||||||
|
// select best one from subscription(s) within the same group
|
||||||
|
groupedSubInfoList.replaceAll((uuid, annoList) -> {
|
||||||
|
if ((uuid == mEmptyUuid) || (annoList.size() <= 1)) {
|
||||||
|
return annoList;
|
||||||
|
}
|
||||||
|
return Collections.singletonList(selectBestFromList(annoList));
|
||||||
|
});
|
||||||
|
|
||||||
|
// build a list of subscriptions (based on the order of slot index)
|
||||||
|
return groupedSubInfoList.values().stream().flatMap(List::stream)
|
||||||
|
.sorted(Comparator.comparingInt(anno -> anno.getSubInfo().getSimSlotIndex()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
} catch (Exception exception) {
|
||||||
|
Log.w(TAG, "Fail to request subIdList", exception);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ParcelUuid getGroupUuid(SubscriptionAnnotation subAnno) {
|
||||||
|
ParcelUuid groupUuid = subAnno.getSubInfo().getGroupUuid();
|
||||||
|
return (groupUuid == null) ? mEmptyUuid : groupUuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SubscriptionAnnotation selectBestFromList(List<SubscriptionAnnotation> annoList) {
|
||||||
|
Comparator<SubscriptionAnnotation> annoSelector = (anno1, anno2) -> {
|
||||||
|
if (anno1.isDisplayAllowed() != anno2.isDisplayAllowed()) {
|
||||||
|
return anno1.isDisplayAllowed() ? -1 : 1;
|
||||||
|
}
|
||||||
|
if (anno1.isActive() != anno2.isActive()) {
|
||||||
|
return anno1.isActive() ? -1 : 1;
|
||||||
|
}
|
||||||
|
if (anno1.isExisted() != anno2.isExisted()) {
|
||||||
|
return anno1.isExisted() ? -1 : 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
annoSelector = annoSelector
|
||||||
|
// eSIM in front of pSIM
|
||||||
|
.thenComparingInt(anno -> -anno.getType())
|
||||||
|
// subscription ID in reverse order
|
||||||
|
.thenComparingInt(anno -> -anno.getSubscriptionId());
|
||||||
|
return annoList.stream().sorted(annoSelector).findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<SubscriptionInfo> getSubInfoList(Context context,
|
||||||
|
Function<SubscriptionManager, List<SubscriptionInfo>> convertor) {
|
||||||
|
SubscriptionManager subManager = getSubscriptionManager(context);
|
||||||
|
return (subManager == null) ? Collections.emptyList() : convertor.apply(subManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected SubscriptionManager getSubscriptionManager(Context context) {
|
||||||
|
return context.getSystemService(SubscriptionManager.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<SubscriptionInfo> getAvailableSubInfoList(Context context) {
|
||||||
|
return getSubInfoList(context, SubscriptionManager::getAvailableSubscriptionInfoList);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<SubscriptionInfo> getActiveSubInfoList(Context context) {
|
||||||
|
return getSubInfoList(context, SubscriptionManager::getActiveSubscriptionInfoList);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
@VisibleForTesting
|
||||||
|
protected static List<Integer> atomicToList(AtomicIntegerArray atomicIntArray) {
|
||||||
|
if (atomicIntArray == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
return IntStream.range(0, atomicIntArray.length())
|
||||||
|
.map(idx -> atomicIntArray.get(idx)).boxed()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.helper;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.telephony.SubscriptionInfo;
|
||||||
|
import android.telephony.SubscriptionManager;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
|
import com.android.settings.network.SubscriptionUtil;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a class helps providing additional info required by UI
|
||||||
|
* based on SubscriptionInfo.
|
||||||
|
*/
|
||||||
|
public class SubscriptionAnnotation {
|
||||||
|
private static final String TAG = "SubscriptionAnnotation";
|
||||||
|
|
||||||
|
private SubscriptionInfo mSubInfo;
|
||||||
|
private int mOrderWithinList;
|
||||||
|
private int mType = TYPE_UNKNOWN;
|
||||||
|
private boolean mIsExisted;
|
||||||
|
private boolean mIsActive;
|
||||||
|
private boolean mIsAllowToDisplay;
|
||||||
|
|
||||||
|
public static final int TYPE_UNKNOWN = 0x0;
|
||||||
|
public static final int TYPE_PSIM = 0x1;
|
||||||
|
public static final int TYPE_ESIM = 0x2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builder class for SubscriptionAnnotation
|
||||||
|
*/
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
private List<SubscriptionInfo> mSubInfoList;
|
||||||
|
private int mIndexWithinList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of builder
|
||||||
|
* @param subInfoList list of subscription info
|
||||||
|
* @param indexWithinList target index within list provided
|
||||||
|
*/
|
||||||
|
public Builder(List<SubscriptionInfo> subInfoList, int indexWithinList) {
|
||||||
|
mSubInfoList = subInfoList;
|
||||||
|
mIndexWithinList = indexWithinList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SubscriptionAnnotation build(Context context, List<Integer> eSimCardId,
|
||||||
|
List<Integer> simSlotIndex, List<Integer> activeSimSlotIndex) {
|
||||||
|
return new SubscriptionAnnotation(mSubInfoList, mIndexWithinList, context,
|
||||||
|
eSimCardId, simSlotIndex, activeSimSlotIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor of class
|
||||||
|
*/
|
||||||
|
protected SubscriptionAnnotation(List<SubscriptionInfo> subInfoList, int subInfoIndex,
|
||||||
|
Context context, List<Integer> eSimCardId,
|
||||||
|
List<Integer> simSlotIndex, List<Integer> activeSimSlotIndexList) {
|
||||||
|
if ((subInfoIndex < 0) || (subInfoIndex >= subInfoList.size())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mSubInfo = subInfoList.get(subInfoIndex);
|
||||||
|
if (mSubInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mOrderWithinList = subInfoIndex;
|
||||||
|
mType = mSubInfo.isEmbedded() ? TYPE_ESIM : TYPE_PSIM;
|
||||||
|
if (mType == TYPE_ESIM) {
|
||||||
|
int cardId = mSubInfo.getCardId();
|
||||||
|
mIsExisted = eSimCardId.contains(cardId);
|
||||||
|
if (mIsExisted) {
|
||||||
|
mIsActive = activeSimSlotIndexList.contains(mSubInfo.getSimSlotIndex());
|
||||||
|
mIsAllowToDisplay = isDisplayAllowed(context);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mIsExisted = simSlotIndex.contains(mSubInfo.getSimSlotIndex());
|
||||||
|
mIsActive = activeSimSlotIndexList.contains(mSubInfo.getSimSlotIndex());
|
||||||
|
if (mIsExisted) {
|
||||||
|
mIsAllowToDisplay = isDisplayAllowed(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// the index provided during construction of Builder
|
||||||
|
public int getOrderingInList() {
|
||||||
|
return mOrderWithinList;
|
||||||
|
}
|
||||||
|
|
||||||
|
// type of subscription
|
||||||
|
public int getType() {
|
||||||
|
return mType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if a subscription is existed within device
|
||||||
|
public boolean isExisted() {
|
||||||
|
return mIsExisted;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if a subscription is currently ON
|
||||||
|
public boolean isActive() {
|
||||||
|
return mIsActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if display of subscription is allowed
|
||||||
|
public boolean isDisplayAllowed() {
|
||||||
|
return mIsAllowToDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the subscription ID
|
||||||
|
public int getSubscriptionId() {
|
||||||
|
return (mSubInfo == null) ? SubscriptionManager.INVALID_SUBSCRIPTION_ID :
|
||||||
|
mSubInfo.getSubscriptionId();
|
||||||
|
}
|
||||||
|
|
||||||
|
// the SubscriptionInfo
|
||||||
|
public SubscriptionInfo getSubInfo() {
|
||||||
|
return mSubInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDisplayAllowed(Context context) {
|
||||||
|
return SubscriptionUtil.isSubscriptionVisible(
|
||||||
|
context.getSystemService(SubscriptionManager.class), context, mSubInfo);
|
||||||
|
}
|
||||||
|
}
|
@@ -19,6 +19,7 @@ package com.android.settings.network.telephony;
|
|||||||
import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
|
import static com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY;
|
||||||
|
|
||||||
import android.app.ActionBar;
|
import android.app.ActionBar;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.UserManager;
|
import android.os.UserManager;
|
||||||
@@ -43,6 +44,8 @@ import com.android.settings.R;
|
|||||||
import com.android.settings.core.SettingsBaseActivity;
|
import com.android.settings.core.SettingsBaseActivity;
|
||||||
import com.android.settings.network.ProxySubscriptionManager;
|
import com.android.settings.network.ProxySubscriptionManager;
|
||||||
import com.android.settings.network.SubscriptionUtil;
|
import com.android.settings.network.SubscriptionUtil;
|
||||||
|
import com.android.settings.network.helper.SelectableSubscriptions;
|
||||||
|
import com.android.settings.network.helper.SubscriptionAnnotation;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -244,15 +247,21 @@ public class MobileNetworkActivity extends SettingsBaseActivity
|
|||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
SubscriptionInfo getSubscription() {
|
SubscriptionInfo getSubscription() {
|
||||||
|
List<SubscriptionAnnotation> subList =
|
||||||
|
(new SelectableSubscriptions(this, true)).call();
|
||||||
|
SubscriptionAnnotation currentSubInfo = null;
|
||||||
if (mCurSubscriptionId != SUB_ID_NULL) {
|
if (mCurSubscriptionId != SUB_ID_NULL) {
|
||||||
return getSubscriptionForSubId(mCurSubscriptionId);
|
currentSubInfo = subList.stream()
|
||||||
|
.filter(SubscriptionAnnotation::isDisplayAllowed)
|
||||||
|
.filter(subAnno -> (subAnno.getSubscriptionId() == mCurSubscriptionId))
|
||||||
|
.findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
final List<SubscriptionInfo> subInfos = getProxySubscriptionManager()
|
if (currentSubInfo == null) {
|
||||||
.getActiveSubscriptionsInfo();
|
currentSubInfo = subList.stream()
|
||||||
if (CollectionUtils.isEmpty(subInfos)) {
|
.filter(SubscriptionAnnotation::isDisplayAllowed)
|
||||||
return null;
|
.findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
return subInfos.get(0);
|
return (currentSubInfo == null) ? null : currentSubInfo.getSubInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
|
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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.network.helper;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.atomic.AtomicIntegerArray;
|
||||||
|
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class SelectableSubscriptionsTest {
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void atomicToList_nullInput_getNoneNullEmptyList() {
|
||||||
|
List<Integer> result = SelectableSubscriptions.atomicToList(null);
|
||||||
|
|
||||||
|
assertThat(result.size()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void atomicToList_zeroLengthInput_getEmptyList() {
|
||||||
|
List<Integer> result = SelectableSubscriptions.atomicToList(new AtomicIntegerArray(0));
|
||||||
|
|
||||||
|
assertThat(result.size()).isEqualTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void atomicToList_subIdInArray_getList() {
|
||||||
|
AtomicIntegerArray array = new AtomicIntegerArray(3);
|
||||||
|
array.set(0, 3);
|
||||||
|
array.set(1, 7);
|
||||||
|
array.set(2, 4);
|
||||||
|
|
||||||
|
List<Integer> result = SelectableSubscriptions.atomicToList(array);
|
||||||
|
|
||||||
|
assertThat(result.size()).isEqualTo(3);
|
||||||
|
assertThat(result.get(0)).isEqualTo(3);
|
||||||
|
assertThat(result.get(1)).isEqualTo(7);
|
||||||
|
assertThat(result.get(2)).isEqualTo(4);
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user