1 /*
2  * Copyright (C) 2014 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.phone.settings;
18 
19 import android.app.AlertDialog;
20 import android.content.Context;
21 import android.content.pm.PackageManager;
22 import android.preference.ListPreference;
23 import android.preference.Preference;
24 import android.telecom.PhoneAccount;
25 import android.telecom.PhoneAccountHandle;
26 import android.telecom.TelecomManager;
27 import android.text.TextUtils;
28 import android.util.AttributeSet;
29 
30 import com.android.phone.R;
31 
32 import java.util.List;
33 import java.util.Objects;
34 
35 public class AccountSelectionPreference extends ListPreference implements
36         Preference.OnPreferenceChangeListener {
37 
38     public interface AccountSelectionListener {
onAccountSelected(AccountSelectionPreference pref, PhoneAccountHandle account)39         boolean onAccountSelected(AccountSelectionPreference pref, PhoneAccountHandle account);
onAccountSelectionDialogShow(AccountSelectionPreference pref)40         void onAccountSelectionDialogShow(AccountSelectionPreference pref);
onAccountChanged(AccountSelectionPreference pref)41         void onAccountChanged(AccountSelectionPreference pref);
42     }
43 
44     private final Context mContext;
45     private AccountSelectionListener mListener;
46     private PhoneAccountHandle[] mAccounts;
47     private String[] mEntryValues;
48     private CharSequence[] mEntries;
49     private boolean mShowSelectionInSummary = true;
50 
AccountSelectionPreference(Context context)51     public AccountSelectionPreference(Context context) {
52         this(context, null);
53     }
54 
AccountSelectionPreference(Context context, AttributeSet attrs)55     public AccountSelectionPreference(Context context, AttributeSet attrs) {
56         super(context, attrs);
57         mContext = context;
58         setOnPreferenceChangeListener(this);
59     }
60 
setListener(AccountSelectionListener listener)61     public void setListener(AccountSelectionListener listener) {
62         mListener = listener;
63     }
64 
setShowSelectionInSummary(boolean value)65     public void setShowSelectionInSummary(boolean value) {
66         mShowSelectionInSummary = value;
67     }
68 
setModel( TelecomManager telecomManager, List<PhoneAccountHandle> accountsList, PhoneAccountHandle currentSelection, CharSequence nullSelectionString)69     public void setModel(
70             TelecomManager telecomManager,
71             List<PhoneAccountHandle> accountsList,
72             PhoneAccountHandle currentSelection,
73             CharSequence nullSelectionString) {
74 
75         mAccounts = accountsList.toArray(new PhoneAccountHandle[accountsList.size()]);
76         mEntryValues = new String[mAccounts.length + 1];
77         mEntries = new CharSequence[mAccounts.length + 1];
78 
79         PackageManager pm = mContext.getPackageManager();
80 
81         int selectedIndex = mAccounts.length;  // Points to nullSelectionString by default
82         int i = 0;
83         for ( ; i < mAccounts.length; i++) {
84             PhoneAccount account = telecomManager.getPhoneAccount(mAccounts[i]);
85             CharSequence label = account.getLabel();
86             if (label != null) {
87                 label = pm.getUserBadgedLabel(label, mAccounts[i].getUserHandle());
88             }
89             boolean isSimAccount =
90                     account.hasCapabilities(PhoneAccount.CAPABILITY_SIM_SUBSCRIPTION);
91             mEntries[i] = (TextUtils.isEmpty(label) && isSimAccount)
92                     ? mContext.getString(R.string.phone_accounts_default_account_label)
93                     : String.valueOf(label);
94             mEntryValues[i] = Integer.toString(i);
95             if (Objects.equals(currentSelection, mAccounts[i])) {
96                 selectedIndex = i;
97             }
98         }
99         mEntryValues[i] = Integer.toString(i);
100         mEntries[i] = nullSelectionString;
101 
102         setEntryValues(mEntryValues);
103         setEntries(mEntries);
104         setValueIndex(selectedIndex);
105         if (mShowSelectionInSummary) {
106             setSummary(mEntries[selectedIndex]);
107         }
108     }
109 
110     @Override
onPreferenceChange(Preference preference, Object newValue)111     public boolean onPreferenceChange(Preference preference, Object newValue) {
112         if (mListener != null) {
113             int index = Integer.parseInt((String) newValue);
114             PhoneAccountHandle account = index < mAccounts.length ? mAccounts[index] : null;
115             if (mListener.onAccountSelected(this, account)) {
116                 if (mShowSelectionInSummary) {
117                     setSummary(mEntries[index]);
118                 }
119                 if (index != findIndexOfValue(getValue())) {
120                     setValueIndex(index);
121                     mListener.onAccountChanged(this);
122                 }
123                 return true;
124             }
125         }
126         return false;
127     }
128 
129     /**
130      * Modifies the dialog to change the default "Cancel" button to "Choose Accounts", which
131      * triggers the {@link PhoneAccountSelectionPreferenceActivity} to be shown.
132      *
133      * @param builder The {@code AlertDialog.Builder}.
134      */
135     @Override
136     protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
137         // Notify the listener that the dialog is about to be built.  This is important so that the
138         // list of enabled accounts can be updated prior to showing the dialog.
139         mListener.onAccountSelectionDialogShow(this);
140 
141         super.onPrepareDialogBuilder(builder);
142     }
143 }
144