From ff244c0e403aabb4fa2b5388bdced924aa770c34 Mon Sep 17 00:00:00 2001 From: chiujason Date: Thu, 12 Apr 2018 15:52:00 +0800 Subject: [PATCH] Migrate PaymentSettings to DashboardFragment - Move preference related logic to controllers. - Add some test cases for controllers. Test: manual Test: make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.nfc make RunSettingsRoboTests -j ROBOTEST_FILTER=com.android.settings.core atest SettingsGatewayTest UniquePreferenceTest Change-Id: I061a194c170f63fab51974f26c24be43d67d6f6f --- res/xml/nfc_payment_settings.xml | 15 ++ .../settings/nfc/BaseNfcPreferenceController.java | 13 +- .../settings/nfc/NfcForegroundPreference.java | 65 ------ .../nfc/NfcForegroundPreferenceController.java | 129 +++++++++++ .../android/settings/nfc/NfcPaymentPreference.java | 199 +++------------- .../nfc/NfcPaymentPreferenceController.java | 257 +++++++++++++++++++++ src/com/android/settings/nfc/PaymentBackend.java | 30 ++- src/com/android/settings/nfc/PaymentSettings.java | 81 +++---- .../nfc/AndroidBeamPreferenceControllerTest.java | 4 +- .../nfc/NfcForegroundPreferenceControllerTest.java | 158 +++++++++++++ .../settings/nfc/NfcForegroundPreferenceTest.java | 79 ------- .../nfc/NfcPaymentPreferenceControllerTest.java | 150 ++++++++++++ .../settings/nfc/NfcPreferenceControllerTest.java | 9 +- .../android/settings/nfc/PaymentSettingsTest.java | 47 +++- 14 files changed, 831 insertions(+), 405 deletions(-) delete mode 100644 src/com/android/settings/nfc/NfcForegroundPreference.java create mode 100644 src/com/android/settings/nfc/NfcForegroundPreferenceController.java create mode 100644 src/com/android/settings/nfc/NfcPaymentPreferenceController.java create mode 100644 tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceControllerTest.java delete mode 100644 tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceTest.java create mode 100644 tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java diff --git a/res/xml/nfc_payment_settings.xml b/res/xml/nfc_payment_settings.xml index 9a5185c483..2508c39fab 100644 --- a/res/xml/nfc_payment_settings.xml +++ b/res/xml/nfc_payment_settings.xml @@ -16,5 +16,20 @@ + + + + + diff --git a/src/com/android/settings/nfc/BaseNfcPreferenceController.java b/src/com/android/settings/nfc/BaseNfcPreferenceController.java index f9cd88a965..e8e7dfd484 100644 --- a/src/com/android/settings/nfc/BaseNfcPreferenceController.java +++ b/src/com/android/settings/nfc/BaseNfcPreferenceController.java @@ -19,11 +19,8 @@ import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.nfc.NfcAdapter; -import android.nfc.NfcManager; import android.os.Handler; import android.provider.Settings; -import androidx.preference.Preference; -import androidx.preference.PreferenceScreen; import com.android.settings.core.PreferenceControllerMixin; import com.android.settingslib.core.AbstractPreferenceController; @@ -31,7 +28,8 @@ import com.android.settingslib.core.lifecycle.LifecycleObserver; import com.android.settingslib.core.lifecycle.events.OnPause; import com.android.settingslib.core.lifecycle.events.OnResume; -import java.util.List; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; public abstract class BaseNfcPreferenceController extends AbstractPreferenceController implements PreferenceControllerMixin, LifecycleObserver, OnResume, OnPause { @@ -66,13 +64,6 @@ public abstract class BaseNfcPreferenceController extends AbstractPreferenceCont } @Override - public void updateNonIndexableKeys(List keys) { - if (!isAvailable()) { - keys.add(getPreferenceKey()); - } - } - - @Override public boolean isAvailable() { return mNfcAdapter != null; } diff --git a/src/com/android/settings/nfc/NfcForegroundPreference.java b/src/com/android/settings/nfc/NfcForegroundPreference.java deleted file mode 100644 index 728f2e4b59..0000000000 --- a/src/com/android/settings/nfc/NfcForegroundPreference.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.settings.nfc; - -import android.content.Context; -import androidx.preference.DropDownPreference; -import androidx.preference.Preference; - -import com.android.settings.R; - -public class NfcForegroundPreference extends DropDownPreference implements - PaymentBackend.Callback, Preference.OnPreferenceChangeListener { - - private final PaymentBackend mPaymentBackend; - public NfcForegroundPreference(Context context, PaymentBackend backend) { - super(context); - mPaymentBackend = backend; - mPaymentBackend.registerCallback(this); - - setTitle(getContext().getString(R.string.nfc_payment_use_default)); - setEntries(new CharSequence[] { - getContext().getString(R.string.nfc_payment_favor_open), - getContext().getString(R.string.nfc_payment_favor_default) - }); - setEntryValues(new CharSequence[] { "1", "0" }); - refresh(); - setOnPreferenceChangeListener(this); - } - - @Override - public void onPaymentAppsChanged() { - refresh(); - } - - void refresh() { - boolean foregroundMode = mPaymentBackend.isForegroundMode(); - if (foregroundMode) { - setValue("1"); - } else { - setValue("0"); - } - setSummary(getEntry()); - } - - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - String newValueString = (String) newValue; - setSummary(getEntries()[findIndexOfValue(newValueString)]); - mPaymentBackend.setForegroundMode(Integer.parseInt(newValueString) != 0); - return true; - } -} diff --git a/src/com/android/settings/nfc/NfcForegroundPreferenceController.java b/src/com/android/settings/nfc/NfcForegroundPreferenceController.java new file mode 100644 index 0000000000..fbc5a32fed --- /dev/null +++ b/src/com/android/settings/nfc/NfcForegroundPreferenceController.java @@ -0,0 +1,129 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package com.android.settings.nfc; + +import android.content.Context; +import android.content.pm.PackageManager; +import android.text.TextUtils; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; + +import java.util.List; + +import androidx.preference.DropDownPreference; +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; + +public class NfcForegroundPreferenceController extends BasePreferenceController implements + PaymentBackend.Callback, Preference.OnPreferenceChangeListener, + LifecycleObserver, OnStart, OnStop { + + private DropDownPreference mPreference; + private PaymentBackend mPaymentBackend; + + public NfcForegroundPreferenceController(Context context, String key) { + super(context, key); + } + + public void setPaymentBackend(PaymentBackend backend) { + mPaymentBackend = backend; + } + + @Override + public void onStart() { + if (mPaymentBackend != null) { + mPaymentBackend.registerCallback(this); + } + } + + @Override + public void onStop() { + if (mPaymentBackend != null) { + mPaymentBackend.unregisterCallback(this); + } + } + + @Override + public int getAvailabilityStatus() { + final PackageManager pm = mContext.getPackageManager(); + if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) { + return DISABLED_UNSUPPORTED; + } + if (mPaymentBackend == null) { + return DISABLED_UNSUPPORTED; + } + final List appInfos = mPaymentBackend.getPaymentAppInfos(); + return (appInfos != null && !appInfos.isEmpty()) + ? AVAILABLE + : DISABLED_UNSUPPORTED; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = (DropDownPreference) screen.findPreference(getPreferenceKey()); + if (mPreference == null) { + return; + } + + mPreference.setEntries(new CharSequence[] { + mContext.getText(R.string.nfc_payment_favor_open), + mContext.getText(R.string.nfc_payment_favor_default) + }); + mPreference.setEntryValues(new CharSequence[] {"1", "0"}); + } + + @Override + public void onPaymentAppsChanged() { + updateState(mPreference); + } + + @Override + public void updateState(Preference preference) { + if (preference instanceof DropDownPreference) { + ((DropDownPreference) preference).setValue( + mPaymentBackend.isForegroundMode() ? "1" : "0"); + } + super.updateState(preference); + } + + @Override + public CharSequence getSummary() { + return mPreference.getEntry(); + } + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (!(preference instanceof DropDownPreference)) { + return false; + } + final DropDownPreference pref = (DropDownPreference) preference; + final String newValueString = (String) newValue; + pref.setSummary(pref.getEntries()[pref.findIndexOfValue(newValueString)]); + mPaymentBackend.setForegroundMode(Integer.parseInt(newValueString) != 0); + return true; + } + + @Override + public void updateNonIndexableKeys(List keys) { + final String key = getPreferenceKey(); + if (!TextUtils.isEmpty(key)) { + keys.add(key); + } + } +} \ No newline at end of file diff --git a/src/com/android/settings/nfc/NfcPaymentPreference.java b/src/com/android/settings/nfc/NfcPaymentPreference.java index 0838a90e62..456115ad67 100644 --- a/src/com/android/settings/nfc/NfcPaymentPreference.java +++ b/src/com/android/settings/nfc/NfcPaymentPreference.java @@ -16,203 +16,58 @@ package com.android.settings.nfc; import android.app.AlertDialog; -import android.content.ActivityNotFoundException; import android.content.Context; -import android.app.Dialog; import android.content.DialogInterface; -import android.content.Intent; -import androidx.preference.PreferenceViewHolder; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.BaseAdapter; -import android.widget.CompoundButton; -import android.widget.ImageView; -import android.widget.RadioButton; +import android.util.AttributeSet; -import com.android.settings.R; -import com.android.settings.nfc.PaymentBackend.PaymentAppInfo; import com.android.settingslib.CustomDialogPreference; -import java.util.List; - -public class NfcPaymentPreference extends CustomDialogPreference implements - PaymentBackend.Callback, View.OnClickListener { - - private static final String TAG = "NfcPaymentPreference"; +import androidx.preference.PreferenceViewHolder; - private final NfcPaymentAdapter mAdapter; - private final Context mContext; - private final LayoutInflater mLayoutInflater; - private final PaymentBackend mPaymentBackend; +public class NfcPaymentPreference extends CustomDialogPreference { - // Fields below only modified on UI thread - private ImageView mSettingsButtonView; + private Listener mListener; - public NfcPaymentPreference(Context context, PaymentBackend backend) { - super(context, null); - mPaymentBackend = backend; - mContext = context; - backend.registerCallback(this); - mAdapter = new NfcPaymentAdapter(); - setDialogTitle(context.getString(R.string.nfc_payment_pay_with)); - mLayoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); - setWidgetLayoutResource(R.layout.preference_widget_gear); + interface Listener { + void onBindViewHolder(PreferenceViewHolder view); - refresh(); + void onPrepareDialogBuilder(AlertDialog.Builder builder, + DialogInterface.OnClickListener listener); } - @Override - public void onBindViewHolder(PreferenceViewHolder view) { - super.onBindViewHolder(view); - - mSettingsButtonView = (ImageView) view.findViewById(R.id.settings_button); - mSettingsButtonView.setOnClickListener(this); - - updateSettingsVisibility(); + public NfcPaymentPreference(Context context, AttributeSet attrs, int defStyleAttr, + int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); } - /** - * MUST be called on UI thread. - */ - public void refresh() { - List appInfos = mPaymentBackend.getPaymentAppInfos(); - PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp(); - if (appInfos != null) { - PaymentAppInfo[] apps = appInfos.toArray(new PaymentAppInfo[appInfos.size()]); - mAdapter.updateApps(apps, defaultApp); - } - setTitle(R.string.nfc_payment_default); - if (defaultApp != null) { - setSummary(defaultApp.label); - } else { - setSummary(mContext.getString(R.string.nfc_payment_default_not_set)); - } - updateSettingsVisibility(); + public NfcPaymentPreference(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); } - @Override - protected void onPrepareDialogBuilder(AlertDialog.Builder builder, - DialogInterface.OnClickListener listener) { - super.onPrepareDialogBuilder(builder, listener); - - builder.setSingleChoiceItems(mAdapter, 0, listener); + public NfcPaymentPreference(Context context, AttributeSet attrs) { + super(context, attrs); } - @Override - public void onPaymentAppsChanged() { - refresh(); + void initialize(Listener listener) { + mListener = listener; } @Override - public void onClick(View view) { - PaymentAppInfo defaultAppInfo = mPaymentBackend.getDefaultApp(); - if (defaultAppInfo != null && defaultAppInfo.settingsComponent != null) { - Intent settingsIntent = new Intent(Intent.ACTION_MAIN); - settingsIntent.setComponent(defaultAppInfo.settingsComponent); - settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - mContext.startActivity(settingsIntent); - } catch (ActivityNotFoundException e) { - Log.e(TAG, "Settings activity not found."); - } - } - } - - void updateSettingsVisibility() { - if (mSettingsButtonView != null) { - PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp(); - if (defaultApp == null || defaultApp.settingsComponent == null) { - mSettingsButtonView.setVisibility(View.GONE); - } else { - mSettingsButtonView.setVisibility(View.VISIBLE); + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); - } + if (mListener != null) { + mListener.onBindViewHolder(view); } } - class NfcPaymentAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener, - View.OnClickListener { - // Only modified on UI thread - private PaymentAppInfo[] appInfos; - - public NfcPaymentAdapter() { - } - - public void updateApps(PaymentAppInfo[] appInfos, PaymentAppInfo currentDefault) { - // Clone app infos, only add those with a banner - this.appInfos = appInfos; - notifyDataSetChanged(); - } - - @Override - public int getCount() { - return appInfos.length; - } - - @Override - public PaymentAppInfo getItem(int i) { - return appInfos[i]; - } - - @Override - public long getItemId(int i) { - return appInfos[i].componentName.hashCode(); - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - ViewHolder holder; - PaymentAppInfo appInfo = appInfos[position]; - if (convertView == null) { - convertView = mLayoutInflater.inflate( - R.layout.nfc_payment_option, parent, false); - holder = new ViewHolder(); - holder.imageView = (ImageView) convertView.findViewById(R.id.banner); - holder.radioButton = (RadioButton) convertView.findViewById(R.id.button); - convertView.setTag(holder); - } else { - holder = (ViewHolder) convertView.getTag(); - } - holder.imageView.setImageDrawable(appInfo.banner); - holder.imageView.setTag(appInfo); - holder.imageView.setContentDescription(appInfo.label); - holder.imageView.setOnClickListener(this); - - // Prevent checked callback getting called on recycled views - holder.radioButton.setOnCheckedChangeListener(null); - holder.radioButton.setChecked(appInfo.isDefault); - holder.radioButton.setContentDescription(appInfo.label); - holder.radioButton.setOnCheckedChangeListener(this); - holder.radioButton.setTag(appInfo); - return convertView; - } - - public class ViewHolder { - public ImageView imageView; - public RadioButton radioButton; - } - - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean b) { - PaymentAppInfo appInfo = (PaymentAppInfo) compoundButton.getTag(); - makeDefault(appInfo); - } - - @Override - public void onClick(View view) { - PaymentAppInfo appInfo = (PaymentAppInfo) view.getTag(); - makeDefault(appInfo); - } + @Override + protected void onPrepareDialogBuilder(AlertDialog.Builder builder, + DialogInterface.OnClickListener listener) { + super.onPrepareDialogBuilder(builder, listener); - void makeDefault(PaymentAppInfo appInfo) { - if (!appInfo.isDefault) { - mPaymentBackend.setDefaultPaymentApp(appInfo.componentName); - } - Dialog dialog = getDialog(); - if (dialog != null) - dialog.dismiss(); + if (mListener != null) { + mListener.onPrepareDialogBuilder(builder, listener); } } } diff --git a/src/com/android/settings/nfc/NfcPaymentPreferenceController.java b/src/com/android/settings/nfc/NfcPaymentPreferenceController.java new file mode 100644 index 0000000000..4f2f755ad7 --- /dev/null +++ b/src/com/android/settings/nfc/NfcPaymentPreferenceController.java @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ +package com.android.settings.nfc; + +import android.app.AlertDialog; +import android.app.Dialog; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.RadioButton; + +import com.android.settings.R; +import com.android.settings.core.BasePreferenceController; +import com.android.settings.nfc.PaymentBackend.PaymentAppInfo; +import com.android.settingslib.core.lifecycle.LifecycleObserver; +import com.android.settingslib.core.lifecycle.events.OnStart; +import com.android.settingslib.core.lifecycle.events.OnStop; + +import java.util.List; + +import androidx.preference.Preference; +import androidx.preference.PreferenceScreen; +import androidx.preference.PreferenceViewHolder; + +public class NfcPaymentPreferenceController extends BasePreferenceController implements + PaymentBackend.Callback, View.OnClickListener, NfcPaymentPreference.Listener, + LifecycleObserver, OnStart, OnStop { + + private static final String TAG = "NfcPaymentController"; + + private final NfcPaymentAdapter mAdapter; + private PaymentBackend mPaymentBackend; + private NfcPaymentPreference mPreference; + private ImageView mSettingsButtonView; + + public NfcPaymentPreferenceController(Context context, String key) { + super(context, key); + mAdapter = new NfcPaymentAdapter(context); + } + + public void setPaymentBackend(PaymentBackend backend) { + mPaymentBackend = backend; + } + + @Override + public void onStart() { + if (mPaymentBackend != null) { + mPaymentBackend.registerCallback(this); + } + } + + @Override + public void onStop() { + if (mPaymentBackend != null) { + mPaymentBackend.unregisterCallback(this); + } + } + + @Override + public int getAvailabilityStatus() { + final PackageManager pm = mContext.getPackageManager(); + if (!pm.hasSystemFeature(PackageManager.FEATURE_NFC)) { + return DISABLED_UNSUPPORTED; + } + if (mPaymentBackend == null) { + mPaymentBackend = new PaymentBackend(mContext); + } + final List appInfos = mPaymentBackend.getPaymentAppInfos(); + return (appInfos != null && !appInfos.isEmpty()) + ? AVAILABLE + : DISABLED_UNSUPPORTED; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPreference = (NfcPaymentPreference) screen.findPreference(getPreferenceKey()); + if (mPreference != null) { + mPreference.initialize(this); + } + } + + @Override + public void onBindViewHolder(PreferenceViewHolder view) { + mSettingsButtonView = (ImageView) view.findViewById(R.id.settings_button); + mSettingsButtonView.setOnClickListener(this); + + updateSettingsVisibility(); + } + + @Override + public void updateState(Preference preference) { + final List appInfos = mPaymentBackend.getPaymentAppInfos(); + if (appInfos != null) { + final PaymentAppInfo[] apps = appInfos.toArray(new PaymentAppInfo[appInfos.size()]); + mAdapter.updateApps(apps); + } + super.updateState(preference); + updateSettingsVisibility(); + } + + @Override + public CharSequence getSummary() { + final PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp(); + if (defaultApp != null) { + return defaultApp.label; + } else { + return mContext.getText(R.string.nfc_payment_default_not_set); + } + } + + @Override + public void onPrepareDialogBuilder(AlertDialog.Builder builder, + DialogInterface.OnClickListener listener) { + builder.setSingleChoiceItems(mAdapter, 0, listener); + } + + @Override + public void onPaymentAppsChanged() { + updateState(mPreference); + } + + @Override + public void onClick(View view) { + final PaymentAppInfo defaultAppInfo = mPaymentBackend.getDefaultApp(); + if (defaultAppInfo != null && defaultAppInfo.settingsComponent != null) { + final Intent settingsIntent = new Intent(Intent.ACTION_MAIN); + settingsIntent.setComponent(defaultAppInfo.settingsComponent); + settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + mContext.startActivity(settingsIntent); + } catch (ActivityNotFoundException e) { + Log.e(TAG, "Settings activity not found."); + } + } + } + + private void updateSettingsVisibility() { + if (mSettingsButtonView != null) { + final PaymentAppInfo defaultApp = mPaymentBackend.getDefaultApp(); + if (defaultApp == null || defaultApp.settingsComponent == null) { + mSettingsButtonView.setVisibility(View.GONE); + } else { + mSettingsButtonView.setVisibility(View.VISIBLE); + } + } + } + + private class NfcPaymentAdapter extends BaseAdapter implements + CompoundButton.OnCheckedChangeListener, View.OnClickListener { + private final LayoutInflater mLayoutInflater; + + // Only modified on UI thread + private PaymentAppInfo[] appInfos; + + public NfcPaymentAdapter(Context context) { + mLayoutInflater = (LayoutInflater) context.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + } + + public void updateApps(PaymentAppInfo[] appInfos) { + // Clone app infos, only add those with a banner + this.appInfos = appInfos; + notifyDataSetChanged(); + } + + @Override + public int getCount() { + return (appInfos != null) ? appInfos.length : 0; + } + + @Override + public PaymentAppInfo getItem(int i) { + return appInfos[i]; + } + + @Override + public long getItemId(int i) { + return appInfos[i].componentName.hashCode(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ViewHolder holder; + final PaymentAppInfo appInfo = appInfos[position]; + if (convertView == null) { + convertView = mLayoutInflater.inflate( + R.layout.nfc_payment_option, parent, false); + holder = new ViewHolder(); + holder.imageView = convertView.findViewById(R.id.banner); + holder.radioButton = convertView.findViewById(R.id.button); + convertView.setTag(holder); + } else { + holder = (ViewHolder) convertView.getTag(); + } + holder.imageView.setImageDrawable(appInfo.banner); + holder.imageView.setTag(appInfo); + holder.imageView.setContentDescription(appInfo.label); + holder.imageView.setOnClickListener(this); + + // Prevent checked callback getting called on recycled views + holder.radioButton.setOnCheckedChangeListener(null); + holder.radioButton.setChecked(appInfo.isDefault); + holder.radioButton.setContentDescription(appInfo.label); + holder.radioButton.setOnCheckedChangeListener(this); + holder.radioButton.setTag(appInfo); + return convertView; + } + + private class ViewHolder { + public ImageView imageView; + public RadioButton radioButton; + } + + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + PaymentAppInfo appInfo = (PaymentAppInfo) compoundButton.getTag(); + makeDefault(appInfo); + } + + @Override + public void onClick(View view) { + PaymentAppInfo appInfo = (PaymentAppInfo) view.getTag(); + makeDefault(appInfo); + } + + private void makeDefault(PaymentAppInfo appInfo) { + if (!appInfo.isDefault) { + mPaymentBackend.setDefaultPaymentApp(appInfo.componentName); + } + final Dialog dialog = mPreference.getDialog(); + if (dialog != null) { + dialog.dismiss(); + } + } + } +} \ No newline at end of file diff --git a/src/com/android/settings/nfc/PaymentBackend.java b/src/com/android/settings/nfc/PaymentBackend.java index 91cd96cd0b..67ea6bdf7c 100644 --- a/src/com/android/settings/nfc/PaymentBackend.java +++ b/src/com/android/settings/nfc/PaymentBackend.java @@ -25,7 +25,9 @@ import android.nfc.NfcAdapter; import android.nfc.cardemulation.ApduServiceInfo; import android.nfc.cardemulation.CardEmulation; import android.os.Handler; +import android.os.Looper; import android.os.Message; +import android.os.UserHandle; import android.provider.Settings; import android.provider.Settings.SettingNotFoundException; @@ -57,7 +59,7 @@ public class PaymentBackend { // Fields below only modified on UI thread private ArrayList mAppInfos; private PaymentAppInfo mDefaultAppInfo; - private ArrayList mCallbacks = new ArrayList(); + private ArrayList mCallbacks = new ArrayList<>(); public PaymentBackend(Context context) { mContext = context; @@ -102,7 +104,8 @@ public class PaymentBackend { appInfo.componentName = service.getComponent(); String settingsActivity = service.getSettingsActivityName(); if (settingsActivity != null) { - appInfo.settingsComponent = new ComponentName(appInfo.componentName.getPackageName(), + appInfo.settingsComponent = new ComponentName( + appInfo.componentName.getPackageName(), settingsActivity); } else { appInfo.settingsComponent = null; @@ -162,7 +165,7 @@ public class PaymentBackend { void setForegroundMode(boolean foreground) { Settings.Secure.putInt(mContext.getContentResolver(), - Settings.Secure.NFC_PAYMENT_FOREGROUND, foreground ? 1 : 0) ; + Settings.Secure.NFC_PAYMENT_FOREGROUND, foreground ? 1 : 0); } ComponentName getDefaultPaymentApp() { @@ -182,14 +185,23 @@ public class PaymentBackend { refresh(); } - private final Handler mHandler = new Handler() { + private class SettingsPackageMonitor extends PackageMonitor { + private Handler mHandler; + @Override - public void dispatchMessage(Message msg) { - refresh(); + public void register(Context context, Looper thread, UserHandle user, + boolean externalStorage) { + if (mHandler == null) { + mHandler = new Handler(thread) { + @Override + public void dispatchMessage(Message msg) { + refresh(); + } + }; + } + super.register(context, thread, user, externalStorage); } - }; - private class SettingsPackageMonitor extends PackageMonitor { @Override public void onPackageAdded(String packageName, int uid) { mHandler.obtainMessage().sendToTarget(); @@ -210,4 +222,4 @@ public class PaymentBackend { mHandler.obtainMessage().sendToTarget(); } } -} +} \ No newline at end of file diff --git a/src/com/android/settings/nfc/PaymentSettings.java b/src/com/android/settings/nfc/PaymentSettings.java index e3cf697fd2..8233581458 100644 --- a/src/com/android/settings/nfc/PaymentSettings.java +++ b/src/com/android/settings/nfc/PaymentSettings.java @@ -19,10 +19,8 @@ package com.android.settings.nfc; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.content.res.Resources; import android.os.Bundle; -import androidx.preference.PreferenceManager; -import androidx.preference.PreferenceScreen; +import android.provider.SearchIndexableResource; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -31,24 +29,26 @@ import android.view.ViewGroup; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.settings.R; -import com.android.settings.SettingsPreferenceFragment; +import com.android.settings.dashboard.DashboardFragment; import com.android.settings.search.BaseSearchIndexProvider; -import com.android.settings.search.Indexable; -import com.android.settings.search.SearchIndexableRaw; import com.android.settingslib.search.SearchIndexable; -import java.util.ArrayList; +import java.util.Arrays; import java.util.List; + @SearchIndexable -public class PaymentSettings extends SettingsPreferenceFragment implements Indexable { +public class PaymentSettings extends DashboardFragment { public static final String TAG = "PaymentSettings"; - static final String PAYMENT_KEY = "payment"; - private PaymentBackend mPaymentBackend; @Override + protected String getLogTag() { + return TAG; + } + + @Override public int getMetricsCategory() { return MetricsEvent.NFC_PAYMENT; } @@ -59,24 +59,13 @@ public class PaymentSettings extends SettingsPreferenceFragment implements Index } @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - + public void onAttach(Context context) { + super.onAttach(context); mPaymentBackend = new PaymentBackend(getActivity()); setHasOptionsMenu(true); - final PreferenceScreen screen = getPreferenceScreen(); - - List appInfos = mPaymentBackend.getPaymentAppInfos(); - if (appInfos != null && appInfos.size() > 0) { - NfcPaymentPreference preference = - new NfcPaymentPreference(getPrefContext(), mPaymentBackend); - preference.setKey(PAYMENT_KEY); - screen.addPreference(preference); - NfcForegroundPreference foreground = new NfcForegroundPreference(getPrefContext(), - mPaymentBackend); - screen.addPreference(foreground); - } + use(NfcPaymentPreferenceController.class).setPaymentBackend(mPaymentBackend); + use(NfcForegroundPreferenceController.class).setPaymentBackend(mPaymentBackend); } @Override @@ -111,31 +100,19 @@ public class PaymentSettings extends SettingsPreferenceFragment implements Index } public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = - new BaseSearchIndexProvider() { - @Override - public List getRawDataToIndex(Context context, boolean enabled) { - final List result = new ArrayList(); - final Resources res = context.getResources(); - - // Add fragment title - SearchIndexableRaw data = new SearchIndexableRaw(context); - data.key = PAYMENT_KEY; - data.title = res.getString(R.string.nfc_payment_settings_title); - data.screenTitle = res.getString(R.string.nfc_payment_settings_title); - data.keywords = res.getString(R.string.keywords_payment_settings); - result.add(data); - return result; - } - - @Override - public List getNonIndexableKeys(Context context) { - final List nonVisibleKeys = super.getNonIndexableKeys(context); - final PackageManager pm = context.getPackageManager(); - if (pm.hasSystemFeature(PackageManager.FEATURE_NFC)) { - return nonVisibleKeys; + new BaseSearchIndexProvider() { + @Override + public List getXmlResourcesToIndex(Context context, + boolean enabled) { + final SearchIndexableResource sir = new SearchIndexableResource(context); + sir.xmlResId = R.xml.nfc_payment_settings; + return Arrays.asList(sir); + } + + @Override + protected boolean isPageSearchEnabled(Context context) { + final PackageManager pm = context.getPackageManager(); + return pm.hasSystemFeature(PackageManager.FEATURE_NFC); } - nonVisibleKeys.add(PAYMENT_KEY); - return nonVisibleKeys; - } - }; -} + }; +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java index d8c44a2544..0fb041b124 100644 --- a/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/nfc/AndroidBeamPreferenceControllerTest.java @@ -17,7 +17,6 @@ package com.android.settings.nfc; import static com.google.common.truth.Truth.assertThat; - import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -27,7 +26,6 @@ import android.nfc.NfcManager; import android.os.UserHandle; import android.os.UserManager; import android.provider.Settings; -import androidx.preference.PreferenceScreen; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settingslib.RestrictedLockUtils; @@ -44,6 +42,8 @@ import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; +import androidx.preference.PreferenceScreen; + @RunWith(SettingsRobolectricTestRunner.class) public class AndroidBeamPreferenceControllerTest { diff --git a/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceControllerTest.java new file mode 100644 index 0000000000..b3e857f866 --- /dev/null +++ b/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceControllerTest.java @@ -0,0 +1,158 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.nfc; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.pm.PackageManager; + +import com.android.settings.R; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +import java.util.ArrayList; + +import androidx.preference.DropDownPreference; +import androidx.preference.PreferenceScreen; + +@RunWith(SettingsRobolectricTestRunner.class) +public class NfcForegroundPreferenceControllerTest { + + private static final String PREF_KEY = PaymentSettingsTest.FOREGROUND_KEY; + + @Mock + private PaymentBackend mPaymentBackend; + @Mock + private PreferenceScreen mScreen; + @Mock + private PackageManager mManager; + + private Context mContext; + private DropDownPreference mPreference; + private NfcForegroundPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + when(mContext.getPackageManager()).thenReturn(mManager); + mController = new NfcForegroundPreferenceController(mContext, PREF_KEY); + mPreference = new DropDownPreference(mContext); + when(mScreen.findPreference(PREF_KEY)).thenReturn(mPreference); + } + + @Test + public void getAvailabilityStatus_noNFC_DISABLED() { + when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(false); + + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(NfcForegroundPreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_noPaymentBackend_DISABLED() { + when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true); + + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(NfcForegroundPreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_noPaymentApps_DISABLED() { + when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true); + mController.setPaymentBackend(mPaymentBackend); + when(mPaymentBackend.getPaymentAppInfos()).thenReturn(null); + + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(NfcForegroundPreferenceController.AVAILABLE); + + when(mPaymentBackend.getPaymentAppInfos()).thenReturn(new ArrayList<>()); + + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(NfcForegroundPreferenceController.AVAILABLE); + } + + private void initPaymentApps() { + when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true); + mController.setPaymentBackend(mPaymentBackend); + final ArrayList appInfos = new ArrayList<>(); + appInfos.add(new PaymentBackend.PaymentAppInfo()); + when(mPaymentBackend.getPaymentAppInfos()).thenReturn(appInfos); + } + + @Test + public void getAvailabilityStatus_hasPaymentApps_AVAILABLE() { + initPaymentApps(); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(NfcForegroundPreferenceController.AVAILABLE); + } + + @Test + public void onStart_shouldRegisterCallback() { + mController.setPaymentBackend(mPaymentBackend); + + mController.onStart(); + + verify(mPaymentBackend).registerCallback(mController); + } + + @Test + public void onStop_shouldUnregisterCallback() { + mController.setPaymentBackend(mPaymentBackend); + mController.onStart(); + + mController.onStop(); + + verify(mPaymentBackend).unregisterCallback(mController); + } + + @Test + public void changeOptions_shouldUpdateEntryAndSummary() { + initPaymentApps(); + mController.displayPreference(mScreen); + mController.onPaymentAppsChanged(); + + final CharSequence favorDefault = mContext.getText(R.string.nfc_payment_favor_default); + final CharSequence favorOpen = mContext.getText(R.string.nfc_payment_favor_open); + + assertThat(mPreference.getEntry()).isEqualTo(favorDefault); + assertThat(mPreference.getSummary()).isEqualTo(favorDefault); + + mPreference.setValueIndex(0); + mPreference.callChangeListener(mPreference.getEntryValues()[0]); + verify(mPaymentBackend).setForegroundMode(true); + assertThat(mPreference.getEntry()).isEqualTo(favorOpen); + assertThat(mPreference.getSummary()).isEqualTo(favorOpen); + + mPreference.setValueIndex(1); + mPreference.callChangeListener(mPreference.getEntryValues()[1]); + verify(mPaymentBackend).setForegroundMode(false); + assertThat(mPreference.getEntry()).isEqualTo(favorDefault); + assertThat(mPreference.getSummary()).isEqualTo(favorDefault); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceTest.java b/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceTest.java deleted file mode 100644 index 4d40b12236..0000000000 --- a/tests/robotests/src/com/android/settings/nfc/NfcForegroundPreferenceTest.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.settings.nfc; - -import static com.google.common.truth.Truth.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -import android.content.Context; -import androidx.preference.PreferenceManager; -import androidx.preference.PreferenceScreen; - -import com.android.settings.R; -import com.android.settings.testutils.SettingsRobolectricTestRunner; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.robolectric.RuntimeEnvironment; - -@RunWith(SettingsRobolectricTestRunner.class) -public class NfcForegroundPreferenceTest { - @Mock - private PaymentBackend mPaymentBackend; - - private Context mContext; - private PreferenceScreen mScreen; - private NfcForegroundPreference mPreference; - - @Before - public void setUp() { - MockitoAnnotations.initMocks(this); - mContext = RuntimeEnvironment.application; - mScreen = spy(new PreferenceScreen(mContext, null)); - when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); - when(mPaymentBackend.isForegroundMode()).thenReturn(false); - mPreference = new NfcForegroundPreference(mContext, mPaymentBackend); - mScreen.addPreference(mPreference); - } - - @Test - public void testTogglingMode() { - String nfc_payment_favor_default = mContext.getString(R.string.nfc_payment_favor_default); - String nfc_payment_favor_open = mContext.getString(R.string.nfc_payment_favor_open); - - assertThat(mPreference.getEntry()).isEqualTo(nfc_payment_favor_default); - assertThat(mPreference.getSummary()).isEqualTo(nfc_payment_favor_default); - - mPreference.setValueIndex(0); - mPreference.callChangeListener(mPreference.getEntryValues()[0]); - verify(mPaymentBackend).setForegroundMode(true); - assertThat(mPreference.getEntry()).isEqualTo(nfc_payment_favor_open); - assertThat(mPreference.getSummary()).isEqualTo(nfc_payment_favor_open); - - mPreference.setValueIndex(1); - mPreference.callChangeListener(mPreference.getEntryValues()[1]); - verify(mPaymentBackend).setForegroundMode(false); - assertThat(mPreference.getEntry()).isEqualTo(nfc_payment_favor_default); - assertThat(mPreference.getSummary()).isEqualTo(nfc_payment_favor_default); - } -} diff --git a/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java new file mode 100644 index 0000000000..a23822f74b --- /dev/null +++ b/tests/robotests/src/com/android/settings/nfc/NfcPaymentPreferenceControllerTest.java @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.nfc; + +import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.content.Context; +import android.content.pm.PackageManager; + +import com.android.settings.R; +import com.android.settings.nfc.PaymentBackend.PaymentAppInfo; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; + +import java.util.ArrayList; + +import androidx.preference.PreferenceScreen; + +@RunWith(SettingsRobolectricTestRunner.class) +public class NfcPaymentPreferenceControllerTest { + + private static final String PREF_KEY = PaymentSettingsTest.PAYMENT_KEY; + + @Mock + private PaymentBackend mPaymentBackend; + @Mock + private PreferenceScreen mScreen; + @Mock + private PackageManager mManager; + + private Context mContext; + private NfcPaymentPreference mPreference; + private NfcPaymentPreferenceController mController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + mContext = spy(RuntimeEnvironment.application); + when(mContext.getPackageManager()).thenReturn(mManager); + mController = new NfcPaymentPreferenceController(mContext, PREF_KEY); + mPreference = spy(new NfcPaymentPreference(mContext, null)); + when(mScreen.findPreference(PREF_KEY)).thenReturn(mPreference); + } + + @Test + public void getAvailabilityStatus_noNFC_DISABLED() { + when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(false); + + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(NfcPaymentPreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_noPaymentApps_DISABLED() { + when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true); + mController.setPaymentBackend(mPaymentBackend); + when(mPaymentBackend.getPaymentAppInfos()).thenReturn(null); + + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(NfcPaymentPreferenceController.AVAILABLE); + + when(mPaymentBackend.getPaymentAppInfos()).thenReturn(new ArrayList<>()); + + assertThat(mController.getAvailabilityStatus()) + .isNotEqualTo(NfcPaymentPreferenceController.AVAILABLE); + } + + @Test + public void getAvailabilityStatus_hasPaymentApps_AVAILABLE() { + when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true); + mController.setPaymentBackend(mPaymentBackend); + final ArrayList appInfos = new ArrayList<>(); + appInfos.add(new PaymentAppInfo()); + when(mPaymentBackend.getPaymentAppInfos()).thenReturn(appInfos); + + assertThat(mController.getAvailabilityStatus()) + .isEqualTo(NfcPaymentPreferenceController.AVAILABLE); + } + + @Test + public void onStart_shouldRegisterCallback() { + mController.setPaymentBackend(mPaymentBackend); + + mController.onStart(); + + verify(mPaymentBackend).registerCallback(mController); + } + + @Test + public void onStop_shouldUnregisterCallback() { + mController.setPaymentBackend(mPaymentBackend); + mController.onStart(); + + mController.onStop(); + + verify(mPaymentBackend).unregisterCallback(mController); + } + + @Test + public void displayPreference_shouldInitialize() { + mController.setPaymentBackend(mPaymentBackend); + + mController.displayPreference(mScreen); + + verify(mPreference).initialize(mController); + } + + @Test + public void onPaymentAppsChanged_shouldRefreshSummary() { + mController.setPaymentBackend(mPaymentBackend); + mController.displayPreference(mScreen); + when(mPaymentBackend.getDefaultApp()).thenReturn(null); + + mController.onPaymentAppsChanged(); + + assertThat(mPreference.getSummary()) + .isEqualTo(mContext.getText(R.string.nfc_payment_default_not_set)); + + final PaymentAppInfo appInfo = new PaymentAppInfo(); + appInfo.label = "test label"; + when(mPaymentBackend.getDefaultApp()).thenReturn(appInfo); + + mController.onPaymentAppsChanged(); + + assertThat(mPreference.getSummary()).isEqualTo(appInfo.label); + } +} \ No newline at end of file diff --git a/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java index ac6006f2c7..9ddcc6917e 100644 --- a/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java +++ b/tests/robotests/src/com/android/settings/nfc/NfcPreferenceControllerTest.java @@ -17,7 +17,6 @@ package com.android.settings.nfc; import static com.google.common.truth.Truth.assertThat; - import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; @@ -26,8 +25,6 @@ import android.nfc.NfcAdapter; import android.nfc.NfcManager; import android.os.UserManager; import android.provider.Settings; -import androidx.preference.SwitchPreference; -import androidx.preference.PreferenceScreen; import com.android.settings.testutils.SettingsRobolectricTestRunner; @@ -42,10 +39,13 @@ import org.robolectric.util.ReflectionHelpers; import java.util.ArrayList; import java.util.List; +import androidx.preference.PreferenceScreen; +import androidx.preference.SwitchPreference; + @RunWith(SettingsRobolectricTestRunner.class) public class NfcPreferenceControllerTest { - Context mContext; + @Mock private NfcAdapter mNfcAdapter; @Mock @@ -55,6 +55,7 @@ public class NfcPreferenceControllerTest { @Mock private PreferenceScreen mScreen; + private Context mContext; private SwitchPreference mNfcPreference; private NfcPreferenceController mNfcController; diff --git a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java index 6feed46dc1..0268711549 100644 --- a/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java +++ b/tests/robotests/src/com/android/settings/nfc/PaymentSettingsTest.java @@ -18,6 +18,7 @@ package com.android.settings.nfc; import static com.google.common.truth.Truth.assertThat; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; @@ -30,42 +31,66 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import java.util.ArrayList; import java.util.List; @RunWith(SettingsRobolectricTestRunner.class) +@Config(shadows = PaymentSettingsTest.ShadowPaymentBackend.class) public class PaymentSettingsTest { - @Mock - Context mContext; + static final String PAYMENT_KEY = "nfc_payment"; + static final String FOREGROUND_KEY = "nfc_foreground"; + + private Context mContext; @Mock private PackageManager mManager; - private PaymentSettings mFragment; - @Before public void setUp() { MockitoAnnotations.initMocks(this); - mFragment = new PaymentSettings(); + mContext = spy(RuntimeEnvironment.application); when(mContext.getPackageManager()).thenReturn(mManager); } @Test - public void testNonIndexableKey_NoNFC_KeyAdded() { + public void getNonIndexableKey_NoNFC_AllKeysAdded() { when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(false); final List niks = - PaymentSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); - assertThat(niks).contains(PaymentSettings.PAYMENT_KEY); + PaymentSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); + + assertThat(niks).contains(PAYMENT_KEY); + assertThat(niks).contains(FOREGROUND_KEY); } @Test - public void testNonIndexableKey_NFC_NoKeyAdded() { + public void getNonIndexableKey_NFC_ForegroundKeyAdded() { when(mManager.hasSystemFeature(PackageManager.FEATURE_NFC)).thenReturn(true); final List niks = - PaymentSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); - assertThat(niks).isEmpty(); + PaymentSettings.SEARCH_INDEX_DATA_PROVIDER.getNonIndexableKeys(mContext); + + assertThat(niks).contains(FOREGROUND_KEY); + } + + @Implements(PaymentBackend.class) + public static class ShadowPaymentBackend { + private ArrayList mAppInfos; + + public void __constructor__(Context context) { + mAppInfos = new ArrayList<>(); + mAppInfos.add(new PaymentBackend.PaymentAppInfo()); + } + + @Implementation + public List getPaymentAppInfos() { + return mAppInfos; + } } } \ No newline at end of file -- 2.11.0