diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/nfc/NfcService.java | 22 | ||||
-rw-r--r-- | src/com/android/nfc/RoutingTableParser.java | 284 | ||||
-rw-r--r-- | src/com/android/nfc/beam/BeamReceiveService.java | 3 | ||||
-rw-r--r-- | src/com/android/nfc/beam/BeamSendService.java | 3 | ||||
-rw-r--r-- | src/com/android/nfc/beam/SendUi.java | 2 | ||||
-rw-r--r-- | src/com/android/nfc/cardemulation/AppChooserActivity.java | 62 | ||||
-rw-r--r-- | src/com/android/nfc/cardemulation/CardEmulationManager.java | 27 | ||||
-rw-r--r-- | src/com/android/nfc/cardemulation/TapAgainDialog.java | 39 |
8 files changed, 293 insertions, 149 deletions
diff --git a/src/com/android/nfc/NfcService.java b/src/com/android/nfc/NfcService.java index 2ec29477..60f4f85b 100644 --- a/src/com/android/nfc/NfcService.java +++ b/src/com/android/nfc/NfcService.java @@ -77,6 +77,7 @@ import android.os.UserManager; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings; +import android.provider.Settings.SettingNotFoundException; import android.se.omapi.ISecureElementService; import android.service.vr.IVrManager; import android.service.vr.IVrStateCallbacks; @@ -536,6 +537,7 @@ public class NfcService implements DeviceHostListener { filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_USER_PRESENT); filter.addAction(Intent.ACTION_USER_SWITCHED); + filter.addAction(Intent.ACTION_USER_ADDED); mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); // Listen for work profile adds or removes. @@ -775,6 +777,7 @@ public class NfcService implements DeviceHostListener { mPrefsEditor.putBoolean(PREF_FIRST_BOOT, false); mPrefsEditor.apply(); mDeviceHost.factoryReset(); + setPaymentForegroundPreference(mUserId); } Log.d(TAG, "checking on firmware download"); if (mPrefs.getBoolean(PREF_NFC_ON, NFC_ON_DEFAULT)) { @@ -889,6 +892,7 @@ public class NfcService implements DeviceHostListener { filter.addAction(Intent.ACTION_SCREEN_ON); filter.addAction(Intent.ACTION_USER_PRESENT); filter.addAction(Intent.ACTION_USER_SWITCHED); + filter.addAction(Intent.ACTION_USER_ADDED); mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); mIsRecovering = false; } @@ -3243,6 +3247,9 @@ public class NfcService implements DeviceHostListener { if (screenState != mScreenState) { new ApplyRoutingTask().execute(Integer.valueOf(screenState)); } + } else if (action.equals(Intent.ACTION_USER_ADDED)) { + int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); + setPaymentForegroundPreference(userId); } } }; @@ -3267,6 +3274,7 @@ public class NfcService implements DeviceHostListener { action.equals(Intent.ACTION_MANAGED_PROFILE_REMOVED) || action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) { mCardEmulationManager.onManagedProfileChanged(); + setPaymentForegroundPreference(user.getIdentifier()); } } }; @@ -3313,6 +3321,20 @@ public class NfcService implements DeviceHostListener { } }; + private void setPaymentForegroundPreference(int user) { + try { + // Check whether the Settings.Secure.NFC_PAYMENT_FOREGROUND exists or not. + Settings.Secure.getIntForUser(mContext.getContentResolver(), + Settings.Secure.NFC_PAYMENT_FOREGROUND, user); + } catch (SettingNotFoundException e) { + boolean foregroundPreference = + mContext.getResources().getBoolean(R.bool.payment_foreground_preference); + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.NFC_PAYMENT_FOREGROUND, foregroundPreference ? 1 : 0, user); + Log.d(TAG, "Set NFC_PAYMENT_FOREGROUND preference:" + foregroundPreference); + } + } + /** * for debugging only - no i18n */ diff --git a/src/com/android/nfc/RoutingTableParser.java b/src/com/android/nfc/RoutingTableParser.java index d2c7f1ad..9174c244 100644 --- a/src/com/android/nfc/RoutingTableParser.java +++ b/src/com/android/nfc/RoutingTableParser.java @@ -17,10 +17,12 @@ package com.android.nfc; import android.os.SystemProperties; -import java.util.Locale; import android.util.Log; import java.io.PrintWriter; +import java.util.Arrays; +import java.util.Locale; +import java.util.Vector; /** * Parse the Routing Table from the last backup lmrt cmd and dump it with a clear typography @@ -28,57 +30,92 @@ import java.io.PrintWriter; public class RoutingTableParser { static final boolean DBG = SystemProperties.getBoolean("persist.nfc.debug_enabled", false); private static final String TAG = "RoutingTableParser"; + private static int sRoutingTableSize = 0; + private static int sRoutingTableMaxSize = 0; + private static Vector<RoutingEntryInfo> sRoutingTable = new Vector<RoutingEntryInfo>(0); + + // Entry types + static final byte TYPE_TECHNOLOGY = 0; + static final byte TYPE_PROTOCOL = 1; + static final byte TYPE_AID = 2; + static final byte TYPE_SYSTEMCODE = 3; + static final byte TYPE_UNSUPPORTED = 4; + + // Commit status + static final int STATS_HOST_OK = 0; + static final int STATS_OFFHOST_OK = 1; + static final int STATS_NOT_FOUND = 2; - private String getTechStr(int value) { + private interface GetEntryStr { + String getEntryStr(byte[] entry); + } + + private GetEntryStr[] mGetEntryStrFuncs = new GetEntryStr[] { + new GetEntryStr() { public String getEntryStr(byte[] entry) { + return getTechStr(entry); } }, + new GetEntryStr() { public String getEntryStr(byte[] entry) { + return getProtoStr(entry); } }, + new GetEntryStr() { public String getEntryStr(byte[] entry) { + return getAidStr(entry); } }, + new GetEntryStr() { public String getEntryStr(byte[] entry) { + return getSystemCodeStr(entry); } }, + }; + + private String getTechStr(byte[] tech) { String[] tech_mask_list = { "TECHNOLOGY_A", "TECHNOLOGY_B", "TECHNOLOGY_F", "TECHNOLOGY_V" }; - if (value > tech_mask_list.length) { + if (tech[0] > tech_mask_list.length) { return "UNSUPPORTED_TECH"; } - return tech_mask_list[value]; + return tech_mask_list[tech[0]]; } - private String getProtoStr(int value) { + private String getProtoStr(byte[] proto) { String[] proto_mask_list = { "PROTOCOL_UNDETERMINED", "PROTOCOL_T1T", "PROTOCOL_T2T", "PROTOCOL_T3T", "PROTOCOL_ISO_DEP", "PROTOCOL_NFC_DEP", "PROTOCOL_T5T", "PROTOCOL_NDEF" }; - if (value > proto_mask_list.length) { + if (proto[0] > proto_mask_list.length) { return "UNSUPPORTED_PROTO"; } - return proto_mask_list[value]; + return proto_mask_list[proto[0]]; } - private String getAidStr(byte[] rt, int offset, int aidLen) { - String Aid = ""; - for (int i = 0; i < aidLen; i++) { - Aid += String.format("%02X", rt[offset + i]); + private String getAidStr(byte[] aid) { + String aidStr = ""; + + for (byte b : aid) { + aidStr += String.format("%02X", b); } - if (Aid.length() == 0) { + if (aidStr.length() == 0) { return "Empty_AID"; } - return "AID_" + Aid; + return "AID_" + aidStr; } - private String getSystemCodeStr(byte[] rt, int offset, int scLen) { - String SystemCode = ""; - for (int i = 0; i < scLen; i++) { - SystemCode += String.format("%02X", rt[offset + i]); + private String getSystemCodeStr(byte[] sc) { + String systemCodeStr = ""; + for (byte b : sc) { + systemCodeStr += String.format("%02X", b); } - return "SYSTEMCODE_" + SystemCode; + return "SYSTEMCODE_" + systemCodeStr; } - private String getBlockCtrlStr(int mask) { + private String getBlockCtrlStr(byte mask) { if ((mask & 0x40) != 0) { return "True"; } return "False"; } - private String getPrefixSubsetStr(int mask) { + private String getPrefixSubsetStr(byte mask, byte type) { + if (type != TYPE_AID) { + return ""; + } + String prefix_subset_str = ""; if ((mask & 0x10) != 0) { prefix_subset_str += "Prefix "; @@ -98,84 +135,172 @@ public class RoutingTableParser { return String.format(fmt, entry, eeId, pwrState, blkCtrl, extra); } - private void dumpTechEntry(byte[] rt, int rtSize, PrintWriter pw, int offset) { - if (offset + 4 >= rtSize) return; + private class RoutingEntryInfo { + public final byte mQualifier; + public final byte mType; + public final byte mNfceeId; + public final byte mPowerState; + public final byte[] mEntry; + + private RoutingEntryInfo(byte qualifier, byte type, byte eeId, byte pwrState, + byte[] entry) { + mQualifier = qualifier; + mType = type; + mNfceeId = eeId; + mPowerState = pwrState; + mEntry = entry; + } - String blkCtrl = getBlockCtrlStr(rt[offset] & 0xF0); - String eeId = String.format("0x%02X", rt[offset + 2]); - String pwrState = String.format("0x%02X", rt[offset + 3]); - String entry = getTechStr(rt[offset + 4]); + private void dump(PrintWriter pw) { + String blkCtrl = getBlockCtrlStr(mQualifier); + String eeId = String.format("0x%02X", mNfceeId); + String pwrState = String.format("0x%02X", mPowerState); + String entry = mGetEntryStrFuncs[mType].getEntryStr(mEntry); + String extra = getPrefixSubsetStr(mQualifier, mType); - pw.println(formatRow(entry, eeId, pwrState, blkCtrl, "")); + pw.println(formatRow(entry, eeId, pwrState, blkCtrl, extra)); + } } - private void dumpProtoEntry(byte[] rt, int rtSize, PrintWriter pw, int offset) { - if (offset + 4 >= rtSize) return; + private boolean validateEntryInfo(byte type, byte[] entry) { + switch(type) { + case TYPE_TECHNOLOGY: + if (entry.length != 1) return false; + break; + case TYPE_PROTOCOL: + if (entry.length != 1) return false; + break; + case TYPE_AID: + if (entry.length > 16) return false; + break; + case TYPE_SYSTEMCODE: + if (entry.length != 2) return false; + break; + default: + return false; + } + return true; + } - String blkCtrl = getBlockCtrlStr(rt[offset] & 0xF0); - String eeId = String.format("0x%02X", rt[offset + 2]); - String pwrState = String.format("0x%02X", rt[offset + 3]); - String entry = getProtoStr(rt[offset + 4]); + /** + * Check commit status by inputting type and entry + */ + public int getCommitStatus(byte type, byte[] entry) { + if (!validateEntryInfo(type, entry)) return STATS_NOT_FOUND; - pw.println(formatRow(entry, eeId, pwrState, blkCtrl, "")); + for (RoutingEntryInfo routingEntry : sRoutingTable) { + if (routingEntry.mType != type) { + continue; + } + if (Arrays.equals(routingEntry.mEntry, entry)) { + return routingEntry.mNfceeId == 0x00 ? STATS_HOST_OK : STATS_OFFHOST_OK; + } + if (routingEntry.mType != TYPE_AID) { + continue; + } + if ((routingEntry.mQualifier & 0x10) != 0 + && entry.length > routingEntry.mEntry.length) { + int ptr = 0; + while (entry[ptr] == routingEntry.mEntry[ptr]) { + ptr += 1; + } + if (ptr == routingEntry.mEntry.length) { + return routingEntry.mNfceeId == 0x00 ? STATS_HOST_OK : STATS_OFFHOST_OK; + } + } + if ((routingEntry.mQualifier & 0x20) != 0 + && entry.length < routingEntry.mEntry.length) { + int ptr = 0; + while (entry[ptr] == routingEntry.mEntry[ptr]) { + ptr += 1; + } + if (ptr == entry.length) { + return routingEntry.mNfceeId == 0x00 ? STATS_HOST_OK : STATS_OFFHOST_OK; + } + } + } + return STATS_NOT_FOUND; } - private void dumpAidEntry(byte[] rt, int rtSize, PrintWriter pw, int offset) { - if (offset + 4 + rt[offset + 1] - 2 >= rtSize) return; + private void addRoutingEntry(byte[] rt, int offset) { + if (offset + 1 >= rt.length) return; + int valueLength = rt[offset + 1]; + + // Qualifier-Type(1 byte) + Length(1 byte) + Value(valueLength bytes) + if (offset + 2 + valueLength > rt.length) return; - String blkCtrl = getBlockCtrlStr(rt[offset] & 0xF0); - String extra = getPrefixSubsetStr(rt[offset] & 0xF0); - String eeId = String.format("0x%02X", rt[offset + 2]); - String pwrState = String.format("0x%02X", rt[offset + 3]); - String entry = getAidStr(rt, offset + 4, rt[offset + 1] - 2); + byte qualifier = (byte) (rt[offset] & 0xF0); + byte type = (byte) (rt[offset] & 0x0F); + byte eeId = rt[offset + 2]; + byte pwrState = rt[offset + 3]; + byte[] entry = new byte[valueLength - 2]; + for (int i = 0; i < valueLength - 2; i++) { + entry[i] = rt[offset + 4 + i]; + } - pw.println(formatRow(entry, eeId, pwrState, blkCtrl, extra)); + if (type == TYPE_SYSTEMCODE && (entry.length & 1) == 0 && entry.length <= 64) { + for (int i = 0; i < entry.length; i += 2) { + byte[] sc_entry = {entry[i], entry[i + 1]}; + sRoutingTable.add(new RoutingEntryInfo(qualifier, type, eeId, pwrState, sc_entry)); + } + } else if (validateEntryInfo(type, entry)) { + sRoutingTable.add(new RoutingEntryInfo(qualifier, type, eeId, pwrState, entry)); + } } - private void dumpSystemEntry(byte[] rt, int rtSize, PrintWriter pw, int offset) { - if (offset + 4 + rt[offset + 1] - 2 >= rtSize) return; + /** + * Parse the raw data of routing table + */ + public void parse(byte[] rt) { + int offset = 0; + + logRoutingTableRawData(rt); + + sRoutingTable.clear(); + while (offset < rt.length) { + byte type = (byte) (rt[offset] & 0x0F); + if (type >= TYPE_UNSUPPORTED) { + // Unrecognizable entry type + Log.e(TAG, String.format("Unrecognizable entry type: 0x%02X, stop parsing", type)); + return; + } + if (offset + 1 >= rt.length) { + // Buffer overflow + Log.e(TAG, String.format("Wrong tlv length, stop parsing")); + return; + } + // Qualifier-Type(1 byte) + Length(1 byte) + Value(valueLength bytes) + int tlvLength = rt[offset + 1] + 2; - String blkCtrl = getBlockCtrlStr(rt[offset] & 0xF0); - String eeId = String.format("0x%02X", rt[offset + 2]); - String pwrState = String.format("0x%02X", rt[offset + 3]); - String entry = getSystemCodeStr(rt, offset + 4, rt[offset + 1] - 2); + addRoutingEntry(rt, offset); - pw.println(formatRow(entry, eeId, pwrState, blkCtrl, "")); + offset += tlvLength; + } } /** - * Get Routing Table from the last backup lmrt cmd and dump it + * Get Routing Table from the last backup lmrt cmd and parse it */ - public void dump(DeviceHost dh, PrintWriter pw) { - int offset = 0; + public void update(DeviceHost dh) { + sRoutingTableMaxSize = dh.getMaxRoutingTableSize(); byte[] rt = dh.getRoutingTable(); - int maxSize = dh.getMaxRoutingTableSize(); + sRoutingTableSize = rt.length; + parse(rt); + } - logRoutingTableRawData(rt); + /** + * Get Routing Table from the last backup lmrt cmd and dump it + */ + public void dump(DeviceHost dh, PrintWriter pw) { + update(dh); pw.println("--- dumpRoutingTable: start ---"); - pw.println(String.format(Locale.US, "RoutingTableSize: %d/%d", rt.length, maxSize)); + pw.println(String.format(Locale.US, "RoutingTableSize: %d/%d", + sRoutingTableSize, sRoutingTableMaxSize)); pw.println(formatRow("Entry", "NFCEE_ID", "Power State", "Block Ctrl", "Extra Info")); - while (offset < rt.length) { - int type = rt[offset] & 0x0F; - if (type == 0x00) { - // Technology-based routing entry - dumpTechEntry(rt, rt.length, pw, offset); - } else if (type == 0x01) { - // Protocol-based routing entry - dumpProtoEntry(rt, rt.length, pw, offset); - } else if (type == 0x02) { - // AID-based routing entry - dumpAidEntry(rt, rt.length, pw, offset); - } else if (type == 0x03) { - // System Code-based routing entry - dumpSystemEntry(rt, rt.length, pw, offset); - } else { - // Unrecognizable entry type - Log.d(TAG, String.format("Unrecognizable entry type: 0x%02X, stop parsing", type)); - break; - } - offset += rt[offset+1] + 2; + + for (RoutingEntryInfo routingEntry : sRoutingTable) { + routingEntry.dump(pw); } pw.println("--- dumpRoutingTable: end ---"); @@ -184,10 +309,11 @@ public class RoutingTableParser { private void logRoutingTableRawData(byte[] lmrt_cmd) { if (!DBG) return; String lmrt_str = ""; - for (int i = 0; i < lmrt_cmd.length; i++) { - lmrt_str += String.format("%02X ", lmrt_cmd[i]); + + for (byte b : lmrt_cmd) { + lmrt_str += String.format("%02X ", b); } - Log.d(TAG, String.format("RoutingTableSize: %d", lmrt_cmd.length)); - Log.d(TAG, String.format("RoutingTable: %s", lmrt_str)); + Log.i(TAG, String.format("RoutingTableSize: %d", lmrt_cmd.length)); + Log.i(TAG, String.format("RoutingTable: %s", lmrt_str)); } } diff --git a/src/com/android/nfc/beam/BeamReceiveService.java b/src/com/android/nfc/beam/BeamReceiveService.java index 5602997b..444b12ed 100644 --- a/src/com/android/nfc/beam/BeamReceiveService.java +++ b/src/com/android/nfc/beam/BeamReceiveService.java @@ -94,7 +94,8 @@ public class BeamReceiveService extends Service implements BeamTransferManager.C // register Beam status receiver mBeamStatusReceiver = new BeamStatusReceiver(this, mTransferManager); registerReceiver(mBeamStatusReceiver, mBeamStatusReceiver.getIntentFilter(), - BeamStatusReceiver.BEAM_STATUS_PERMISSION, new Handler()); + BeamStatusReceiver.BEAM_STATUS_PERMISSION, new Handler(), + Context.RECEIVER_EXPORTED); mTransferManager.start(); mTransferManager.updateNotification(); diff --git a/src/com/android/nfc/beam/BeamSendService.java b/src/com/android/nfc/beam/BeamSendService.java index f4880d49..13f8f3d3 100644 --- a/src/com/android/nfc/beam/BeamSendService.java +++ b/src/com/android/nfc/beam/BeamSendService.java @@ -107,7 +107,8 @@ public class BeamSendService extends Service implements BeamTransferManager.Call // register Beam status receiver mBeamStatusReceiver = new BeamStatusReceiver(this, mTransferManager); registerReceiver(mBeamStatusReceiver, mBeamStatusReceiver.getIntentFilter(), - BeamStatusReceiver.BEAM_STATUS_PERMISSION, new Handler()); + BeamStatusReceiver.BEAM_STATUS_PERMISSION, new Handler(), + Context.RECEIVER_EXPORTED); if (transferRecord.dataLinkType == BeamTransferRecord.DATA_LINK_TYPE_BLUETOOTH) { if (mBluetoothAdapter.isEnabled()) { diff --git a/src/com/android/nfc/beam/SendUi.java b/src/com/android/nfc/beam/SendUi.java index 966d1376..e2094163 100644 --- a/src/com/android/nfc/beam/SendUi.java +++ b/src/com/android/nfc/beam/SendUi.java @@ -331,7 +331,7 @@ public class SendUi implements Animator.AnimatorListener, View.OnTouchListener, new ScreenshotTask().execute(); final IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - mContext.registerReceiver(mReceiver, filter); + mContext.registerReceiver(mReceiver, filter, Context.RECEIVER_EXPORTED); } /** Show pre-send animation */ diff --git a/src/com/android/nfc/cardemulation/AppChooserActivity.java b/src/com/android/nfc/cardemulation/AppChooserActivity.java index 11f4d46e..ee16aeb1 100644 --- a/src/com/android/nfc/cardemulation/AppChooserActivity.java +++ b/src/com/android/nfc/cardemulation/AppChooserActivity.java @@ -42,15 +42,17 @@ import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; import com.android.internal.R; -import com.android.internal.app.AlertActivity; -import com.android.internal.app.AlertController; +import com.google.android.material.bottomsheet.BottomSheetBehavior; +import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback; import java.util.ArrayList; import java.util.List; -public class AppChooserActivity extends AlertActivity +public class AppChooserActivity extends AppCompatActivity implements AdapterView.OnItemClickListener { static final String TAG = "AppChooserActivity"; @@ -60,6 +62,7 @@ public class AppChooserActivity extends AlertActivity public static final String EXTRA_FAILED_COMPONENT = "failed_component"; private int mIconSize; + private TextView mTextView; private ListView mListView; private ListAdapter mListAdapter; private CardEmulation mCardEmuManager; @@ -81,7 +84,6 @@ public class AppChooserActivity extends AlertActivity protected void onCreate(Bundle savedInstanceState, String category, ArrayList<ApduServiceInfo> options, ComponentName failedComponent) { super.onCreate(savedInstanceState); - setTheme(com.android.nfc.R.style.DialogAlertDayNight); IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF); registerReceiver(mReceiver, filter); @@ -97,7 +99,6 @@ public class AppChooserActivity extends AlertActivity final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); mCardEmuManager = CardEmulation.getInstance(adapter); - AlertController.AlertParams ap = mAlertParams; final ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE); mIconSize = am.getLauncherLargeIconSize(); @@ -108,6 +109,27 @@ public class AppChooserActivity extends AlertActivity // 3. No failed component and alternatives: pick alternative PackageManager pm = getPackageManager(); + setContentView(com.android.nfc.R.layout.cardemu_resolver_bottomsheet); + + + findViewById(com.android.nfc.R.id.touch_outside).setOnClickListener(v -> finish()); + BottomSheetBehavior.from(findViewById(com.android.nfc.R.id.bottom_sheet)) + .setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { + @Override + public void onStateChanged(@NonNull View bottomSheet, int newState) { + switch (newState) { + case BottomSheetBehavior.STATE_HIDDEN: + finish(); + break; + } + } + + @Override + public void onSlide(@NonNull View bottomSheet, float slideOffset) { + // no op + } + }); + CharSequence applicationLabel = "unknown"; if (failedComponent != null) { try { @@ -117,30 +139,20 @@ public class AppChooserActivity extends AlertActivity } } + mTextView = (TextView) findViewById(com.android.nfc.R.id.appchooser_text); if (options.size() == 0 && failedComponent != null) { String formatString = getString(com.android.nfc.R.string.transaction_failure); - ap.mTitle = ""; - ap.mMessage = String.format(formatString, applicationLabel); - ap.mPositiveButtonText = getString(R.string.ok); - setupAlert(); + mTextView.setText(String.format(formatString, applicationLabel)); } else { mListAdapter = new ListAdapter(this, options); if (failedComponent != null) { String formatString = getString(com.android.nfc.R.string.could_not_use_app); - ap.mTitle = String.format(formatString, applicationLabel); - ap.mNegativeButtonText = getString(R.string.cancel); - } else { - if (CardEmulation.CATEGORY_PAYMENT.equals(category)) { - ap.mTitle = getString(com.android.nfc.R.string.pay_with); - } else { - ap.mTitle = getString(com.android.nfc.R.string.complete_with); - } + mTextView.setText(String.format(formatString, applicationLabel)); } - ap.mView = getLayoutInflater().inflate(com.android.nfc.R.layout.cardemu_resolver, null); - mListView = (ListView) ap.mView.findViewById(com.android.nfc.R.id.resolver_list); + mListView = (ListView) findViewById(com.android.nfc.R.id.resolver_list); + mListView.setDivider(getResources().getDrawable(android.R.color.transparent)); if (isPayment) { - mListView.setDivider(getResources().getDrawable(android.R.color.transparent)); int height = (int) (getResources().getDisplayMetrics().density * 16); mListView.setDividerHeight(height); } else { @@ -148,10 +160,9 @@ public class AppChooserActivity extends AlertActivity } mListView.setAdapter(mListAdapter); mListView.setOnItemClickListener(this); - - setupAlert(); } Window window = getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND); window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); } @@ -206,7 +217,10 @@ public class AppChooserActivity extends AlertActivity for (ApduServiceInfo service : services) { CharSequence label = service.getDescription(); if (label == null) label = service.loadLabel(pm); - Drawable icon = service.loadIcon(pm); + + Drawable icon = pm.getUserBadgedIcon(service.loadIcon(pm), + UserHandle.getUserHandleForUid(service.getUid())); + Drawable banner = null; if (mIsPayment) { banner = service.loadBanner(pm); @@ -258,8 +272,6 @@ public class AppChooserActivity extends AlertActivity if (mIsPayment) { holder.banner.setImageDrawable(appInfo.displayBanner); } else { - ViewGroup.LayoutParams lp = holder.icon.getLayoutParams(); - lp.width = lp.height = mIconSize; holder.icon.setImageDrawable(appInfo.displayIcon); holder.text.setText(appInfo.displayLabel); } diff --git a/src/com/android/nfc/cardemulation/CardEmulationManager.java b/src/com/android/nfc/cardemulation/CardEmulationManager.java index e3d21627..378fe6e0 100644 --- a/src/com/android/nfc/cardemulation/CardEmulationManager.java +++ b/src/com/android/nfc/cardemulation/CardEmulationManager.java @@ -264,30 +264,9 @@ public class CardEmulationManager implements RegisteredServicesCache.Callback, getDefaultServiceForCategory(userId, CardEmulation.CATEGORY_PAYMENT, true); if (DBG) Log.d(TAG, "Current default: " + defaultPaymentService); if (defaultPaymentService == null) { - // A payment service may have been removed, leaving only one; - // in that case, automatically set that app as default. - int numPaymentServices = 0; - ComponentName lastFoundPaymentService = null; - for (ApduServiceInfo service : services) { - if (service.hasCategory(CardEmulation.CATEGORY_PAYMENT)) { - numPaymentServices++; - lastFoundPaymentService = service.getComponent(); - } - } - if (numPaymentServices > 1) { - // More than one service left, leave default unset - if (DBG) Log.d(TAG, "No default set, more than one service left."); - setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT); - } else if (numPaymentServices == 1) { - // Make single found payment service the default - if (DBG) Log.d(TAG, "No default set, making single service default."); - setDefaultServiceForCategoryChecked(userId, lastFoundPaymentService, - CardEmulation.CATEGORY_PAYMENT); - } else { - // No payment services left, leave default at null - if (DBG) Log.d(TAG, "No default set, last payment service removed."); - setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT); - } + // A payment service may have been removed, set default payment selection to "not set". + if (DBG) Log.d(TAG, "No default set, last payment service removed."); + setDefaultServiceForCategoryChecked(userId, null, CardEmulation.CATEGORY_PAYMENT); } } diff --git a/src/com/android/nfc/cardemulation/TapAgainDialog.java b/src/com/android/nfc/cardemulation/TapAgainDialog.java index e786ab33..a46735b8 100644 --- a/src/com/android/nfc/cardemulation/TapAgainDialog.java +++ b/src/com/android/nfc/cardemulation/TapAgainDialog.java @@ -22,13 +22,18 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.graphics.drawable.Drawable; import android.nfc.NfcAdapter; import android.nfc.cardemulation.ApduServiceInfo; import android.nfc.cardemulation.CardEmulation; import android.os.Bundle; +import android.os.UserHandle; +import android.view.View; import android.view.Window; import android.view.WindowManager; +import android.widget.ImageView; import android.widget.TextView; +import androidx.appcompat.widget.Toolbar; import com.android.internal.R; import com.android.internal.app.AlertActivity; @@ -56,7 +61,7 @@ public class TapAgainDialog extends AlertActivity implements DialogInterface.OnC protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setTheme(com.android.nfc.R.style.DialogAlertDayNight); + setTheme(com.android.nfc.R.style.TapAgainDayNight); final NfcAdapter adapter = NfcAdapter.getDefaultAdapter(this); mCardEmuManager = CardEmulation.getInstance(adapter); @@ -72,24 +77,22 @@ public class TapAgainDialog extends AlertActivity implements DialogInterface.OnC ap.mView = getLayoutInflater().inflate(com.android.nfc.R.layout.tapagain, null); PackageManager pm = getPackageManager(); - TextView tv = (TextView) ap.mView.findViewById(com.android.nfc.R.id.textview); - String description = serviceInfo.getDescription(); - if (description == null) { - CharSequence label = serviceInfo.loadLabel(pm); - if (label == null) { + + Toolbar toolbar = (Toolbar) ap.mView.findViewById(com.android.nfc.R.id.tap_again_toolbar); + toolbar.setNavigationIcon(getDrawable(com.android.nfc.R.drawable.ic_close)); + toolbar.setNavigationOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { finish(); - } else { - description = label.toString(); } - } - if (CardEmulation.CATEGORY_PAYMENT.equals(category)) { - String formatString = getString(com.android.nfc.R.string.tap_again_to_pay); - tv.setText(String.format(formatString, description)); - } else { - String formatString = getString(com.android.nfc.R.string.tap_again_to_complete); - tv.setText(String.format(formatString, description)); - } - ap.mNegativeButtonText = getString(R.string.cancel); + }); + + ImageView iv = (ImageView) ap.mView.findViewById(com.android.nfc.R.id.tap_again_appicon); + Drawable icon = pm.getUserBadgedIcon(serviceInfo.loadIcon(pm), + UserHandle.getUserHandleForUid(serviceInfo.getUid())); + + iv.setImageDrawable(icon); + setupAlert(); Window window = getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); @@ -113,4 +116,4 @@ public class TapAgainDialog extends AlertActivity implements DialogInterface.OnC public void onClick(DialogInterface dialog, int which) { finish(); } -}
\ No newline at end of file +} |