Loading src/com/android/settings/network/SubscriptionUtil.java +1 −1 Original line number Diff line number Diff line Loading @@ -486,7 +486,7 @@ public class SubscriptionUtil { * @param info the subscriptionInfo to check against. * @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) { if (info == null) return false; // If subscription is NOT grouped opportunistic subscription, it's visible. Loading src/com/android/settings/network/helper/QueryEsimCardId.java 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * 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()); } } No newline at end of file src/com/android/settings/network/helper/QuerySimSlotIndex.java 0 → 100644 +87 −0 Original line number Diff line number Diff line /* * 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(); } } No newline at end of file src/com/android/settings/network/helper/SelectableSubscriptions.java 0 → 100644 +160 −0 Original line number Diff line number Diff line /* * 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 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.List; 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.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.IntStream; /** * This is a Callable class to query user selectable subscription list. * * Here's example of creating a Callable for retrieving a list of SubscriptionAnnotation * for active Subscriptions: * * List<SubscriptionAnnotation> result = (new SelectableSubscriptions(context, false)).call(); * * Another example for retrieving a list of SubscriptionAnnotation for all subscriptions * accessible in another thread. * * List<SubscriptionAnnotation> result = ExecutorService.submit( * new SelectableSubscriptions(context, true)).get() */ public class SelectableSubscriptions implements Callable<List<SubscriptionAnnotation>> { private static final String TAG = "SelectableSubscriptions"; private Context mContext; private Supplier<List<SubscriptionInfo>> mSubscriptions; private Predicate<SubscriptionAnnotation> mFilter; private Function<List<SubscriptionAnnotation>, List<SubscriptionAnnotation>> mFinisher; /** * 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()); mFinisher = annoList -> annoList; } /** * Add UnaryOperator to be applied to the final result. * @param finisher a function to be applied to the final result. */ public SelectableSubscriptions addFinisher( UnaryOperator<List<SubscriptionAnnotation>> finisher) { mFinisher = mFinisher.andThen(finisher); return this; } /** * 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()); // build a list of SubscriptionAnnotation return IntStream.range(0, subInfoList.size()) .mapToObj(subInfoIndex -> new SubscriptionAnnotation.Builder(subInfoList, subInfoIndex)) .map(annoBdr -> annoBdr.build(mContext, eSimCardIdList, simSlotIndexList, activeSimSlotIndexList)) .filter(mFilter) .collect(Collectors.collectingAndThen(Collectors.toList(), mFinisher)); } catch (Exception exception) { Log.w(TAG, "Fail to request subIdList", exception); } return Collections.emptyList(); } 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()); } } No newline at end of file src/com/android/settings/network/helper/SubscriptionAnnotation.java 0 → 100644 +163 −0 Original line number Diff line number Diff line /* * 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 androidx.annotation.Keep; import androidx.annotation.VisibleForTesting; 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 ParcelUuid EMPTY_UUID = ParcelUuid.fromString("0-0-0-0-0"); 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 */ @Keep @VisibleForTesting 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 @Keep public int getOrderingInList() { return mOrderWithinList; } // type of subscription @Keep public int getType() { return mType; } // if a subscription is existed within device @Keep public boolean isExisted() { return mIsExisted; } // if a subscription is currently ON @Keep public boolean isActive() { return mIsActive; } // if display of subscription is allowed @Keep public boolean isDisplayAllowed() { return mIsAllowToDisplay; } // the subscription ID @Keep public int getSubscriptionId() { return (mSubInfo == null) ? SubscriptionManager.INVALID_SUBSCRIPTION_ID : mSubInfo.getSubscriptionId(); } // the grouping UUID @Keep public ParcelUuid getGroupUuid() { return (mSubInfo == null) ? null : mSubInfo.getGroupUuid(); } // the SubscriptionInfo @Keep public SubscriptionInfo getSubInfo() { return mSubInfo; } private boolean isDisplayAllowed(Context context) { return SubscriptionUtil.isSubscriptionVisible( context.getSystemService(SubscriptionManager.class), context, mSubInfo); } } No newline at end of file Loading
src/com/android/settings/network/SubscriptionUtil.java +1 −1 Original line number Diff line number Diff line Loading @@ -486,7 +486,7 @@ public class SubscriptionUtil { * @param info the subscriptionInfo to check against. * @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) { if (info == null) return false; // If subscription is NOT grouped opportunistic subscription, it's visible. Loading
src/com/android/settings/network/helper/QueryEsimCardId.java 0 → 100644 +58 −0 Original line number Diff line number Diff line /* * 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()); } } No newline at end of file
src/com/android/settings/network/helper/QuerySimSlotIndex.java 0 → 100644 +87 −0 Original line number Diff line number Diff line /* * 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(); } } No newline at end of file
src/com/android/settings/network/helper/SelectableSubscriptions.java 0 → 100644 +160 −0 Original line number Diff line number Diff line /* * 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 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.List; 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.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.IntStream; /** * This is a Callable class to query user selectable subscription list. * * Here's example of creating a Callable for retrieving a list of SubscriptionAnnotation * for active Subscriptions: * * List<SubscriptionAnnotation> result = (new SelectableSubscriptions(context, false)).call(); * * Another example for retrieving a list of SubscriptionAnnotation for all subscriptions * accessible in another thread. * * List<SubscriptionAnnotation> result = ExecutorService.submit( * new SelectableSubscriptions(context, true)).get() */ public class SelectableSubscriptions implements Callable<List<SubscriptionAnnotation>> { private static final String TAG = "SelectableSubscriptions"; private Context mContext; private Supplier<List<SubscriptionInfo>> mSubscriptions; private Predicate<SubscriptionAnnotation> mFilter; private Function<List<SubscriptionAnnotation>, List<SubscriptionAnnotation>> mFinisher; /** * 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()); mFinisher = annoList -> annoList; } /** * Add UnaryOperator to be applied to the final result. * @param finisher a function to be applied to the final result. */ public SelectableSubscriptions addFinisher( UnaryOperator<List<SubscriptionAnnotation>> finisher) { mFinisher = mFinisher.andThen(finisher); return this; } /** * 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()); // build a list of SubscriptionAnnotation return IntStream.range(0, subInfoList.size()) .mapToObj(subInfoIndex -> new SubscriptionAnnotation.Builder(subInfoList, subInfoIndex)) .map(annoBdr -> annoBdr.build(mContext, eSimCardIdList, simSlotIndexList, activeSimSlotIndexList)) .filter(mFilter) .collect(Collectors.collectingAndThen(Collectors.toList(), mFinisher)); } catch (Exception exception) { Log.w(TAG, "Fail to request subIdList", exception); } return Collections.emptyList(); } 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()); } } No newline at end of file
src/com/android/settings/network/helper/SubscriptionAnnotation.java 0 → 100644 +163 −0 Original line number Diff line number Diff line /* * 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 androidx.annotation.Keep; import androidx.annotation.VisibleForTesting; 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 ParcelUuid EMPTY_UUID = ParcelUuid.fromString("0-0-0-0-0"); 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 */ @Keep @VisibleForTesting 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 @Keep public int getOrderingInList() { return mOrderWithinList; } // type of subscription @Keep public int getType() { return mType; } // if a subscription is existed within device @Keep public boolean isExisted() { return mIsExisted; } // if a subscription is currently ON @Keep public boolean isActive() { return mIsActive; } // if display of subscription is allowed @Keep public boolean isDisplayAllowed() { return mIsAllowToDisplay; } // the subscription ID @Keep public int getSubscriptionId() { return (mSubInfo == null) ? SubscriptionManager.INVALID_SUBSCRIPTION_ID : mSubInfo.getSubscriptionId(); } // the grouping UUID @Keep public ParcelUuid getGroupUuid() { return (mSubInfo == null) ? null : mSubInfo.getGroupUuid(); } // the SubscriptionInfo @Keep public SubscriptionInfo getSubInfo() { return mSubInfo; } private boolean isDisplayAllowed(Context context) { return SubscriptionUtil.isSubscriptionVisible( context.getSystemService(SubscriptionManager.class), context, mSubInfo); } } No newline at end of file