blob: 5f3a10ad05cf7763f567190bce4e4e73300beaa3 [file] [log] [blame]
package com.android.cts.verifier.nfc.hce;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NfcAdapter;
import android.nfc.cardemulation.CardEmulation;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;
@TargetApi(19)
public abstract class BaseEmulatorActivity extends PassFailButtons.Activity {
static final String TAG = "BaseEmulatorActivity";
NfcAdapter mAdapter;
CardEmulation mCardEmulation;
ProgressDialog mSetupDialog;
ComponentName mMakingDefault;
final ArrayList<ComponentName> SERVICES = new ArrayList<ComponentName>(
Arrays.asList(
PaymentService1.COMPONENT,
PaymentService2.COMPONENT,
TransportService1.COMPONENT,
TransportService2.COMPONENT,
AccessService.COMPONENT,
ThroughputService.COMPONENT,
OffHostService.COMPONENT,
PaymentServiceDynamicAids.COMPONENT,
PrefixPaymentService1.COMPONENT,
PrefixPaymentService2.COMPONENT,
PrefixTransportService1.COMPONENT,
PrefixTransportService2.COMPONENT,
PrefixAccessService.COMPONENT,
LargeNumAidsService.COMPONENT)
);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = NfcAdapter.getDefaultAdapter(this);
mCardEmulation = CardEmulation.getInstance(mAdapter);
}
abstract void onServicesSetup(boolean result);
abstract void onApduSequenceComplete(ComponentName component, long duration);
void onApduSequenceError() {
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(HceUtils.ACTION_APDU_SEQUENCE_COMPLETE);
registerReceiver(mReceiver, filter);
}
final void setupServices(Context context, ComponentName... components) {
mSetupDialog = new ProgressDialog(context);
new SetupServicesTask().execute(components);
}
final boolean makePaymentDefault(final ComponentName defaultComponent, int stringId) {
if (!mCardEmulation.isDefaultServiceForCategory(defaultComponent,
CardEmulation.CATEGORY_PAYMENT)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Note");
builder.setMessage(stringId);
mMakingDefault = defaultComponent;
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent changeDefault = new Intent(CardEmulation.ACTION_CHANGE_DEFAULT);
changeDefault.putExtra(CardEmulation.EXTRA_CATEGORY, CardEmulation.CATEGORY_PAYMENT);
changeDefault.putExtra(CardEmulation.EXTRA_SERVICE_COMPONENT, defaultComponent);
startActivityForResult(changeDefault, 0);
}
});
builder.show();
return true;
} else {
return false;
}
}
final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (HceUtils.ACTION_APDU_SEQUENCE_COMPLETE.equals(action)) {
// Get component whose sequence was completed
ComponentName component = intent.getParcelableExtra(HceUtils.EXTRA_COMPONENT);
long duration = intent.getLongExtra(HceUtils.EXTRA_DURATION, 0);
if (component != null) {
onApduSequenceComplete(component, duration);
}
} else if (HceUtils.ACTION_APDU_SEQUENCE_ERROR.equals(action)) {
onApduSequenceError();
}
}
};
private class SetupServicesTask extends AsyncTask<ComponentName, Void, Boolean> {
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
mSetupDialog.dismiss();
onServicesSetup(result);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
mSetupDialog.setTitle(R.string.nfc_hce_please_wait);
mSetupDialog.setMessage(getString(R.string.nfc_hce_setting_up));
mSetupDialog.setCancelable(false);
mSetupDialog.show();
}
@Override
protected Boolean doInBackground(ComponentName... components) {
List<ComponentName> enableComponents = Arrays.asList(components);
for (ComponentName component : SERVICES) {
if (enableComponents.contains(component)) {
Log.d(TAG, "Enabling component " + component);
HceUtils.enableComponent(getPackageManager(), component);
} else {
Log.d(TAG, "Disabling component " + component);
HceUtils.disableComponent(getPackageManager(), component);
}
}
// This is a trick to invalidate the HCE cache and avoid
// having to wait for PackageManager broadcasts to NFCService.
ComponentName bogusComponent = new ComponentName("com.android.cts.verifier",
"com.android.cts.verifier.nfc.hce.BogusService");
mCardEmulation.isDefaultServiceForCategory(bogusComponent,
CardEmulation.CATEGORY_PAYMENT);
return true;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
// Verify it's default
if (!mCardEmulation.isDefaultServiceForCategory(mMakingDefault,
CardEmulation.CATEGORY_PAYMENT)) {
// Popup dialog-box
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Test failed.");
builder.setMessage("The service was not made the default service according " +
"to CardEmulation.getDefaultServiceForCategory(), verify the make " +
"default implementation is correct.");
builder.setPositiveButton("OK", null);
builder.show();
onPaymentDefaultResult(mMakingDefault, false);
} else {
onPaymentDefaultResult(mMakingDefault, true);
}
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Test failed.");
builder.setMessage("You clicked no.");
builder.setPositiveButton("OK", null);
builder.show();
onPaymentDefaultResult(mMakingDefault, false);
}
}
void onPaymentDefaultResult(ComponentName component, boolean success) {
};
}