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.contacts.common.widget;
18 
19 import android.telecom.PhoneAccount;
20 import android.telecom.PhoneAccountHandle;
21 import android.app.AlertDialog;
22 import android.app.Dialog;
23 import android.app.DialogFragment;
24 import android.app.FragmentManager;
25 import android.content.Context;
26 import android.content.DialogInterface;
27 import android.os.Bundle;
28 import android.telecom.TelecomManager;
29 import android.telephony.PhoneNumberUtils;
30 import android.text.TextUtils;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.ViewGroup;
34 import android.widget.ArrayAdapter;
35 import android.widget.CheckBox;
36 import android.widget.CompoundButton;
37 import android.widget.ImageView;
38 import android.widget.LinearLayout;
39 import android.widget.ListAdapter;
40 import android.widget.TextView;
41 
42 import com.android.contacts.common.R;
43 
44 import java.util.List;
45 
46 /**
47  * Dialog that allows the user to select a phone accounts for a given action. Optionally provides
48  * the choice to set the phone account as default.
49  */
50 public class SelectPhoneAccountDialogFragment extends DialogFragment {
51     private int mTitleResId;
52     private boolean mCanSetDefault;
53     private List<PhoneAccountHandle> mAccountHandles;
54     private boolean mIsSelected;
55     private boolean mIsDefaultChecked;
56     private TelecomManager mTelecomManager;
57     private SelectPhoneAccountListener mListener;
58 
59     /**
60      * Shows the account selection dialog.
61      * This is the preferred way to show this dialog.
62      *
63      * @param fragmentManager The fragment manager.
64      * @param accountHandles The {@code PhoneAccountHandle}s available to select from.
65      * @param listener The listener for the results of the account selection.
66      */
showAccountDialog(FragmentManager fragmentManager, List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener)67     public static void showAccountDialog(FragmentManager fragmentManager,
68             List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener) {
69         showAccountDialog(fragmentManager, R.string.select_account_dialog_title, false,
70                 accountHandles, listener);
71     }
72 
73     /**
74      * Shows the account selection dialog.
75      * This is the preferred way to show this dialog.
76      * This method also allows specifying a custom title and "set default" checkbox.
77      *
78      * @param fragmentManager The fragment manager.
79      * @param titleResId The resource ID for the string to use in the title of the dialog.
80      * @param canSetDefault {@code true} if the dialog should include an option to set the selection
81      * as the default. False otherwise.
82      * @param accountHandles The {@code PhoneAccountHandle}s available to select from.
83      * @param listener The listener for the results of the account selection.
84      */
showAccountDialog(FragmentManager fragmentManager, int titleResId, boolean canSetDefault, List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener)85     public static void showAccountDialog(FragmentManager fragmentManager, int titleResId,
86             boolean canSetDefault, List<PhoneAccountHandle> accountHandles,
87             SelectPhoneAccountListener listener) {
88         SelectPhoneAccountDialogFragment fragment =
89                 new SelectPhoneAccountDialogFragment(
90                         titleResId, canSetDefault, accountHandles, listener);
91         fragment.show(fragmentManager, "selectAccount");
92     }
93 
SelectPhoneAccountDialogFragment(int titleResId, boolean canSetDefault, List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener)94     public SelectPhoneAccountDialogFragment(int titleResId, boolean canSetDefault,
95             List<PhoneAccountHandle> accountHandles, SelectPhoneAccountListener listener) {
96         super();
97         mTitleResId = titleResId;
98         mCanSetDefault = canSetDefault;
99         mAccountHandles = accountHandles;
100         mListener = listener;
101     }
102 
103     public interface SelectPhoneAccountListener {
onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle, boolean setDefault)104         void onPhoneAccountSelected(PhoneAccountHandle selectedAccountHandle, boolean setDefault);
onDialogDismissed()105         void onDialogDismissed();
106     }
107 
108     @Override
onCreateDialog(Bundle savedInstanceState)109     public Dialog onCreateDialog(Bundle savedInstanceState) {
110         mIsSelected = false;
111         mIsDefaultChecked = false;
112         mTelecomManager =
113                 (TelecomManager) getActivity().getSystemService(Context.TELECOM_SERVICE);
114 
115         final DialogInterface.OnClickListener selectionListener =
116                 new DialogInterface.OnClickListener() {
117             @Override
118             public void onClick(DialogInterface dialog, int which) {
119                 mIsSelected = true;
120                 PhoneAccountHandle selectedAccountHandle = mAccountHandles.get(which);
121                 mListener.onPhoneAccountSelected(selectedAccountHandle, mIsDefaultChecked);
122             }
123         };
124 
125         final CompoundButton.OnCheckedChangeListener checkListener =
126                 new CompoundButton.OnCheckedChangeListener() {
127             @Override
128             public void onCheckedChanged(CompoundButton check, boolean isChecked) {
129                 mIsDefaultChecked = isChecked;
130             }
131         };
132 
133         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
134         ListAdapter selectAccountListAdapter = new SelectAccountListAdapter(
135                 builder.getContext(),
136                 R.layout.select_account_list_item,
137                 mAccountHandles);
138 
139         AlertDialog dialog = builder.setTitle(mTitleResId)
140                 .setAdapter(selectAccountListAdapter, selectionListener)
141                 .create();
142 
143         if (mCanSetDefault) {
144             // Generate custom checkbox view
145             LinearLayout checkboxLayout = (LinearLayout) getActivity()
146                     .getLayoutInflater()
147                     .inflate(R.layout.default_account_checkbox, null);
148 
149             CheckBox cb =
150                     (CheckBox) checkboxLayout.findViewById(R.id.default_account_checkbox_view);
151             cb.setOnCheckedChangeListener(checkListener);
152 
153             dialog.getListView().addFooterView(checkboxLayout);
154         }
155 
156         return dialog;
157     }
158 
159     private class SelectAccountListAdapter extends ArrayAdapter<PhoneAccountHandle> {
160         private int mResId;
161 
SelectAccountListAdapter( Context context, int resource, List<PhoneAccountHandle> accountHandles)162         public SelectAccountListAdapter(
163                 Context context, int resource, List<PhoneAccountHandle> accountHandles) {
164             super(context, resource, accountHandles);
165             mResId = resource;
166         }
167 
168         @Override
getView(int position, View convertView, ViewGroup parent)169         public View getView(int position, View convertView, ViewGroup parent) {
170             LayoutInflater inflater = (LayoutInflater)
171                     getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
172 
173             View rowView;
174             final ViewHolder holder;
175 
176             if (convertView == null) {
177                 // Cache views for faster scrolling
178                 rowView = inflater.inflate(mResId, null);
179                 holder = new ViewHolder();
180                 holder.labelTextView = (TextView) rowView.findViewById(R.id.label);
181                 holder.numberTextView = (TextView) rowView.findViewById(R.id.number);
182                 holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
183                 rowView.setTag(holder);
184             }
185             else {
186                 rowView = convertView;
187                 holder = (ViewHolder) rowView.getTag();
188             }
189 
190             PhoneAccountHandle accountHandle = getItem(position);
191             PhoneAccount account = mTelecomManager.getPhoneAccount(accountHandle);
192             holder.labelTextView.setText(account.getLabel());
193             if (account.getAddress() == null ||
194                     TextUtils.isEmpty(account.getAddress().getSchemeSpecificPart())) {
195                 holder.numberTextView.setVisibility(View.GONE);
196             } else {
197                 holder.numberTextView.setVisibility(View.VISIBLE);
198                 holder.numberTextView.setText(
199                         PhoneNumberUtils.ttsSpanAsPhoneNumber(
200                                 account.getAddress().getSchemeSpecificPart()));
201             }
202             holder.imageView.setImageDrawable(account.createIconDrawable(getContext()));
203             return rowView;
204         }
205 
206         private class ViewHolder {
207             TextView labelTextView;
208             TextView numberTextView;
209             ImageView imageView;
210         }
211     }
212 
213     @Override
onPause()214     public void onPause() {
215         if (!mIsSelected) {
216             mListener.onDialogDismissed();
217         }
218         super.onPause();
219     }
220 }
221