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