Since U, a sub can be associated with a particular profile, and thus in V we enforce filtering on the caller and only show the subs that are associated with the caller. However, in some cases the caller indeed needs to see all subs regardless of its association, e.g. sysUI. Therefore, a param isForAllProfile is added to indicate whether the caller intends to see all subs. Bug: 296076674 Test: voice call + data browsing Flag: ACONFIG com.android.internal.telephony.flags.enforce_subscription_user_filter DEVELOPMENT Change-Id: I88e29b445a11f36e1a3db80368bb9e46ef06eac3
255 lines
9.5 KiB
Java
255 lines
9.5 KiB
Java
/*
|
|
* Copyright (C) 2019 The Android Open Source Project
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License
|
|
*/
|
|
|
|
package com.android.settings.sim;
|
|
|
|
import static android.telephony.SubscriptionManager.PROFILE_CLASS_PROVISIONING;
|
|
|
|
import android.app.Dialog;
|
|
import android.app.settings.SettingsEnums;
|
|
import android.content.Context;
|
|
import android.os.Bundle;
|
|
import android.telephony.SubscriptionInfo;
|
|
import android.telephony.SubscriptionManager;
|
|
import android.text.TextUtils;
|
|
import android.util.Log;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.AdapterView;
|
|
import android.widget.BaseAdapter;
|
|
import android.widget.ListView;
|
|
import android.widget.TextView;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.annotation.VisibleForTesting;
|
|
import androidx.appcompat.app.AlertDialog;
|
|
|
|
import com.android.internal.telephony.flags.Flags;
|
|
import com.android.settings.R;
|
|
import com.android.settings.network.SubscriptionUtil;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Shows a dialog consisting of a list of SIMs (aka subscriptions), possibly including an additional
|
|
* entry indicating "ask me every time".
|
|
*/
|
|
public class SimListDialogFragment extends SimDialogFragment {
|
|
private static final String TAG = "SimListDialogFragment";
|
|
protected static final String KEY_INCLUDE_ASK_EVERY_TIME = "include_ask_every_time";
|
|
protected static final String KEY_SHOW_CANCEL_ITEM = "show_cancel_item";
|
|
|
|
protected SelectSubscriptionAdapter mAdapter;
|
|
@VisibleForTesting
|
|
@NonNull
|
|
List<SubscriptionInfo> mSubscriptions = new ArrayList<>();
|
|
|
|
public static SimListDialogFragment newInstance(int dialogType, int titleResId,
|
|
boolean includeAskEveryTime, boolean isCancelItemShowed) {
|
|
final SimListDialogFragment fragment = new SimListDialogFragment();
|
|
final Bundle args = initArguments(dialogType, titleResId);
|
|
args.putBoolean(KEY_INCLUDE_ASK_EVERY_TIME, includeAskEveryTime);
|
|
args.putBoolean(KEY_SHOW_CANCEL_ITEM, isCancelItemShowed);
|
|
fragment.setArguments(args);
|
|
return fragment;
|
|
}
|
|
|
|
@NonNull
|
|
@Override
|
|
public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
|
|
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
|
View titleView = LayoutInflater.from(getContext()).inflate(
|
|
R.layout.sim_confirm_dialog_title_multiple_enabled_profiles_supported, null);
|
|
TextView titleTextView = titleView.findViewById(R.id.title);
|
|
titleTextView.setText(getContext().getString(getTitleResId()));
|
|
builder.setCustomTitle(titleTextView);
|
|
mAdapter = new SelectSubscriptionAdapter(builder.getContext(), mSubscriptions);
|
|
|
|
final AlertDialog dialog = builder.create();
|
|
|
|
View content = LayoutInflater.from(getContext()).inflate(
|
|
R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null);
|
|
|
|
final ListView lvItems = content != null ? content.findViewById(R.id.carrier_list) : null;
|
|
if (lvItems != null) {
|
|
setAdapter(lvItems);
|
|
lvItems.setVisibility(View.VISIBLE);
|
|
lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
|
@Override
|
|
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
|
onClick(position);
|
|
}
|
|
});
|
|
}
|
|
|
|
dialog.setView(content);
|
|
updateDialog();
|
|
|
|
return dialog;
|
|
}
|
|
|
|
/**
|
|
* If the user click the item at the list, then it sends the callback.
|
|
* @param selectionIndex the index of item in the list.
|
|
*/
|
|
public void onClick(int selectionIndex) {
|
|
final SimDialogActivity activity = (SimDialogActivity) getActivity();
|
|
if (selectionIndex >= 0 && selectionIndex < mSubscriptions.size()) {
|
|
int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
|
final SubscriptionInfo subscription = mSubscriptions.get(selectionIndex);
|
|
if (subscription != null) {
|
|
subId = subscription.getSubscriptionId();
|
|
}
|
|
activity.onSubscriptionSelected(getDialogType(), subId);
|
|
}
|
|
Log.d(TAG, "Start showing auto data switch dialog");
|
|
activity.showEnableAutoDataSwitchDialog();
|
|
if (getDialog() != null) getDialog().dismiss();
|
|
}
|
|
|
|
protected List<SubscriptionInfo> getCurrentSubscriptions() {
|
|
final SubscriptionManager manager = getContext().getSystemService(
|
|
SubscriptionManager.class).createForAllUserProfiles();
|
|
return manager.getActiveSubscriptionInfoList();
|
|
}
|
|
|
|
@Override
|
|
public void updateDialog() {
|
|
Log.d(TAG, "Dialog updated, dismiss status: " + mWasDismissed);
|
|
if (mWasDismissed) {
|
|
return;
|
|
}
|
|
|
|
List<SubscriptionInfo> currentSubscriptions = getCurrentSubscriptions();
|
|
if (currentSubscriptions == null) {
|
|
dismiss();
|
|
return;
|
|
}
|
|
|
|
// Remove the provisioning or satellite eSIM from the subscription list.
|
|
currentSubscriptions.removeIf(info -> info.isEmbedded()
|
|
&& (info.getProfileClass() == PROFILE_CLASS_PROVISIONING
|
|
|| (Flags.oemEnabledSatelliteFlag() && info.isOnlyNonTerrestrialNetwork())));
|
|
|
|
boolean includeAskEveryTime = getArguments().getBoolean(KEY_INCLUDE_ASK_EVERY_TIME);
|
|
boolean isCancelItemShowed = getArguments().getBoolean(KEY_SHOW_CANCEL_ITEM);
|
|
if (includeAskEveryTime || isCancelItemShowed) {
|
|
int arraySize = currentSubscriptions.size()
|
|
+ (includeAskEveryTime ? 1 : 0)
|
|
+ (isCancelItemShowed ? 1 : 0);
|
|
final List<SubscriptionInfo> tmp = new ArrayList<>(arraySize);
|
|
if (includeAskEveryTime) {
|
|
// add the value of 'AskEveryTime' item
|
|
tmp.add(null);
|
|
}
|
|
tmp.addAll(currentSubscriptions);
|
|
if (isCancelItemShowed) {
|
|
// add the value of 'Cancel' item
|
|
tmp.add(null);
|
|
}
|
|
currentSubscriptions = tmp;
|
|
}
|
|
if (currentSubscriptions.equals(mSubscriptions)) {
|
|
return;
|
|
}
|
|
|
|
mSubscriptions.clear();
|
|
mSubscriptions.addAll(currentSubscriptions);
|
|
mAdapter.notifyDataSetChanged();
|
|
}
|
|
|
|
@VisibleForTesting
|
|
void setAdapter(ListView lvItems) {
|
|
lvItems.setAdapter(mAdapter);
|
|
}
|
|
|
|
@Override
|
|
public int getMetricsCategory() {
|
|
return SettingsEnums.DIALOG_SIM_LIST;
|
|
}
|
|
|
|
private static class SelectSubscriptionAdapter extends BaseAdapter {
|
|
private Context mContext;
|
|
private LayoutInflater mInflater;
|
|
List<SubscriptionInfo> mSubscriptions;
|
|
|
|
public SelectSubscriptionAdapter(Context context, List<SubscriptionInfo> subscriptions) {
|
|
mSubscriptions = subscriptions;
|
|
mContext = context;
|
|
}
|
|
|
|
@Override
|
|
public int getCount() {
|
|
return mSubscriptions.size();
|
|
}
|
|
|
|
@Override
|
|
public SubscriptionInfo getItem(int position) {
|
|
return mSubscriptions.get(position);
|
|
}
|
|
|
|
@Override
|
|
public long getItemId(int position) {
|
|
final SubscriptionInfo info = mSubscriptions.get(position);
|
|
if (info == null) {
|
|
return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
|
|
}
|
|
return info.getSubscriptionId();
|
|
}
|
|
|
|
@Override
|
|
public View getView(int position, View convertView, ViewGroup parent) {
|
|
if (convertView == null) {
|
|
if (mInflater == null) {
|
|
mInflater = LayoutInflater.from(parent.getContext());
|
|
}
|
|
convertView = mInflater.inflate(R.layout.select_account_list_item, parent, false);
|
|
}
|
|
final SubscriptionInfo sub = getItem(position);
|
|
|
|
final TextView title = convertView.findViewById(R.id.title);
|
|
final TextView summary = convertView.findViewById(R.id.summary);
|
|
|
|
if (sub == null) {
|
|
if (position == 0) {
|
|
title.setText(R.string.sim_calls_ask_first_prefs_title);
|
|
} else {
|
|
title.setText(R.string.sim_action_cancel);
|
|
}
|
|
summary.setVisibility(View.GONE);
|
|
} else {
|
|
title.setText(SubscriptionUtil.getUniqueSubscriptionDisplayName(sub, mContext));
|
|
String phoneNumber = isMdnProvisioned(sub.getNumber()) ? sub.getNumber() : "";
|
|
if (!TextUtils.isEmpty(phoneNumber)) {
|
|
summary.setVisibility(View.VISIBLE);
|
|
summary.setText(phoneNumber);
|
|
} else {
|
|
summary.setVisibility(View.GONE);
|
|
}
|
|
}
|
|
return convertView;
|
|
}
|
|
|
|
// An MDN is considered not provisioned if it's empty or all 0's
|
|
private boolean isMdnProvisioned(String mdn) {
|
|
return !(TextUtils.isEmpty(mdn) || mdn.matches("[\\D0]+"));
|
|
}
|
|
}
|
|
}
|