1 /*
2  * Copyright (C) 2015 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 package com.android.settings.nfc;
17 
18 import android.app.Activity;
19 import android.app.AlertDialog;
20 import android.content.ActivityNotFoundException;
21 import android.content.Context;
22 import android.content.DialogInterface;
23 import android.content.Intent;
24 import android.support.v7.preference.PreferenceViewHolder;
25 import android.util.Log;
26 import android.view.LayoutInflater;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.widget.BaseAdapter;
30 import android.widget.CompoundButton;
31 import android.widget.ImageView;
32 import android.widget.RadioButton;
33 
34 import com.android.settings.CustomDialogPreference;
35 import com.android.settings.R;
36 import com.android.settings.dashboard.SummaryLoader;
37 import com.android.settings.nfc.PaymentBackend.PaymentAppInfo;
38 
39 import java.util.List;
40 
41 public class NfcPaymentPreference extends CustomDialogPreference implements
42         PaymentBackend.Callback, View.OnClickListener {
43 
44     private static final String TAG = "NfcPaymentPreference";
45 
46     private final NfcPaymentAdapter mAdapter;
47     private final Context mContext;
48     private final LayoutInflater mLayoutInflater;
49     private final PaymentBackend mPaymentBackend;
50 
51     // Fields below only modified on UI thread
52     private ImageView mSettingsButtonView;
53 
NfcPaymentPreference(Context context, PaymentBackend backend)54     public NfcPaymentPreference(Context context, PaymentBackend backend) {
55         super(context, null);
56         mPaymentBackend = backend;
57         mContext = context;
58         backend.registerCallback(this);
59         mAdapter = new NfcPaymentAdapter();
60         setDialogTitle(context.getString(R.string.nfc_payment_pay_with));
61         mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
62         setWidgetLayoutResource(R.layout.preference_widget_settings);
63 
64         refresh();
65     }
66 
67     @Override
onBindViewHolder(PreferenceViewHolder view)68     public void onBindViewHolder(PreferenceViewHolder view) {
69         super.onBindViewHolder(view);
70 
71         mSettingsButtonView = (ImageView) view.findViewById(R.id.settings_button);
72         mSettingsButtonView.setOnClickListener(this);
73 
74         updateSettingsVisibility();
75     }
76 
77     /**
78      * MUST be called on UI thread.
79      */
refresh()80     public void refresh() {
81         List<PaymentAppInfo> appInfos = mPaymentBackend.getPaymentAppInfos();
82         PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp();
83         if (appInfos != null) {
84             PaymentAppInfo[] apps = appInfos.toArray(new PaymentAppInfo[appInfos.size()]);
85             mAdapter.updateApps(apps, defaultApp);
86         }
87         setTitle(R.string.nfc_payment_default);
88         if (defaultApp != null) {
89             setSummary(defaultApp.label);
90         } else {
91             setSummary(mContext.getString(R.string.nfc_payment_default_not_set));
92         }
93         updateSettingsVisibility();
94     }
95 
96     @Override
onPrepareDialogBuilder(AlertDialog.Builder builder, DialogInterface.OnClickListener listener)97     protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
98             DialogInterface.OnClickListener listener) {
99         super.onPrepareDialogBuilder(builder, listener);
100 
101         builder.setSingleChoiceItems(mAdapter, 0, listener);
102     }
103 
104     @Override
onPaymentAppsChanged()105     public void onPaymentAppsChanged() {
106         refresh();
107     }
108 
109     @Override
onClick(View view)110     public void onClick(View view) {
111         PaymentAppInfo defaultAppInfo = mPaymentBackend.getDefaultApp();
112         if (defaultAppInfo != null && defaultAppInfo.settingsComponent != null) {
113             Intent settingsIntent = new Intent(Intent.ACTION_MAIN);
114             settingsIntent.setComponent(defaultAppInfo.settingsComponent);
115             settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
116             try {
117                 mContext.startActivity(settingsIntent);
118             } catch (ActivityNotFoundException e) {
119                 Log.e(TAG, "Settings activity not found.");
120             }
121         }
122     }
123 
updateSettingsVisibility()124     void updateSettingsVisibility() {
125         if (mSettingsButtonView != null) {
126             PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp();
127             if (defaultApp == null || defaultApp.settingsComponent == null) {
128                 mSettingsButtonView.setVisibility(View.GONE);
129             } else {
130                 mSettingsButtonView.setVisibility(View.VISIBLE);
131 
132             }
133         }
134     }
135 
136     class NfcPaymentAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener,
137             View.OnClickListener {
138         // Only modified on UI thread
139         private PaymentAppInfo[] appInfos;
140 
NfcPaymentAdapter()141         public NfcPaymentAdapter() {
142         }
143 
updateApps(PaymentAppInfo[] appInfos, PaymentAppInfo currentDefault)144         public void updateApps(PaymentAppInfo[] appInfos, PaymentAppInfo currentDefault) {
145             // Clone app infos, only add those with a banner
146             this.appInfos = appInfos;
147             notifyDataSetChanged();
148         }
149 
150         @Override
getCount()151         public int getCount() {
152             return appInfos.length;
153         }
154 
155         @Override
getItem(int i)156         public PaymentAppInfo getItem(int i) {
157             return appInfos[i];
158         }
159 
160         @Override
getItemId(int i)161         public long getItemId(int i) {
162             return appInfos[i].componentName.hashCode();
163         }
164 
165         @Override
getView(int position, View convertView, ViewGroup parent)166         public View getView(int position, View convertView, ViewGroup parent) {
167             ViewHolder holder;
168             PaymentAppInfo appInfo = appInfos[position];
169             if (convertView == null) {
170                 convertView = mLayoutInflater.inflate(
171                         R.layout.nfc_payment_option, parent, false);
172                 holder = new ViewHolder();
173                 holder.imageView = (ImageView) convertView.findViewById(R.id.banner);
174                 holder.radioButton = (RadioButton) convertView.findViewById(R.id.button);
175                 convertView.setTag(holder);
176             } else {
177                 holder = (ViewHolder) convertView.getTag();
178             }
179             holder.imageView.setImageDrawable(appInfo.banner);
180             holder.imageView.setTag(appInfo);
181             holder.imageView.setContentDescription(appInfo.label);
182             holder.imageView.setOnClickListener(this);
183 
184             // Prevent checked callback getting called on recycled views
185             holder.radioButton.setOnCheckedChangeListener(null);
186             holder.radioButton.setChecked(appInfo.isDefault);
187             holder.radioButton.setContentDescription(appInfo.label);
188             holder.radioButton.setOnCheckedChangeListener(this);
189             holder.radioButton.setTag(appInfo);
190             return convertView;
191         }
192 
193         public class ViewHolder {
194             public ImageView imageView;
195             public RadioButton radioButton;
196         }
197 
198         @Override
onCheckedChanged(CompoundButton compoundButton, boolean b)199         public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
200             PaymentAppInfo appInfo = (PaymentAppInfo) compoundButton.getTag();
201             makeDefault(appInfo);
202         }
203 
204         @Override
onClick(View view)205         public void onClick(View view) {
206             PaymentAppInfo appInfo = (PaymentAppInfo) view.getTag();
207             makeDefault(appInfo);
208         }
209 
makeDefault(PaymentAppInfo appInfo)210         void makeDefault(PaymentAppInfo appInfo) {
211             if (!appInfo.isDefault) {
212                 mPaymentBackend.setDefaultPaymentApp(appInfo.componentName);
213             }
214             getDialog().dismiss();
215         }
216     }
217 }
218