• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.android.cts.verifier.nfc.hce;
2 
3 import static android.content.Context.RECEIVER_EXPORTED;
4 
5 import android.annotation.TargetApi;
6 import android.app.Activity;
7 import android.app.AlertDialog;
8 import android.app.ProgressDialog;
9 import android.content.BroadcastReceiver;
10 import android.content.ComponentName;
11 import android.content.Context;
12 import android.content.DialogInterface;
13 import android.content.Intent;
14 import android.content.IntentFilter;
15 import android.nfc.NfcAdapter;
16 import android.nfc.cardemulation.CardEmulation;
17 import android.os.AsyncTask;
18 import android.os.Bundle;
19 import android.os.UserHandle;
20 import android.util.Log;
21 
22 import com.android.cts.verifier.PassFailButtons;
23 import com.android.cts.verifier.R;
24 
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.List;
28 
29 @TargetApi(19)
30 public abstract class BaseEmulatorActivity extends PassFailButtons.Activity {
31     static final String TAG = "BaseEmulatorActivity";
32     NfcAdapter mAdapter;
33     CardEmulation mCardEmulation;
34     ProgressDialog mSetupDialog;
35     ComponentName mMakingDefault;
36 
37     final ArrayList<ComponentName> SERVICES = new ArrayList<ComponentName>(
38             Arrays.asList(
39             PaymentService1.COMPONENT,
40             PaymentService2.COMPONENT,
41             TransportService1.COMPONENT,
42             TransportService2.COMPONENT,
43             AccessService.COMPONENT,
44             ThroughputService.COMPONENT,
45             OffHostService.COMPONENT,
46             PaymentServiceDynamicAids.COMPONENT,
47             PrefixPaymentService1.COMPONENT,
48             PrefixPaymentService2.COMPONENT,
49             PrefixTransportService1.COMPONENT,
50             PrefixTransportService2.COMPONENT,
51             PrefixAccessService.COMPONENT,
52             LargeNumAidsService.COMPONENT,
53             ScreenOnOnlyOffHostService.COMPONENT,
54             ScreenOffPaymentService.COMPONENT)
55     );
56 
57     @Override
onCreate(Bundle savedInstanceState)58     protected void onCreate(Bundle savedInstanceState) {
59         super.onCreate(savedInstanceState);
60 
61         mAdapter = NfcAdapter.getDefaultAdapter(this);
62         mCardEmulation = CardEmulation.getInstance(mAdapter);
63         IntentFilter filter = new IntentFilter(HceUtils.ACTION_APDU_SEQUENCE_COMPLETE);
64         registerReceiver(mReceiver, filter, RECEIVER_EXPORTED);
65     }
66 
onServicesSetup(boolean result)67     abstract void onServicesSetup(boolean result);
68 
onApduSequenceComplete(ComponentName component, long duration)69     abstract void onApduSequenceComplete(ComponentName component, long duration);
70 
onApduSequenceError()71     void onApduSequenceError() {
72 
73     }
74 
75     @Override
onStop()76     protected void onStop() {
77         super.onStop();
78     }
79 
80     @Override
onDestroy()81     protected void onDestroy() {
82         super.onDestroy();
83         unregisterReceiver(mReceiver);
84     }
85 
86     @Override
onPause()87     protected void onPause() {
88         super.onPause();
89     }
90 
91     @Override
onResume()92     protected void onResume() {
93         super.onResume();
94     }
95 
setupServices(Context context, ComponentName... components)96     final void setupServices(Context context, ComponentName... components) {
97         mSetupDialog = new ProgressDialog(context);
98         new SetupServicesTask().execute(components);
99     }
100 
makePaymentDefault(final ComponentName defaultComponent, int stringId)101     final boolean makePaymentDefault(final ComponentName defaultComponent, int stringId) {
102         if (!mCardEmulation.isDefaultServiceForCategory(defaultComponent,
103                 CardEmulation.CATEGORY_PAYMENT)) {
104             AlertDialog.Builder builder = new AlertDialog.Builder(this);
105             builder.setTitle("Note");
106             builder.setMessage(stringId);
107             mMakingDefault = defaultComponent;
108             builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
109                 @Override
110                 public void onClick(DialogInterface dialog, int which) {
111                     Intent changeDefault = new Intent(CardEmulation.ACTION_CHANGE_DEFAULT);
112                     changeDefault.putExtra(CardEmulation.EXTRA_CATEGORY,
113                             CardEmulation.CATEGORY_PAYMENT);
114                     changeDefault.putExtra(CardEmulation.EXTRA_SERVICE_COMPONENT, defaultComponent);
115                     changeDefault.putExtra(Intent.EXTRA_USER,
116                             UserHandle.getUserHandleForUid(getApplicationInfo().uid));
117                     startActivityForResult(changeDefault, 0);
118                 }
119             });
120             builder.show();
121             return true;
122         } else {
123             return false;
124         }
125     }
126 
127     final BroadcastReceiver mReceiver = new BroadcastReceiver() {
128         @Override
129         public void onReceive(Context context, Intent intent) {
130             String action = intent.getAction();
131             if (HceUtils.ACTION_APDU_SEQUENCE_COMPLETE.equals(action)) {
132                 // Get component whose sequence was completed
133                 ComponentName component = intent.getParcelableExtra(HceUtils.EXTRA_COMPONENT);
134                 long duration = intent.getLongExtra(HceUtils.EXTRA_DURATION, 0);
135                 if (component != null) {
136                     onApduSequenceComplete(component, duration);
137                 }
138             } else if (HceUtils.ACTION_APDU_SEQUENCE_ERROR.equals(action)) {
139                 onApduSequenceError();
140             }
141         }
142     };
143 
144     private class SetupServicesTask extends AsyncTask<ComponentName, Void, Boolean> {
145         @Override
onPostExecute(Boolean result)146         protected void onPostExecute(Boolean result) {
147             super.onPostExecute(result);
148             mSetupDialog.dismiss();
149             onServicesSetup(result);
150         }
151 
152         @Override
onPreExecute()153         protected void onPreExecute() {
154             super.onPreExecute();
155             mSetupDialog.setTitle(R.string.nfc_hce_please_wait);
156             mSetupDialog.setMessage(getString(R.string.nfc_hce_setting_up));
157             mSetupDialog.setCancelable(false);
158             mSetupDialog.show();
159         }
160 
161         @Override
doInBackground(ComponentName... components)162         protected Boolean doInBackground(ComponentName... components) {
163             List<ComponentName> enableComponents = Arrays.asList(components);
164             for (ComponentName component : SERVICES) {
165                 if (enableComponents.contains(component)) {
166                     Log.d(TAG, "Enabling component " + component);
167                     HceUtils.enableComponent(getPackageManager(), component);
168                 } else {
169                     Log.d(TAG, "Disabling component " + component);
170                     HceUtils.disableComponent(getPackageManager(), component);
171                 }
172             }
173             // This is a trick to invalidate the HCE cache and avoid
174             // having to wait for PackageManager broadcasts to NFCService.
175             ComponentName bogusComponent = new ComponentName("com.android.cts.verifier",
176                     "com.android.cts.verifier.nfc.hce.BogusService");
177             mCardEmulation.isDefaultServiceForCategory(bogusComponent,
178                     CardEmulation.CATEGORY_PAYMENT);
179             return true;
180         }
181     }
182 
183     @Override
onActivityResult(int requestCode, int resultCode, Intent data)184     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
185         super.onActivityResult(requestCode, resultCode, data);
186         if (resultCode == Activity.RESULT_OK) {
187             // Verify it's default
188             if (!mCardEmulation.isDefaultServiceForCategory(mMakingDefault,
189                     CardEmulation.CATEGORY_PAYMENT)) {
190                 // Popup dialog-box
191                 AlertDialog.Builder builder = new AlertDialog.Builder(this);
192                 builder.setTitle("Test failed.");
193                 builder.setMessage("The service was not made the default service according " +
194                         "to CardEmulation.getDefaultServiceForCategory(), verify the make " +
195                         "default implementation is correct.");
196                 builder.setPositiveButton("OK", null);
197                 builder.show();
198                 onPaymentDefaultResult(mMakingDefault, false);
199             } else {
200                 onPaymentDefaultResult(mMakingDefault, true);
201             }
202         } else {
203             AlertDialog.Builder builder = new AlertDialog.Builder(this);
204             builder.setTitle("Test failed.");
205             builder.setMessage("You clicked no.");
206             builder.setPositiveButton("OK", null);
207             builder.show();
208             onPaymentDefaultResult(mMakingDefault, false);
209         }
210     }
211 
onPaymentDefaultResult(ComponentName component, boolean success)212     void onPaymentDefaultResult(ComponentName component, boolean success) {
213 
214     };
215 }
216