• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.settings.sim;
18 
19 import android.app.Dialog;
20 import android.app.settings.SettingsEnums;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.os.Bundle;
24 import android.telephony.SubscriptionInfo;
25 import android.telephony.SubscriptionManager;
26 import android.text.TextUtils;
27 import android.util.Log;
28 import android.view.LayoutInflater;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.widget.BaseAdapter;
32 import android.widget.ImageView;
33 import android.widget.TextView;
34 
35 import androidx.annotation.NonNull;
36 import androidx.annotation.Nullable;
37 import androidx.annotation.VisibleForTesting;
38 import androidx.appcompat.app.AlertDialog;
39 
40 import com.android.settings.R;
41 import com.android.settings.Utils;
42 import com.android.settings.network.SubscriptionUtil;
43 
44 import java.util.ArrayList;
45 import java.util.List;
46 
47 /**
48  * Shows a dialog consisting of a list of SIMs (aka subscriptions), possibly including an additional
49  * entry indicating "ask me every time".
50  */
51 public class SimListDialogFragment extends SimDialogFragment implements
52         DialogInterface.OnClickListener {
53     private static final String TAG = "SimListDialogFragment";
54     protected static final String KEY_INCLUDE_ASK_EVERY_TIME = "include_ask_every_time";
55 
56     protected SelectSubscriptionAdapter mAdapter;
57     @VisibleForTesting
58     List<SubscriptionInfo> mSubscriptions;
59 
newInstance(int dialogType, int titleResId, boolean includeAskEveryTime)60     public static SimListDialogFragment newInstance(int dialogType, int titleResId,
61             boolean includeAskEveryTime) {
62         final SimListDialogFragment fragment = new SimListDialogFragment();
63         final Bundle args = initArguments(dialogType, titleResId);
64         args.putBoolean(KEY_INCLUDE_ASK_EVERY_TIME, includeAskEveryTime);
65         fragment.setArguments(args);
66         return fragment;
67     }
68 
69     @NonNull
70     @Override
onCreateDialog(@ullable Bundle savedInstanceState)71     public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
72         mSubscriptions = new ArrayList<>();
73 
74         final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
75         builder.setTitle(getTitleResId());
76 
77         mAdapter = new SelectSubscriptionAdapter(builder.getContext(), mSubscriptions);
78 
79         setAdapter(builder);
80         final Dialog dialog = builder.create();
81         updateDialog();
82         return dialog;
83     }
84 
85     @Override
onClick(DialogInterface dialog, int selectionIndex)86     public void onClick(DialogInterface dialog, int selectionIndex) {
87         if (selectionIndex >= 0 && selectionIndex < mSubscriptions.size()) {
88             int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
89             final SubscriptionInfo subscription = mSubscriptions.get(selectionIndex);
90             if (subscription != null) {
91                 subId = subscription.getSubscriptionId();
92             }
93             final SimDialogActivity activity = (SimDialogActivity) getActivity();
94             activity.onSubscriptionSelected(getDialogType(), subId);
95         }
96     }
97 
getCurrentSubscriptions()98     protected List<SubscriptionInfo> getCurrentSubscriptions() {
99         final SubscriptionManager manager = getContext().getSystemService(
100                 SubscriptionManager.class);
101         return manager.getActiveSubscriptionInfoList();
102     }
103 
104     @Override
updateDialog()105     public void updateDialog() {
106         Log.d(TAG, "Dialog updated, dismiss status: " + mWasDismissed);
107 
108         List<SubscriptionInfo> currentSubscriptions = getCurrentSubscriptions();
109         if (currentSubscriptions == null) {
110             if (!mWasDismissed) {
111                 dismiss();
112             }
113             return;
114         }
115         if (getArguments().getBoolean(KEY_INCLUDE_ASK_EVERY_TIME)) {
116             final List<SubscriptionInfo> tmp = new ArrayList<>(currentSubscriptions.size() + 1);
117             tmp.add(null);
118             tmp.addAll(currentSubscriptions);
119             currentSubscriptions = tmp;
120         }
121         if (currentSubscriptions.equals(mSubscriptions)) {
122             return;
123         }
124         mSubscriptions.clear();
125         mSubscriptions.addAll(currentSubscriptions);
126         mAdapter.notifyDataSetChanged();
127     }
128 
129     @VisibleForTesting
setAdapter(AlertDialog.Builder builder)130     void setAdapter(AlertDialog.Builder builder) {
131         builder.setAdapter(mAdapter, this);
132     }
133 
134     @Override
getMetricsCategory()135     public int getMetricsCategory() {
136         return SettingsEnums.DIALOG_SIM_LIST;
137     }
138 
139     private static class SelectSubscriptionAdapter extends BaseAdapter {
140         private Context mContext;
141         private LayoutInflater mInflater;
142         List<SubscriptionInfo> mSubscriptions;
143 
SelectSubscriptionAdapter(Context context, List<SubscriptionInfo> subscriptions)144         public SelectSubscriptionAdapter(Context context, List<SubscriptionInfo> subscriptions) {
145             mSubscriptions = subscriptions;
146             mContext = context;
147         }
148 
149         @Override
getCount()150         public int getCount() {
151             return mSubscriptions.size();
152         }
153 
154         @Override
getItem(int position)155         public SubscriptionInfo getItem(int position) {
156             return mSubscriptions.get(position);
157         }
158 
159         @Override
getItemId(int position)160         public long getItemId(int position) {
161             final SubscriptionInfo info = mSubscriptions.get(position);
162             if (info == null) {
163                 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
164             }
165             return info.getSubscriptionId();
166         }
167 
168         @Override
getView(int position, View convertView, ViewGroup parent)169         public View getView(int position, View convertView, ViewGroup parent) {
170             if (convertView == null) {
171                 if (mInflater == null) {
172                     mInflater = LayoutInflater.from(parent.getContext());
173                 }
174                 convertView = mInflater.inflate(R.layout.select_account_list_item, parent, false);
175             }
176             final SubscriptionInfo sub = getItem(position);
177 
178             final TextView title = convertView.findViewById(R.id.title);
179             final TextView summary = convertView.findViewById(R.id.summary);
180             final ImageView icon = convertView.findViewById(R.id.icon);
181 
182             if (sub == null) {
183                 title.setText(R.string.sim_calls_ask_first_prefs_title);
184                 summary.setText("");
185                 icon.setImageDrawable(mContext.getDrawable(R.drawable.ic_feedback_24dp));
186                 icon.setImageTintList(
187                         Utils.getColorAttr(mContext, android.R.attr.textColorSecondary));
188             } else {
189                 title.setText(SubscriptionUtil.getUniqueSubscriptionDisplayName(sub, mContext));
190                 summary.setText(isMdnProvisioned(sub.getNumber()) ? sub.getNumber() : "");
191                 icon.setImageBitmap(sub.createIconBitmap(mContext));
192 
193             }
194             return convertView;
195         }
196 
197         // An MDN is considered not provisioned if it's empty or all 0's
isMdnProvisioned(String mdn)198         private boolean isMdnProvisioned(String mdn) {
199             return !(TextUtils.isEmpty(mdn) || mdn.matches("[\\D0]+"));
200         }
201     }
202 }
203