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