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