diff options
author | 2024-12-13 15:37:37 -0800 | |
---|---|---|
committer | 2024-12-13 15:37:37 -0800 | |
commit | 19faae068d207e915eaf00be489cb1a0fe63bba1 (patch) | |
tree | efcb891ca8758d8fd75fdbe7be9ea02d9cf75751 /nfc-non-updatable | |
parent | 132a431ef6685b02525da38e45088bc142251927 (diff) |
Revert "nfc(framework): Split non-updatable portion to a separat..."
Revert submission 3411958-framework-nfc-code-split
Reason for revert: Causing a lot of merge conflicts down the chain because of missing changes in aosp/main.
Reverted changes: /q/submissionid:3411958-framework-nfc-code-split
Bug: 384067476
Change-Id: Ic451b2f5ebd80f875bc2c46c6a17516dc81dfd16
Test: Compiles
Diffstat (limited to 'nfc-non-updatable')
10 files changed, 0 insertions, 2366 deletions
diff --git a/nfc-non-updatable/Android.bp b/nfc-non-updatable/Android.bp deleted file mode 100644 index ff987bb84b17..000000000000 --- a/nfc-non-updatable/Android.bp +++ /dev/null @@ -1,23 +0,0 @@ -package { - default_team: "trendy_team_fwk_nfc", - // See: http://go/android-license-faq - // A large-scale-change added 'default_applicable_licenses' to import - // all of the 'license_kinds' from "frameworks_base_license" - // to get the below license kinds: - // SPDX-license-identifier-Apache-2.0 - default_applicable_licenses: ["frameworks_base_license"], -} - -filegroup { - name: "framework-nfc-non-updatable-sources", - path: "java", - srcs: [ - "java/android/nfc/NfcServiceManager.java", - "java/android/nfc/cardemulation/ApduServiceInfo.aidl", - "java/android/nfc/cardemulation/ApduServiceInfo.java", - "java/android/nfc/cardemulation/NfcFServiceInfo.aidl", - "java/android/nfc/cardemulation/NfcFServiceInfo.java", - "java/android/nfc/cardemulation/AidGroup.aidl", - "java/android/nfc/cardemulation/AidGroup.java", - ], -} diff --git a/nfc-non-updatable/OWNERS b/nfc-non-updatable/OWNERS deleted file mode 100644 index f46dccd97974..000000000000 --- a/nfc-non-updatable/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -# Bug component: 48448 -include platform/packages/apps/Nfc:/OWNERS
\ No newline at end of file diff --git a/nfc-non-updatable/flags/flags.aconfig b/nfc-non-updatable/flags/flags.aconfig deleted file mode 100644 index ee287aba709f..000000000000 --- a/nfc-non-updatable/flags/flags.aconfig +++ /dev/null @@ -1,191 +0,0 @@ -package: "android.nfc" -container: "system" - -flag { - name: "nfc_event_listener" - is_exported: true - namespace: "nfc" - description: "Enable NFC Event listener APIs" - bug: "356447790" -} - -flag { - name: "enable_nfc_mainline" - is_exported: true - namespace: "nfc" - description: "Flag for NFC mainline changes" - bug: "292140387" -} - -flag { - name: "enable_nfc_reader_option" - is_exported: true - namespace: "nfc" - description: "Flag for NFC reader option API changes" - bug: "291187960" -} - -flag { - name: "enable_nfc_user_restriction" - is_exported: true - namespace: "nfc" - description: "Flag for NFC user restriction" - bug: "291187960" -} - -flag { - name: "nfc_observe_mode" - is_exported: true - namespace: "nfc" - description: "Enable NFC Observe Mode" - bug: "294217286" -} - -flag { - name: "nfc_read_polling_loop" - is_exported: true - namespace: "nfc" - description: "Enable NFC Polling Loop Notifications" - bug: "294217286" -} - -flag { - name: "nfc_observe_mode_st_shim" - namespace: "nfc" - description: "Enable NFC Observe Mode ST shim" - bug: "294217286" -} - -flag { - name: "nfc_read_polling_loop_st_shim" - namespace: "nfc" - description: "Enable NFC Polling Loop Notifications ST shim" - bug: "294217286" -} - -flag { - name: "enable_tag_detection_broadcasts" - namespace: "nfc" - description: "Enable sending broadcasts to Wallet role holder when a tag enters/leaves the field." - bug: "306203494" -} - -flag { - name: "enable_nfc_charging" - is_exported: true - namespace: "nfc" - description: "Flag for NFC charging changes" - bug: "292143899" -} - -flag { - name: "enable_nfc_set_discovery_tech" - is_exported: true - namespace: "nfc" - description: "Flag for NFC set discovery tech API" - bug: "300351519" -} - -flag { - name: "nfc_vendor_cmd" - is_exported: true - namespace: "nfc" - description: "Enable NFC vendor command support" - bug: "289879306" -} - -flag { - name: "nfc_oem_extension" - is_exported: true - namespace: "nfc" - description: "Enable NFC OEM extension support" - bug: "331206243" -} - -flag { - name: "nfc_state_change" - is_exported: true - namespace: "nfc" - description: "Enable nfc state change API" - bug: "319934052" -} - -flag { - name: "nfc_set_default_disc_tech" - is_exported: true - namespace: "nfc" - description: "Flag for NFC set default disc tech API" - bug: "321311407" -} - -flag { - name: "nfc_persist_log" - is_exported: true - namespace: "nfc" - description: "Enable NFC persistent log support" - bug: "321310044" -} - -flag { - name: "nfc_action_manage_services_settings" - is_exported: true - namespace: "nfc" - description: "Add Settings.ACTION_MANAGE_OTHER_NFC_SERVICES_SETTINGS" - bug: "358129872" -} - -flag { - name: "nfc_override_recover_routing_table" - is_exported: true - namespace: "nfc" - description: "Enable override and recover routing table" - bug: "329043523" -} - -flag { - name: "nfc_watchdog" - is_exported: true - namespace: "nfc" - description: "Enable watchdog for the NFC system process" - bug: "362937338" -} - -flag { - name: "enable_card_emulation_euicc" - is_exported: true - namespace: "nfc" - description: "Enable EUICC card emulation" - bug: "321314635" -} - -flag { - name: "nfc_state_change_security_log_event_enabled" - is_exported: true - namespace: "nfc" - description: "Enabling security log for nfc state change" - bug: "319934052" -} - -flag { - name: "nfc_associated_role_services" - is_exported: true - namespace: "nfc" - description: "Share wallet role routing priority with associated services" - bug: "366243361" -} - -flag { - name: "nfc_set_service_enabled_for_category_other" - is_exported: true - namespace: "nfc" - description: "Enable set service enabled for category other" - bug: "338157113" -} - -flag { - name: "nfc_check_tag_intent_preference" - is_exported: true - namespace: "nfc" - description: "App can check its tag intent preference status" - bug: "335916336" -} diff --git a/nfc-non-updatable/java/android/nfc/NfcServiceManager.java b/nfc-non-updatable/java/android/nfc/NfcServiceManager.java deleted file mode 100644 index 5582f1154cad..000000000000 --- a/nfc-non-updatable/java/android/nfc/NfcServiceManager.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (C) 2022 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. - */ - - -/********************************************************************** - * This file is not a part of the NFC mainline modure * - * *******************************************************************/ - -package android.nfc; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.annotation.SystemApi.Client; -import android.content.Context; -import android.os.IBinder; -import android.os.ServiceManager; - -/** - * Provides a way to register and obtain the system service binder objects managed by the nfc - * service. - * - * @hide - */ -@SystemApi(client = Client.MODULE_LIBRARIES) -public class NfcServiceManager { - - /** - * @hide - */ - public NfcServiceManager() { - } - - /** - * A class that exposes the methods to register and obtain each system service. - */ - public static final class ServiceRegisterer { - private final String mServiceName; - - /** - * @hide - */ - public ServiceRegisterer(String serviceName) { - mServiceName = serviceName; - } - - /** - * Register a system server binding object for a service. - */ - public void register(@NonNull IBinder service) { - ServiceManager.addService(mServiceName, service); - } - - /** - * Get the system server binding object for a service. - * - * <p>This blocks until the service instance is ready, - * or a timeout happens, in which case it returns null. - */ - @Nullable - public IBinder get() { - return ServiceManager.getService(mServiceName); - } - - /** - * Get the system server binding object for a service. - * - * <p>This blocks until the service instance is ready, - * or a timeout happens, in which case it throws {@link ServiceNotFoundException}. - */ - @NonNull - public IBinder getOrThrow() throws ServiceNotFoundException { - try { - return ServiceManager.getServiceOrThrow(mServiceName); - } catch (ServiceManager.ServiceNotFoundException e) { - throw new ServiceNotFoundException(mServiceName); - } - } - - /** - * Get the system server binding object for a service. If the specified service is - * not available, it returns null. - */ - @Nullable - public IBinder tryGet() { - return ServiceManager.checkService(mServiceName); - } - } - - /** - * See {@link ServiceRegisterer#getOrThrow}. - * - */ - public static class ServiceNotFoundException extends ServiceManager.ServiceNotFoundException { - /** - * Constructor. - * - * @param name the name of the binder service that cannot be found. - * - */ - public ServiceNotFoundException(@NonNull String name) { - super(name); - } - } - - /** - * Returns {@link ServiceRegisterer} for the "nfc" service. - */ - @NonNull - public ServiceRegisterer getNfcManagerServiceRegisterer() { - return new ServiceRegisterer(Context.NFC_SERVICE); - } -} diff --git a/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.aidl b/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.aidl deleted file mode 100644 index 56d6fa559677..000000000000 --- a/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2013 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 android.nfc.cardemulation; - -parcelable AidGroup; diff --git a/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.java b/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.java deleted file mode 100644 index ae3e333051d7..000000000000 --- a/nfc-non-updatable/java/android/nfc/cardemulation/AidGroup.java +++ /dev/null @@ -1,298 +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 android.nfc.cardemulation; - -import android.annotation.FlaggedApi; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.nfc.Flags; -import android.os.Parcel; -import android.os.Parcelable; -import android.util.Log; -import android.util.proto.ProtoOutputStream; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; -import org.xmlpull.v1.XmlSerializer; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.regex.Pattern; - -/********************************************************************** - * This file is not a part of the NFC mainline module * - * *******************************************************************/ - -/** - * The AidGroup class represents a group of Application Identifiers (AIDs). - * - * <p>The format of AIDs is defined in the ISO/IEC 7816-4 specification. This class - * requires the AIDs to be input as a hexadecimal string, with an even amount of - * hexadecimal characters, e.g. "F014811481". - * - * @hide - */ -@SystemApi -@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) -public final class AidGroup implements Parcelable { - /** - * The maximum number of AIDs that can be present in any one group. - */ - private static final int MAX_NUM_AIDS = 256; - - private static final String TAG = "AidGroup"; - - - private final List<String> mAids; - private final String mCategory; - @SuppressWarnings("unused") // Unused as of now, but part of the XML input. - private final String mDescription; - - /** - * Creates a new AidGroup object. - * - * @param aids list of AIDs present in the group - * @param category category of this group, e.g. {@link CardEmulation#CATEGORY_PAYMENT} - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public AidGroup(@NonNull List<String> aids, @Nullable String category) { - if (aids == null || aids.size() == 0) { - throw new IllegalArgumentException("No AIDS in AID group."); - } - if (aids.size() > MAX_NUM_AIDS) { - throw new IllegalArgumentException("Too many AIDs in AID group."); - } - for (String aid : aids) { - if (!isValidAid(aid)) { - throw new IllegalArgumentException("AID " + aid + " is not a valid AID."); - } - } - if (isValidCategory(category)) { - this.mCategory = category; - } else { - this.mCategory = CardEmulation.CATEGORY_OTHER; - } - this.mAids = new ArrayList<String>(aids.size()); - for (String aid : aids) { - this.mAids.add(aid.toUpperCase(Locale.US)); - } - this.mDescription = null; - } - - /** - * Creates a new AidGroup object. - * - * @param category category of this group, e.g. {@link CardEmulation#CATEGORY_PAYMENT} - * @param description description of this group - */ - AidGroup(@NonNull String category, @NonNull String description) { - this.mAids = new ArrayList<String>(); - this.mCategory = category; - this.mDescription = description; - } - - /** - * Returns the category of this group. - * @return the category of this AID group - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public String getCategory() { - return mCategory; - } - - /** - * Returns the list of AIDs in this group. - * - * @return the list of AIDs in this group - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public List<String> getAids() { - return mAids; - } - - @Override - public String toString() { - StringBuilder out = new StringBuilder("Category: " + mCategory - + ", AIDs:"); - for (String aid : mAids) { - out.append(aid); - out.append(", "); - } - return out.toString(); - } - - /** - * Dump debugging info as AidGroupProto. - * - * If the output belongs to a sub message, the caller is responsible for wrapping this function - * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}. - * - * @param proto the ProtoOutputStream to write to - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void dump(@NonNull ProtoOutputStream proto) { - proto.write(AidGroupProto.CATEGORY, mCategory); - for (String aid : mAids) { - proto.write(AidGroupProto.AIDS, aid); - } - } - - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @Override - public int describeContents() { - return 0; - } - - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - dest.writeString8(mCategory); - dest.writeInt(mAids.size()); - if (mAids.size() > 0) { - dest.writeStringList(mAids); - } - } - - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public static final @NonNull Parcelable.Creator<AidGroup> CREATOR = - new Parcelable.Creator<AidGroup>() { - - @Override - public AidGroup createFromParcel(Parcel source) { - String category = source.readString8(); - int listSize = source.readInt(); - ArrayList<String> aidList = new ArrayList<String>(); - if (listSize > 0) { - source.readStringList(aidList); - } - return new AidGroup(aidList, category); - } - - @Override - public AidGroup[] newArray(int size) { - return new AidGroup[size]; - } - }; - - /** - * Create an instance of AID group from XML file. - * - * @param parser input xml parser stream - * @throws XmlPullParserException If an error occurs parsing the element. - * @throws IOException If an error occurs reading the element. - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @Nullable - public static AidGroup createFromXml(@NonNull XmlPullParser parser) - throws XmlPullParserException, IOException { - String category = null; - ArrayList<String> aids = new ArrayList<String>(); - AidGroup group = null; - boolean inGroup = false; - - int eventType = parser.getEventType(); - int minDepth = parser.getDepth(); - while (eventType != XmlPullParser.END_DOCUMENT && parser.getDepth() >= minDepth) { - String tagName = parser.getName(); - if (eventType == XmlPullParser.START_TAG) { - if (tagName.equals("aid")) { - if (inGroup) { - String aid = parser.getAttributeValue(null, "value"); - if (aid != null) { - aids.add(aid.toUpperCase()); - } - } else { - Log.d(TAG, "Ignoring <aid> tag while not in group"); - } - } else if (tagName.equals("aid-group")) { - category = parser.getAttributeValue(null, "category"); - if (category == null) { - Log.e(TAG, "<aid-group> tag without valid category"); - return null; - } - inGroup = true; - } else { - Log.d(TAG, "Ignoring unexpected tag: " + tagName); - } - } else if (eventType == XmlPullParser.END_TAG) { - if (tagName.equals("aid-group") && inGroup && aids.size() > 0) { - group = new AidGroup(aids, category); - break; - } - } - eventType = parser.next(); - } - return group; - } - - /** - * Serialize instance of AID group to XML file. - * @param out XML serializer stream - * @throws IOException If an error occurs reading the element. - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void writeAsXml(@NonNull XmlSerializer out) throws IOException { - out.startTag(null, "aid-group"); - out.attribute(null, "category", mCategory); - for (String aid : mAids) { - out.startTag(null, "aid"); - out.attribute(null, "value", aid); - out.endTag(null, "aid"); - } - out.endTag(null, "aid-group"); - } - - private static boolean isValidCategory(String category) { - return CardEmulation.CATEGORY_PAYMENT.equals(category) || - CardEmulation.CATEGORY_OTHER.equals(category); - } - - private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?"); - /** - * Copied over from {@link CardEmulation#isValidAid(String)} - * @hide - */ - private static boolean isValidAid(String aid) { - if (aid == null) - return false; - - // If a prefix/subset AID, the total length must be odd (even # of AID chars + '*') - if ((aid.endsWith("*") || aid.endsWith("#")) && ((aid.length() % 2) == 0)) { - Log.e(TAG, "AID " + aid + " is not a valid AID."); - return false; - } - - // If not a prefix/subset AID, the total length must be even (even # of AID chars) - if ((!(aid.endsWith("*") || aid.endsWith("#"))) && ((aid.length() % 2) != 0)) { - Log.e(TAG, "AID " + aid + " is not a valid AID."); - return false; - } - - // Verify hex characters - if (!AID_PATTERN.matcher(aid).matches()) { - Log.e(TAG, "AID " + aid + " is not a valid AID."); - return false; - } - - return true; - } -} diff --git a/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.aidl b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.aidl deleted file mode 100644 index a62fdd6a6c5c..000000000000 --- a/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2013 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 android.nfc.cardemulation; - -parcelable ApduServiceInfo; diff --git a/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java deleted file mode 100644 index eac783628ed9..000000000000 --- a/nfc-non-updatable/java/android/nfc/cardemulation/ApduServiceInfo.java +++ /dev/null @@ -1,1172 +0,0 @@ -/* - * Copyright (C) 2013 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. - */ - -/********************************************************************** - * This file is not a part of the NFC mainline module * - * *******************************************************************/ - -package android.nfc.cardemulation; - -import android.annotation.FlaggedApi; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.compat.annotation.UnsupportedAppUsage; -import android.content.ComponentName; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.content.res.Resources; -import android.content.res.Resources.NotFoundException; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.graphics.drawable.Drawable; -import android.nfc.Flags; -import android.os.Parcel; -import android.os.ParcelFileDescriptor; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.util.Log; -import android.util.Xml; -import android.util.proto.ProtoOutputStream; - -import com.android.internal.R; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.TreeMap; -import java.util.regex.Pattern; - -/** - * Class holding APDU service info. - * - * @hide - */ -@SystemApi -@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) -public final class ApduServiceInfo implements Parcelable { - private static final String TAG = "ApduServiceInfo"; - - /** - * The service that implements this - */ - private final ResolveInfo mService; - - /** - * Description of the service - */ - private final String mDescription; - - /** - * Whether this service represents AIDs running on the host CPU - */ - private final boolean mOnHost; - - /** - * Offhost reader name. - * eg: SIM, eSE etc - */ - private String mOffHostName; - - /** - * Offhost reader name from manifest file. - * Used for resetOffHostSecureElement() - */ - private final String mStaticOffHostName; - - /** - * Mapping from category to static AID group - */ - private final HashMap<String, AidGroup> mStaticAidGroups; - - /** - * Mapping from category to dynamic AID group - */ - private final HashMap<String, AidGroup> mDynamicAidGroups; - - - private final Map<String, Boolean> mAutoTransact; - - private final Map<Pattern, Boolean> mAutoTransactPatterns; - - /** - * Whether this service should only be started when the device is unlocked. - */ - private final boolean mRequiresDeviceUnlock; - - /** - * Whether this service should only be started when the device is screen on. - */ - private final boolean mRequiresDeviceScreenOn; - - /** - * The id of the service banner specified in XML. - */ - private final int mBannerResourceId; - - /** - * The uid of the package the service belongs to - */ - private final int mUid; - - /** - * Settings Activity for this service - */ - private final String mSettingsActivityName; - - /** - * State of the service for CATEGORY_OTHER selection - */ - private boolean mCategoryOtherServiceEnabled; - - /** - * Whether the NFC stack should default to Observe Mode when this preferred service. - */ - private boolean mShouldDefaultToObserveMode; - - /** - * Whether or not this service wants to share the same routing priority as the - * Wallet role owner. - */ - private boolean mShareRolePriority; - - /** - * @hide - */ - @UnsupportedAppUsage - public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, - ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups, - boolean requiresUnlock, int bannerResource, int uid, - String settingsActivityName, String offHost, String staticOffHost) { - this(info, onHost, description, staticAidGroups, dynamicAidGroups, - requiresUnlock, bannerResource, uid, settingsActivityName, - offHost, staticOffHost, false); - } - - /** - * @hide - */ - public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, - ArrayList<AidGroup> staticAidGroups, ArrayList<AidGroup> dynamicAidGroups, - boolean requiresUnlock, int bannerResource, int uid, - String settingsActivityName, String offHost, String staticOffHost, - boolean isEnabled) { - this(info, onHost, description, staticAidGroups, dynamicAidGroups, - requiresUnlock, onHost ? true : false, bannerResource, uid, - settingsActivityName, offHost, staticOffHost, isEnabled); - } - - /** - * @hide - */ - public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, - List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, - boolean requiresUnlock, boolean requiresScreenOn, int bannerResource, int uid, - String settingsActivityName, String offHost, String staticOffHost, boolean isEnabled) { - this(info, onHost, description, staticAidGroups, dynamicAidGroups, - requiresUnlock, requiresScreenOn, bannerResource, uid, - settingsActivityName, offHost, staticOffHost, isEnabled, - new HashMap<String, Boolean>(), new TreeMap<>( - Comparator.comparing(Pattern::toString))); - } - - /** - * @hide - */ - public ApduServiceInfo(ResolveInfo info, boolean onHost, String description, - List<AidGroup> staticAidGroups, List<AidGroup> dynamicAidGroups, - boolean requiresUnlock, boolean requiresScreenOn, int bannerResource, int uid, - String settingsActivityName, String offHost, String staticOffHost, boolean isEnabled, - Map<String, Boolean> autoTransact, Map<Pattern, Boolean> autoTransactPatterns) { - this.mService = info; - this.mDescription = description; - this.mStaticAidGroups = new HashMap<String, AidGroup>(); - this.mDynamicAidGroups = new HashMap<String, AidGroup>(); - this.mAutoTransact = autoTransact; - this.mAutoTransactPatterns = autoTransactPatterns; - this.mOffHostName = offHost; - this.mStaticOffHostName = staticOffHost; - this.mOnHost = onHost; - this.mRequiresDeviceUnlock = requiresUnlock; - this.mRequiresDeviceScreenOn = requiresScreenOn; - for (AidGroup aidGroup : staticAidGroups) { - this.mStaticAidGroups.put(aidGroup.getCategory(), aidGroup); - } - for (AidGroup aidGroup : dynamicAidGroups) { - this.mDynamicAidGroups.put(aidGroup.getCategory(), aidGroup); - } - this.mBannerResourceId = bannerResource; - this.mUid = uid; - this.mSettingsActivityName = settingsActivityName; - this.mCategoryOtherServiceEnabled = isEnabled; - } - - /** - * Creates a new ApduServiceInfo object. - * - * @param pm packageManager instance - * @param info app component info - * @param onHost whether service is on host or not (secure element) - * @throws XmlPullParserException If an error occurs parsing the element. - * @throws IOException If an error occurs reading the element. - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public ApduServiceInfo(@NonNull PackageManager pm, @NonNull ResolveInfo info, boolean onHost) - throws XmlPullParserException, IOException { - ServiceInfo si = info.serviceInfo; - XmlResourceParser parser = null; - try { - if (onHost) { - parser = si.loadXmlMetaData(pm, HostApduService.SERVICE_META_DATA); - if (parser == null) { - throw new XmlPullParserException("No " + HostApduService.SERVICE_META_DATA + - " meta-data"); - } - } else { - parser = si.loadXmlMetaData(pm, OffHostApduService.SERVICE_META_DATA); - if (parser == null) { - throw new XmlPullParserException("No " + OffHostApduService.SERVICE_META_DATA + - " meta-data"); - } - } - - int eventType = parser.getEventType(); - while (eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_DOCUMENT) { - eventType = parser.next(); - } - - String tagName = parser.getName(); - if (onHost && !"host-apdu-service".equals(tagName)) { - throw new XmlPullParserException( - "Meta-data does not start with <host-apdu-service> tag"); - } else if (!onHost && !"offhost-apdu-service".equals(tagName)) { - throw new XmlPullParserException( - "Meta-data does not start with <offhost-apdu-service> tag"); - } - - Resources res = pm.getResourcesForApplication(si.applicationInfo); - AttributeSet attrs = Xml.asAttributeSet(parser); - if (onHost) { - TypedArray sa = res.obtainAttributes(attrs, - com.android.internal.R.styleable.HostApduService); - mService = info; - mDescription = sa.getString( - com.android.internal.R.styleable.HostApduService_description); - mRequiresDeviceUnlock = sa.getBoolean( - com.android.internal.R.styleable.HostApduService_requireDeviceUnlock, - false); - mRequiresDeviceScreenOn = sa.getBoolean( - com.android.internal.R.styleable.HostApduService_requireDeviceScreenOn, - true); - mBannerResourceId = sa.getResourceId( - com.android.internal.R.styleable.HostApduService_apduServiceBanner, -1); - mSettingsActivityName = sa.getString( - com.android.internal.R.styleable.HostApduService_settingsActivity); - mOffHostName = null; - mStaticOffHostName = mOffHostName; - mShouldDefaultToObserveMode = sa.getBoolean( - R.styleable.HostApduService_shouldDefaultToObserveMode, - false); - if (Flags.nfcAssociatedRoleServices()) { - mShareRolePriority = sa.getBoolean( - R.styleable.HostApduService_shareRolePriority, - false - ); - } - sa.recycle(); - } else { - TypedArray sa = res.obtainAttributes(attrs, - com.android.internal.R.styleable.OffHostApduService); - mService = info; - mDescription = sa.getString( - com.android.internal.R.styleable.OffHostApduService_description); - mRequiresDeviceUnlock = sa.getBoolean( - com.android.internal.R.styleable.OffHostApduService_requireDeviceUnlock, - false); - mRequiresDeviceScreenOn = sa.getBoolean( - com.android.internal.R.styleable.OffHostApduService_requireDeviceScreenOn, - false); - mBannerResourceId = sa.getResourceId( - com.android.internal.R.styleable.OffHostApduService_apduServiceBanner, -1); - mSettingsActivityName = sa.getString( - com.android.internal.R.styleable.HostApduService_settingsActivity); - mOffHostName = sa.getString( - com.android.internal.R.styleable.OffHostApduService_secureElementName); - mShouldDefaultToObserveMode = sa.getBoolean( - R.styleable.OffHostApduService_shouldDefaultToObserveMode, - false); - if (mOffHostName != null) { - if (mOffHostName.equals("eSE")) { - mOffHostName = "eSE1"; - } else if (mOffHostName.equals("SIM")) { - mOffHostName = "SIM1"; - } - } - mStaticOffHostName = mOffHostName; - if (Flags.nfcAssociatedRoleServices()) { - mShareRolePriority = sa.getBoolean( - R.styleable.OffHostApduService_shareRolePriority, - false - ); - } - sa.recycle(); - } - - mStaticAidGroups = new HashMap<String, AidGroup>(); - mDynamicAidGroups = new HashMap<String, AidGroup>(); - mAutoTransact = new HashMap<String, Boolean>(); - mAutoTransactPatterns = new TreeMap<Pattern, Boolean>( - Comparator.comparing(Pattern::toString)); - mOnHost = onHost; - - final int depth = parser.getDepth(); - AidGroup currentGroup = null; - - // Parsed values for the current AID group - while (((eventType = parser.next()) != XmlPullParser.END_TAG || parser.getDepth() > depth) - && eventType != XmlPullParser.END_DOCUMENT) { - tagName = parser.getName(); - if (eventType == XmlPullParser.START_TAG && "aid-group".equals(tagName) && - currentGroup == null) { - final TypedArray groupAttrs = res.obtainAttributes(attrs, - com.android.internal.R.styleable.AidGroup); - // Get category of AID group - String groupCategory = groupAttrs.getString( - com.android.internal.R.styleable.AidGroup_category); - String groupDescription = groupAttrs.getString( - com.android.internal.R.styleable.AidGroup_description); - if (!CardEmulation.CATEGORY_PAYMENT.equals(groupCategory)) { - groupCategory = CardEmulation.CATEGORY_OTHER; - } - currentGroup = mStaticAidGroups.get(groupCategory); - if (currentGroup != null) { - if (!CardEmulation.CATEGORY_OTHER.equals(groupCategory)) { - Log.e(TAG, "Not allowing multiple aid-groups in the " + - groupCategory + " category"); - currentGroup = null; - } - } else { - currentGroup = new AidGroup(groupCategory, groupDescription); - } - groupAttrs.recycle(); - } else if (eventType == XmlPullParser.END_TAG && "aid-group".equals(tagName) && - currentGroup != null) { - if (currentGroup.getAids().size() > 0) { - if (!mStaticAidGroups.containsKey(currentGroup.getCategory())) { - mStaticAidGroups.put(currentGroup.getCategory(), currentGroup); - } - } else { - Log.e(TAG, "Not adding <aid-group> with empty or invalid AIDs"); - } - currentGroup = null; - } else if (eventType == XmlPullParser.START_TAG && "aid-filter".equals(tagName) && - currentGroup != null) { - final TypedArray a = res.obtainAttributes(attrs, - com.android.internal.R.styleable.AidFilter); - String aid = a.getString(com.android.internal.R.styleable.AidFilter_name). - toUpperCase(); - if (isValidAid(aid) && !currentGroup.getAids().contains(aid)) { - currentGroup.getAids().add(aid); - } else { - Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid); - } - a.recycle(); - } else if (eventType == XmlPullParser.START_TAG && - "aid-prefix-filter".equals(tagName) && currentGroup != null) { - final TypedArray a = res.obtainAttributes(attrs, - com.android.internal.R.styleable.AidFilter); - String aid = a.getString(com.android.internal.R.styleable.AidFilter_name). - toUpperCase(); - // Add wildcard char to indicate prefix - aid = aid.concat("*"); - if (isValidAid(aid) && !currentGroup.getAids().contains(aid)) { - currentGroup.getAids().add(aid); - } else { - Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid); - } - a.recycle(); - } else if (eventType == XmlPullParser.START_TAG && - tagName.equals("aid-suffix-filter") && currentGroup != null) { - final TypedArray a = res.obtainAttributes(attrs, - com.android.internal.R.styleable.AidFilter); - String aid = a.getString(com.android.internal.R.styleable.AidFilter_name). - toUpperCase(); - // Add wildcard char to indicate suffix - aid = aid.concat("#"); - if (isValidAid(aid) && !currentGroup.getAids().contains(aid)) { - currentGroup.getAids().add(aid); - } else { - Log.e(TAG, "Ignoring invalid or duplicate aid: " + aid); - } - a.recycle(); - } else if (eventType == XmlPullParser.START_TAG - && "polling-loop-filter".equals(tagName) && currentGroup == null) { - final TypedArray a = res.obtainAttributes(attrs, - com.android.internal.R.styleable.PollingLoopFilter); - String plf = - a.getString(com.android.internal.R.styleable.PollingLoopFilter_name) - .toUpperCase(Locale.ROOT); - boolean autoTransact = a.getBoolean( - com.android.internal.R.styleable.PollingLoopFilter_autoTransact, - false); - if (!mOnHost && !autoTransact) { - Log.e(TAG, "Ignoring polling-loop-filter " + plf - + " for offhost service that isn't autoTransact"); - } else { - mAutoTransact.put(plf, autoTransact); - } - a.recycle(); - } else if (eventType == XmlPullParser.START_TAG - && "polling-loop-pattern-filter".equals(tagName) && currentGroup == null) { - final TypedArray a = res.obtainAttributes(attrs, - com.android.internal.R.styleable.PollingLoopPatternFilter); - String plf = a.getString( - com.android.internal.R.styleable.PollingLoopPatternFilter_name) - .toUpperCase(Locale.ROOT); - boolean autoTransact = a.getBoolean( - com.android.internal.R.styleable.PollingLoopFilter_autoTransact, - false); - if (!mOnHost && !autoTransact) { - Log.e(TAG, "Ignoring polling-loop-filter " + plf - + " for offhost service that isn't autoTransact"); - } else { - mAutoTransactPatterns.put(Pattern.compile(plf), autoTransact); - } - a.recycle(); - } - } - } catch (NameNotFoundException e) { - throw new XmlPullParserException("Unable to create context for: " + si.packageName); - } finally { - if (parser != null) parser.close(); - } - // Set uid - mUid = si.applicationInfo.uid; - - mCategoryOtherServiceEnabled = true; // support other category - - } - - /** - * Returns the app component corresponding to this APDU service. - * - * @return app component for this service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public ComponentName getComponent() { - return new ComponentName(mService.serviceInfo.packageName, - mService.serviceInfo.name); - } - - /** - * Returns the offhost secure element name (if the service is offhost). - * - * @return offhost secure element name for offhost services - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @Nullable - public String getOffHostSecureElement() { - return mOffHostName; - } - - /** - * Returns a consolidated list of AIDs from the AID groups - * registered by this service. Note that if a service has both - * a static (manifest-based) AID group for a category and a dynamic - * AID group, only the dynamically registered AIDs will be returned - * for that category. - * @return List of AIDs registered by the service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public List<String> getAids() { - final ArrayList<String> aids = new ArrayList<String>(); - for (AidGroup group : getAidGroups()) { - aids.addAll(group.getAids()); - } - return aids; - } - - /** - * Returns the current polling loop filters for this service. - * @return List of polling loop filters. - */ - @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) - @NonNull - public List<String> getPollingLoopFilters() { - return new ArrayList<>(mAutoTransact.keySet()); - } - - /** - * Returns whether this service would like to automatically transact for a given plf. - * - * @param plf the polling loop filter to query. - * @return {@code true} indicating to auto transact, {@code false} indicating to not. - */ - @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) - public boolean getShouldAutoTransact(@NonNull String plf) { - if (mAutoTransact.getOrDefault(plf.toUpperCase(Locale.ROOT), false)) { - return true; - } - List<Pattern> patternMatches = mAutoTransactPatterns.keySet().stream() - .filter(p -> p.matcher(plf).matches()).toList(); - if (patternMatches == null || patternMatches.size() == 0) { - return false; - } - for (Pattern patternMatch : patternMatches) { - if (mAutoTransactPatterns.get(patternMatch)) { - return true; - } - } - return false; - } - - /** - * Returns the current polling loop pattern filters for this service. - * @return List of polling loop pattern filters. - */ - @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) - @NonNull - public List<Pattern> getPollingLoopPatternFilters() { - return new ArrayList<>(mAutoTransactPatterns.keySet()); - } - - /** - * Returns a consolidated list of AIDs with prefixes from the AID groups - * registered by this service. Note that if a service has both - * a static (manifest-based) AID group for a category and a dynamic - * AID group, only the dynamically registered AIDs will be returned - * for that category. - * @return List of prefix AIDs registered by the service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public List<String> getPrefixAids() { - final ArrayList<String> prefixAids = new ArrayList<String>(); - for (AidGroup group : getAidGroups()) { - for (String aid : group.getAids()) { - if (aid.endsWith("*")) { - prefixAids.add(aid); - } - } - } - return prefixAids; - } - - /** - * Returns a consolidated list of AIDs with subsets from the AID groups - * registered by this service. Note that if a service has both - * a static (manifest-based) AID group for a category and a dynamic - * AID group, only the dynamically registered AIDs will be returned - * for that category. - * @return List of prefix AIDs registered by the service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public List<String> getSubsetAids() { - final ArrayList<String> subsetAids = new ArrayList<String>(); - for (AidGroup group : getAidGroups()) { - for (String aid : group.getAids()) { - if (aid.endsWith("#")) { - subsetAids.add(aid); - } - } - } - return subsetAids; - } - - /** - * Returns the registered AID group for this category. - * - * @param category category name - * @return {@link AidGroup} instance for the provided category - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public AidGroup getDynamicAidGroupForCategory(@NonNull String category) { - return mDynamicAidGroups.get(category); - } - - /** - * Removes the registered AID group for this category. - * - * @param category category name - * @return {@code true} if an AID group existed - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public boolean removeDynamicAidGroupForCategory(@NonNull String category) { - return (mDynamicAidGroups.remove(category) != null); - } - - /** - * Returns a consolidated list of AID groups - * registered by this service. Note that if a service has both - * a static (manifest-based) AID group for a category and a dynamic - * AID group, only the dynamically registered AID group will be returned - * for that category. - * @return List of AIDs registered by the service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public List<AidGroup> getAidGroups() { - final ArrayList<AidGroup> groups = new ArrayList<AidGroup>(); - for (Map.Entry<String, AidGroup> entry : mDynamicAidGroups.entrySet()) { - groups.add(entry.getValue()); - } - for (Map.Entry<String, AidGroup> entry : mStaticAidGroups.entrySet()) { - if (!mDynamicAidGroups.containsKey(entry.getKey())) { - // Consolidate AID groups - don't return static ones - // if a dynamic group exists for the category. - groups.add(entry.getValue()); - } - } - return groups; - } - - /** - * Returns the category to which this service has attributed the AID that is passed in, - * or null if we don't know this AID. - * @param aid AID to lookup for - * @return category name corresponding to this AID - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public String getCategoryForAid(@NonNull String aid) { - List<AidGroup> groups = getAidGroups(); - for (AidGroup group : groups) { - if (group.getAids().contains(aid.toUpperCase())) { - return group.getCategory(); - } - } - return null; - } - - /** - * Returns whether there is any AID group for this category. - * @param category category name - * @return {@code true} if an AID group exists - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public boolean hasCategory(@NonNull String category) { - return (mStaticAidGroups.containsKey(category) || mDynamicAidGroups.containsKey(category)); - } - - /** - * Returns whether the service is on host or not. - * @return true if the service is on host (not secure element) - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public boolean isOnHost() { - return mOnHost; - } - - /** - * Returns whether the service requires device unlock. - * @return whether the service requires device unlock - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public boolean requiresUnlock() { - return mRequiresDeviceUnlock; - } - - /** - * Returns whether this service should only be started when the device is screen on. - * @return whether the service requires screen on - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public boolean requiresScreenOn() { - return mRequiresDeviceScreenOn; - } - - /** - * Returns whether the NFC stack should default to observe mode when this service is preferred. - * @return whether the NFC stack should default to observe mode when this service is preferred - */ - @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE) - public boolean shouldDefaultToObserveMode() { - return mShouldDefaultToObserveMode; - } - - /** - * Sets whether the NFC stack should default to observe mode when this service is preferred. - * @param shouldDefaultToObserveMode whether the NFC stack should default to observe mode when - * this service is preferred - */ - @FlaggedApi(Flags.FLAG_NFC_OBSERVE_MODE) - public void setShouldDefaultToObserveMode(boolean shouldDefaultToObserveMode) { - mShouldDefaultToObserveMode = shouldDefaultToObserveMode; - } - - /** - * Returns whether or not this service wants to share the Wallet role holder priority - * with other packages/services with the same signature. - * - * @return whether or not this service wants to share priority - */ - @FlaggedApi(Flags.FLAG_NFC_ASSOCIATED_ROLE_SERVICES) - public boolean shareRolePriority() { - return mShareRolePriority; - } - - /** - * Returns description of service. - * @return user readable description of service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public String getDescription() { - return mDescription; - } - - /** - * Returns uid of service. - * @return uid of the service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public int getUid() { - return mUid; - } - - /** - * Add or replace an AID group to this service. - * @param aidGroup instance of aid group to set or replace - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void setDynamicAidGroup(@NonNull AidGroup aidGroup) { - mDynamicAidGroups.put(aidGroup.getCategory(), aidGroup); - } - - /** - * Add a Polling Loop Filter. Custom NFC polling frames that match this filter will be - * delivered to {@link HostApduService#processPollingFrames(List)}. Adding a key with this - * multiple times will cause the value to be overwritten each time. - * @param pollingLoopFilter the polling loop filter to add, must be a valid hexadecimal string - * @param autoTransact when true, disable observe mode when this filter matches, when false, - * matching does not change the observe mode state - */ - @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) - public void addPollingLoopFilter(@NonNull String pollingLoopFilter, - boolean autoTransact) { - if (!mOnHost && !autoTransact) { - return; - } - mAutoTransact.put(pollingLoopFilter, autoTransact); - } - - /** - * Remove a Polling Loop Filter. Custom NFC polling frames that match this filter will no - * longer be delivered to {@link HostApduService#processPollingFrames(List)}. - * @param pollingLoopFilter this polling loop filter to add. - */ - @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) - public void removePollingLoopFilter(@NonNull String pollingLoopFilter) { - mAutoTransact.remove(pollingLoopFilter.toUpperCase(Locale.ROOT)); - } - - /** - * Add a Polling Loop Pattern Filter. Custom NFC polling frames that match this filter will be - * delivered to {@link HostApduService#processPollingFrames(List)}. Adding a key with this - * multiple times will cause the value to be overwritten each time. - * @param pollingLoopPatternFilter the polling loop pattern filter to add, must be a valid - * regex to match a hexadecimal string - * @param autoTransact when true, disable observe mode when this filter matches, when false, - * matching does not change the observe mode state - */ - @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) - public void addPollingLoopPatternFilter(@NonNull String pollingLoopPatternFilter, - boolean autoTransact) { - if (!mOnHost && !autoTransact) { - return; - } - mAutoTransactPatterns.put(Pattern.compile(pollingLoopPatternFilter), autoTransact); - } - - /** - * Remove a Polling Loop Pattern Filter. Custom NFC polling frames that match this filter will - * no longer be delivered to {@link HostApduService#processPollingFrames(List)}. - * @param pollingLoopPatternFilter this polling loop filter to add. - */ - @FlaggedApi(Flags.FLAG_NFC_READ_POLLING_LOOP) - public void removePollingLoopPatternFilter(@NonNull String pollingLoopPatternFilter) { - mAutoTransactPatterns.remove( - Pattern.compile(pollingLoopPatternFilter.toUpperCase(Locale.ROOT))); - } - - /** - * Sets the off host Secure Element. - * @param offHost Secure Element to set. Only accept strings with prefix SIM or prefix eSE. - * Ref: GSMA TS.26 - NFC Handset Requirements - * TS26_NFC_REQ_069: For UICC, Secure Element Name SHALL be SIM[smartcard slot] - * (e.g. SIM/SIM1, SIM2… SIMn). - * TS26_NFC_REQ_070: For embedded SE, Secure Element Name SHALL be eSE[number] - * (e.g. eSE/eSE1, eSE2, etc.). - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void setOffHostSecureElement(@NonNull String offHost) { - mOffHostName = offHost; - } - - /** - * Resets the off host Secure Element to statically defined - * by the service in the manifest file. - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void resetOffHostSecureElement() { - mOffHostName = mStaticOffHostName; - } - - /** - * Load label for this service. - * @param pm packagemanager instance - * @return label name corresponding to service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public CharSequence loadLabel(@NonNull PackageManager pm) { - return mService.loadLabel(pm); - } - - /** - * Load application label for this service. - * @param pm packagemanager instance - * @return app label name corresponding to service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public CharSequence loadAppLabel(@NonNull PackageManager pm) { - try { - return pm.getApplicationLabel(pm.getApplicationInfo( - mService.resolvePackageName, PackageManager.GET_META_DATA)); - } catch (PackageManager.NameNotFoundException e) { - return null; - } - } - - /** - * Load application icon for this service. - * @param pm packagemanager instance - * @return app icon corresponding to service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public Drawable loadIcon(@NonNull PackageManager pm) { - return mService.loadIcon(pm); - } - - /** - * Load application banner for this service. - * @param pm packagemanager instance - * @return app banner corresponding to service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public Drawable loadBanner(@NonNull PackageManager pm) { - Resources res; - try { - res = pm.getResourcesForApplication(mService.serviceInfo.packageName); - Drawable banner = res.getDrawable(mBannerResourceId); - return banner; - } catch (NotFoundException e) { - Log.e(TAG, "Could not load banner."); - return null; - } catch (NameNotFoundException e) { - Log.e(TAG, "Could not load banner."); - return null; - } - } - - /** - * Load activity name for this service. - * @return activity name for this service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public String getSettingsActivityName() { return mSettingsActivityName; } - - @Override - public String toString() { - StringBuilder out = new StringBuilder("ApduService: "); - out.append(getComponent()); - out.append(", UID: " + mUid); - out.append(", description: " + mDescription); - out.append(", Static AID Groups: "); - for (AidGroup aidGroup : mStaticAidGroups.values()) { - out.append(aidGroup.toString()); - } - out.append(", Dynamic AID Groups: "); - for (AidGroup aidGroup : mDynamicAidGroups.values()) { - out.append(aidGroup.toString()); - } - return out.toString(); - } - - @Override - public boolean equals(@Nullable Object o) { - if (this == o) return true; - if (!(o instanceof ApduServiceInfo)) return false; - ApduServiceInfo thatService = (ApduServiceInfo) o; - - return thatService.getComponent().equals(this.getComponent()) - && thatService.getUid() == this.getUid(); - } - - @Override - public int hashCode() { - return getComponent().hashCode(); - } - - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @Override - public int describeContents() { - return 0; - } - - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - mService.writeToParcel(dest, flags); - dest.writeString(mDescription); - dest.writeInt(mOnHost ? 1 : 0); - dest.writeString(mOffHostName); - dest.writeString(mStaticOffHostName); - dest.writeInt(mStaticAidGroups.size()); - if (mStaticAidGroups.size() > 0) { - dest.writeTypedList(new ArrayList<AidGroup>(mStaticAidGroups.values())); - } - dest.writeInt(mDynamicAidGroups.size()); - if (mDynamicAidGroups.size() > 0) { - dest.writeTypedList(new ArrayList<AidGroup>(mDynamicAidGroups.values())); - } - dest.writeInt(mRequiresDeviceUnlock ? 1 : 0); - dest.writeInt(mRequiresDeviceScreenOn ? 1 : 0); - dest.writeInt(mBannerResourceId); - dest.writeInt(mUid); - dest.writeString(mSettingsActivityName); - - dest.writeInt(mCategoryOtherServiceEnabled ? 1 : 0); - dest.writeInt(mAutoTransact.size()); - dest.writeMap(mAutoTransact); - dest.writeInt(mAutoTransactPatterns.size()); - dest.writeMap(mAutoTransactPatterns); - }; - - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public static final @NonNull Parcelable.Creator<ApduServiceInfo> CREATOR = - new Parcelable.Creator<ApduServiceInfo>() { - @Override - public ApduServiceInfo createFromParcel(Parcel source) { - ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source); - String description = source.readString(); - boolean onHost = source.readInt() != 0; - String offHostName = source.readString(); - String staticOffHostName = source.readString(); - ArrayList<AidGroup> staticAidGroups = new ArrayList<AidGroup>(); - int numStaticGroups = source.readInt(); - if (numStaticGroups > 0) { - source.readTypedList(staticAidGroups, AidGroup.CREATOR); - } - ArrayList<AidGroup> dynamicAidGroups = new ArrayList<AidGroup>(); - int numDynamicGroups = source.readInt(); - if (numDynamicGroups > 0) { - source.readTypedList(dynamicAidGroups, AidGroup.CREATOR); - } - boolean requiresUnlock = source.readInt() != 0; - boolean requiresScreenOn = source.readInt() != 0; - int bannerResource = source.readInt(); - int uid = source.readInt(); - String settingsActivityName = source.readString(); - boolean isEnabled = source.readInt() != 0; - int autoTransactSize = source.readInt(); - HashMap<String, Boolean> autoTransact = - new HashMap<String, Boolean>(autoTransactSize); - source.readMap(autoTransact, getClass().getClassLoader(), - String.class, Boolean.class); - int autoTransactPatternSize = source.readInt(); - HashMap<Pattern, Boolean> autoTransactPatterns = - new HashMap<Pattern, Boolean>(autoTransactSize); - source.readMap(autoTransactPatterns, getClass().getClassLoader(), - Pattern.class, Boolean.class); - return new ApduServiceInfo(info, onHost, description, staticAidGroups, - dynamicAidGroups, requiresUnlock, requiresScreenOn, bannerResource, uid, - settingsActivityName, offHostName, staticOffHostName, - isEnabled, autoTransact, autoTransactPatterns); - } - - @Override - public ApduServiceInfo[] newArray(int size) { - return new ApduServiceInfo[size]; - } - }; - - /** - * Dump contents for debugging. - * @param fd parcelfiledescriptor instance - * @param pw printwriter instance - * @param args args for dumping - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void dump(@NonNull ParcelFileDescriptor fd, @NonNull PrintWriter pw, - @NonNull String[] args) { - pw.println(" " + getComponent() - + " (Description: " + getDescription() + ")" - + " (UID: " + getUid() + ")"); - if (mOnHost) { - pw.println(" On Host Service"); - } else { - pw.println(" Off-host Service"); - pw.println(" " + "Current off-host SE:" + mOffHostName - + " static off-host SE:" + mStaticOffHostName); - } - pw.println(" Static AID groups:"); - for (AidGroup group : mStaticAidGroups.values()) { - pw.println(" Category: " + group.getCategory() - + "(enabled: " + mCategoryOtherServiceEnabled + ")"); - for (String aid : group.getAids()) { - pw.println(" AID: " + aid); - } - } - pw.println(" Dynamic AID groups:"); - for (AidGroup group : mDynamicAidGroups.values()) { - pw.println(" Category: " + group.getCategory() - + "(enabled: " + mCategoryOtherServiceEnabled + ")"); - for (String aid : group.getAids()) { - pw.println(" AID: " + aid); - } - } - pw.println(" Settings Activity: " + mSettingsActivityName); - pw.println(" Requires Device Unlock: " + mRequiresDeviceUnlock); - pw.println(" Requires Device ScreenOn: " + mRequiresDeviceScreenOn); - pw.println(" Should Default to Observe Mode: " + mShouldDefaultToObserveMode); - pw.println(" Auto-Transact Mapping: " + mAutoTransact); - pw.println(" Auto-Transact Patterns: " + mAutoTransactPatterns); - } - - - /** - * Enable or disable this CATEGORY_OTHER service. - * - * @param enabled true to indicate if user has enabled this service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void setCategoryOtherServiceEnabled(boolean enabled) { - mCategoryOtherServiceEnabled = enabled; - } - - - /** - * Returns whether this CATEGORY_OTHER service is enabled or not. - * - * @return true to indicate if user has enabled this service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public boolean isCategoryOtherServiceEnabled() { - return mCategoryOtherServiceEnabled; - } - - /** - * Dump debugging info as ApduServiceInfoProto. - * - * If the output belongs to a sub message, the caller is responsible for wrapping this function - * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}. - * See proto definition in frameworks/base/core/proto/android/nfc/apdu_service_info.proto - * - * @param proto the ProtoOutputStream to write to - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void dumpDebug(@NonNull ProtoOutputStream proto) { - getComponent().dumpDebug(proto, ApduServiceInfoProto.COMPONENT_NAME); - proto.write(ApduServiceInfoProto.DESCRIPTION, getDescription()); - proto.write(ApduServiceInfoProto.ON_HOST, mOnHost); - if (!mOnHost) { - proto.write(ApduServiceInfoProto.OFF_HOST_NAME, mOffHostName); - proto.write(ApduServiceInfoProto.STATIC_OFF_HOST_NAME, mStaticOffHostName); - } - for (AidGroup group : mStaticAidGroups.values()) { - long token = proto.start(ApduServiceInfoProto.STATIC_AID_GROUPS); - group.dump(proto); - proto.end(token); - } - for (AidGroup group : mDynamicAidGroups.values()) { - long token = proto.start(ApduServiceInfoProto.STATIC_AID_GROUPS); - group.dump(proto); - proto.end(token); - } - proto.write(ApduServiceInfoProto.SETTINGS_ACTIVITY_NAME, mSettingsActivityName); - proto.write(ApduServiceInfoProto.SHOULD_DEFAULT_TO_OBSERVE_MODE, - mShouldDefaultToObserveMode); - { - long token = proto.start(ApduServiceInfoProto.AUTO_TRANSACT_MAPPING); - for (Map.Entry<String, Boolean> entry : mAutoTransact.entrySet()) { - proto.write(ApduServiceInfoProto.AutoTransactMapping.AID, entry.getKey()); - proto.write(ApduServiceInfoProto.AutoTransactMapping.SHOULD_AUTO_TRANSACT, - entry.getValue()); - } - proto.end(token); - } - { - long token = proto.start(ApduServiceInfoProto.AUTO_TRANSACT_PATTERNS); - for (Map.Entry<Pattern, Boolean> entry : mAutoTransactPatterns.entrySet()) { - proto.write(ApduServiceInfoProto.AutoTransactPattern.REGEXP_PATTERN, - entry.getKey().pattern()); - proto.write(ApduServiceInfoProto.AutoTransactPattern.SHOULD_AUTO_TRANSACT, - entry.getValue()); - } - proto.end(token); - } - } - - private static final Pattern AID_PATTERN = Pattern.compile("[0-9A-Fa-f]{10,32}\\*?\\#?"); - /** - * Copied over from {@link CardEmulation#isValidAid(String)} - * @hide - */ - private static boolean isValidAid(String aid) { - if (aid == null) - return false; - - // If a prefix/subset AID, the total length must be odd (even # of AID chars + '*') - if ((aid.endsWith("*") || aid.endsWith("#")) && ((aid.length() % 2) == 0)) { - Log.e(TAG, "AID " + aid + " is not a valid AID."); - return false; - } - - // If not a prefix/subset AID, the total length must be even (even # of AID chars) - if ((!(aid.endsWith("*") || aid.endsWith("#"))) && ((aid.length() % 2) != 0)) { - Log.e(TAG, "AID " + aid + " is not a valid AID."); - return false; - } - - // Verify hex characters - if (!AID_PATTERN.matcher(aid).matches()) { - Log.e(TAG, "AID " + aid + " is not a valid AID."); - return false; - } - - return true; - } -} diff --git a/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.aidl b/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.aidl deleted file mode 100644 index 56b98ebd90fa..000000000000 --- a/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.aidl +++ /dev/null @@ -1,19 +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 android.nfc.cardemulation; - -parcelable NfcFServiceInfo; diff --git a/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.java b/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.java deleted file mode 100644 index 33bc16978721..000000000000 --- a/nfc-non-updatable/java/android/nfc/cardemulation/NfcFServiceInfo.java +++ /dev/null @@ -1,497 +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. - */ - -/********************************************************************** - * This file is not a part of the NFC mainline module * - * *******************************************************************/ - -package android.nfc.cardemulation; - -import android.annotation.FlaggedApi; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.SystemApi; -import android.content.ComponentName; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; -import android.graphics.drawable.Drawable; -import android.nfc.Flags; -import android.os.Parcel; -import android.os.ParcelFileDescriptor; -import android.os.Parcelable; -import android.util.AttributeSet; -import android.util.Log; -import android.util.Xml; -import android.util.proto.ProtoOutputStream; - -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; - -import java.io.IOException; -import java.io.PrintWriter; - -/** - * Class to hold NfcF service info. - * - * @hide - */ -@SystemApi -@FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) -public final class NfcFServiceInfo implements Parcelable { - static final String TAG = "NfcFServiceInfo"; - - private static final String DEFAULT_T3T_PMM = "FFFFFFFFFFFFFFFF"; - - /** - * The service that implements this - */ - private final ResolveInfo mService; - - /** - * Description of the service - */ - private final String mDescription; - - /** - * System Code of the service - */ - private final String mSystemCode; - - /** - * System Code of the service registered by API - */ - private String mDynamicSystemCode; - - /** - * NFCID2 of the service - */ - private final String mNfcid2; - - /** - * NFCID2 of the service registered by API - */ - private String mDynamicNfcid2; - - /** - * The uid of the package the service belongs to - */ - private final int mUid; - - /** - * LF_T3T_PMM of the service - */ - private final String mT3tPmm; - - /** - * @hide - */ - public NfcFServiceInfo(ResolveInfo info, String description, - String systemCode, String dynamicSystemCode, String nfcid2, String dynamicNfcid2, - int uid, String t3tPmm) { - this.mService = info; - this.mDescription = description; - this.mSystemCode = systemCode; - this.mDynamicSystemCode = dynamicSystemCode; - this.mNfcid2 = nfcid2; - this.mDynamicNfcid2 = dynamicNfcid2; - this.mUid = uid; - this.mT3tPmm = t3tPmm; - } - - /** - * Creates a new NfcFServiceInfo object. - * - * @param pm packageManager instance - * @param info app component info - * @throws XmlPullParserException If an error occurs parsing the element. - * @throws IOException If an error occurs reading the element. - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public NfcFServiceInfo(@NonNull PackageManager pm, @NonNull ResolveInfo info) - throws XmlPullParserException, IOException { - ServiceInfo si = info.serviceInfo; - XmlResourceParser parser = null; - try { - parser = si.loadXmlMetaData(pm, HostNfcFService.SERVICE_META_DATA); - if (parser == null) { - throw new XmlPullParserException("No " + HostNfcFService.SERVICE_META_DATA + - " meta-data"); - } - - int eventType = parser.getEventType(); - while (eventType != XmlPullParser.START_TAG && - eventType != XmlPullParser.END_DOCUMENT) { - eventType = parser.next(); - } - - String tagName = parser.getName(); - if (!"host-nfcf-service".equals(tagName)) { - throw new XmlPullParserException( - "Meta-data does not start with <host-nfcf-service> tag"); - } - - Resources res = pm.getResourcesForApplication(si.applicationInfo); - AttributeSet attrs = Xml.asAttributeSet(parser); - TypedArray sa = res.obtainAttributes(attrs, - com.android.internal.R.styleable.HostNfcFService); - mService = info; - mDescription = sa.getString( - com.android.internal.R.styleable.HostNfcFService_description); - mDynamicSystemCode = null; - mDynamicNfcid2 = null; - sa.recycle(); - - String systemCode = null; - String nfcid2 = null; - String t3tPmm = null; - final int depth = parser.getDepth(); - - while (((eventType = parser.next()) != XmlPullParser.END_TAG || - parser.getDepth() > depth) && eventType != XmlPullParser.END_DOCUMENT) { - tagName = parser.getName(); - if (eventType == XmlPullParser.START_TAG && - "system-code-filter".equals(tagName) && systemCode == null) { - final TypedArray a = res.obtainAttributes(attrs, - com.android.internal.R.styleable.SystemCodeFilter); - systemCode = a.getString( - com.android.internal.R.styleable.SystemCodeFilter_name).toUpperCase(); - if (!isValidSystemCode(systemCode) && - !systemCode.equalsIgnoreCase("NULL")) { - Log.e(TAG, "Invalid System Code: " + systemCode); - systemCode = null; - } - a.recycle(); - } else if (eventType == XmlPullParser.START_TAG && - "nfcid2-filter".equals(tagName) && nfcid2 == null) { - final TypedArray a = res.obtainAttributes(attrs, - com.android.internal.R.styleable.Nfcid2Filter); - nfcid2 = a.getString( - com.android.internal.R.styleable.Nfcid2Filter_name).toUpperCase(); - if (!nfcid2.equalsIgnoreCase("RANDOM") && - !nfcid2.equalsIgnoreCase("NULL") && - !isValidNfcid2(nfcid2)) { - Log.e(TAG, "Invalid NFCID2: " + nfcid2); - nfcid2 = null; - } - a.recycle(); - } else if (eventType == XmlPullParser.START_TAG && tagName.equals("t3tPmm-filter") - && t3tPmm == null) { - final TypedArray a = res.obtainAttributes(attrs, - com.android.internal.R.styleable.T3tPmmFilter); - t3tPmm = a.getString( - com.android.internal.R.styleable.T3tPmmFilter_name).toUpperCase(); - a.recycle(); - } - } - mSystemCode = (systemCode == null ? "NULL" : systemCode); - mNfcid2 = (nfcid2 == null ? "NULL" : nfcid2); - mT3tPmm = (t3tPmm == null ? DEFAULT_T3T_PMM : t3tPmm); - } catch (NameNotFoundException e) { - throw new XmlPullParserException("Unable to create context for: " + si.packageName); - } finally { - if (parser != null) parser.close(); - } - // Set uid - mUid = si.applicationInfo.uid; - } - - /** - * Returns the app component corresponding to this NFCF service. - * - * @return app component for this service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public ComponentName getComponent() { - return new ComponentName(mService.serviceInfo.packageName, - mService.serviceInfo.name); - } - - /** - * Returns the system code corresponding to this service. - * - * @return system code for this service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public String getSystemCode() { - return (mDynamicSystemCode == null ? mSystemCode : mDynamicSystemCode); - } - - /** - * Add or replace a system code to this service. - * @param systemCode system code to set or replace - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void setDynamicSystemCode(@NonNull String systemCode) { - mDynamicSystemCode = systemCode; - } - - /** - * Returns NFC ID2. - * - * @return nfc id2 to return - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public String getNfcid2() { - return (mDynamicNfcid2 == null ? mNfcid2 : mDynamicNfcid2); - } - - /** - * Set or replace NFC ID2 - * - * @param nfcid2 NFC ID2 string - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void setDynamicNfcid2(@NonNull String nfcid2) { - mDynamicNfcid2 = nfcid2; - } - - /** - * Returns description of service. - * @return user readable description of service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public String getDescription() { - return mDescription; - } - - /** - * Returns uid of service. - * @return uid of the service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public int getUid() { - return mUid; - } - - /** - * Returns LF_T3T_PMM of the service - * @return returns LF_T3T_PMM of the service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public String getT3tPmm() { - return mT3tPmm; - } - - /** - * Load application label for this service. - * @param pm packagemanager instance - * @return label name corresponding to service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public CharSequence loadLabel(@NonNull PackageManager pm) { - return mService.loadLabel(pm); - } - - /** - * Load application icon for this service. - * @param pm packagemanager instance - * @return app icon corresponding to service - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @NonNull - public Drawable loadIcon(@NonNull PackageManager pm) { - return mService.loadIcon(pm); - } - - @Override - public String toString() { - StringBuilder out = new StringBuilder("NfcFService: "); - out.append(getComponent()); - out.append(", UID: " + mUid); - out.append(", description: " + mDescription); - out.append(", System Code: " + mSystemCode); - if (mDynamicSystemCode != null) { - out.append(", dynamic System Code: " + mDynamicSystemCode); - } - out.append(", NFCID2: " + mNfcid2); - if (mDynamicNfcid2 != null) { - out.append(", dynamic NFCID2: " + mDynamicNfcid2); - } - out.append(", T3T PMM:" + mT3tPmm); - return out.toString(); - } - - @Override - public boolean equals(@Nullable Object o) { - if (this == o) return true; - if (!(o instanceof NfcFServiceInfo)) return false; - NfcFServiceInfo thatService = (NfcFServiceInfo) o; - - if (!thatService.getComponent().equals(this.getComponent())) return false; - if (thatService.getUid() != this.getUid()) return false; - if (!thatService.mSystemCode.equalsIgnoreCase(this.mSystemCode)) return false; - if (!thatService.mNfcid2.equalsIgnoreCase(this.mNfcid2)) return false; - if (!thatService.mT3tPmm.equalsIgnoreCase(this.mT3tPmm)) return false; - return true; - } - - @Override - public int hashCode() { - return getComponent().hashCode(); - } - - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @Override - public int describeContents() { - return 0; - } - - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - @Override - public void writeToParcel(@NonNull Parcel dest, int flags) { - mService.writeToParcel(dest, flags); - dest.writeString(mDescription); - dest.writeString(mSystemCode); - dest.writeInt(mDynamicSystemCode != null ? 1 : 0); - if (mDynamicSystemCode != null) { - dest.writeString(mDynamicSystemCode); - } - dest.writeString(mNfcid2); - dest.writeInt(mDynamicNfcid2 != null ? 1 : 0); - if (mDynamicNfcid2 != null) { - dest.writeString(mDynamicNfcid2); - } - dest.writeInt(mUid); - dest.writeString(mT3tPmm); - }; - - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public static final @NonNull Parcelable.Creator<NfcFServiceInfo> CREATOR = - new Parcelable.Creator<NfcFServiceInfo>() { - @Override - public NfcFServiceInfo createFromParcel(Parcel source) { - ResolveInfo info = ResolveInfo.CREATOR.createFromParcel(source); - String description = source.readString(); - String systemCode = source.readString(); - String dynamicSystemCode = null; - if (source.readInt() != 0) { - dynamicSystemCode = source.readString(); - } - String nfcid2 = source.readString(); - String dynamicNfcid2 = null; - if (source.readInt() != 0) { - dynamicNfcid2 = source.readString(); - } - int uid = source.readInt(); - String t3tPmm = source.readString(); - NfcFServiceInfo service = new NfcFServiceInfo(info, description, - systemCode, dynamicSystemCode, nfcid2, dynamicNfcid2, uid, t3tPmm); - return service; - } - - @Override - public NfcFServiceInfo[] newArray(int size) { - return new NfcFServiceInfo[size]; - } - }; - - /** - * Dump contents of the service for debugging. - * @param fd parcelfiledescriptor instance - * @param pw printwriter instance - * @param args args for dumping - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void dump(@NonNull ParcelFileDescriptor fd, @NonNull PrintWriter pw, - @NonNull String[] args) { - pw.println(" " + getComponent() - + " (Description: " + getDescription() + ")" - + " (UID: " + getUid() + ")"); - pw.println(" System Code: " + getSystemCode()); - pw.println(" NFCID2: " + getNfcid2()); - pw.println(" T3tPmm: " + getT3tPmm()); - } - - /** - * Dump debugging info as NfcFServiceInfoProto. - * - * If the output belongs to a sub message, the caller is responsible for wrapping this function - * between {@link ProtoOutputStream#start(long)} and {@link ProtoOutputStream#end(long)}. - * - * @param proto the ProtoOutputStream to write to - */ - @FlaggedApi(Flags.FLAG_ENABLE_NFC_MAINLINE) - public void dumpDebug(@NonNull ProtoOutputStream proto) { - getComponent().dumpDebug(proto, NfcFServiceInfoProto.COMPONENT_NAME); - proto.write(NfcFServiceInfoProto.DESCRIPTION, getDescription()); - proto.write(NfcFServiceInfoProto.SYSTEM_CODE, getSystemCode()); - proto.write(NfcFServiceInfoProto.NFCID2, getNfcid2()); - proto.write(NfcFServiceInfoProto.T3T_PMM, getT3tPmm()); - } - - /** - * Copied over from {@link NfcFCardEmulation#isValidSystemCode(String)} - * @hide - */ - private static boolean isValidSystemCode(String systemCode) { - if (systemCode == null) { - return false; - } - if (systemCode.length() != 4) { - Log.e(TAG, "System Code " + systemCode + " is not a valid System Code."); - return false; - } - // check if the value is between "4000" and "4FFF" (excluding "4*FF") - if (!systemCode.startsWith("4") || systemCode.toUpperCase().endsWith("FF")) { - Log.e(TAG, "System Code " + systemCode + " is not a valid System Code."); - return false; - } - try { - Integer.parseInt(systemCode, 16); - } catch (NumberFormatException e) { - Log.e(TAG, "System Code " + systemCode + " is not a valid System Code."); - return false; - } - return true; - } - - /** - * Copied over from {@link NfcFCardEmulation#isValidNfcid2(String)} - * @hide - */ - private static boolean isValidNfcid2(String nfcid2) { - if (nfcid2 == null) { - return false; - } - if (nfcid2.length() != 16) { - Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2."); - return false; - } - // check if the the value starts with "02FE" - if (!nfcid2.toUpperCase().startsWith("02FE")) { - Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2."); - return false; - } - try { - Long.parseLong(nfcid2, 16); - } catch (NumberFormatException e) { - Log.e(TAG, "NFCID2 " + nfcid2 + " is not a valid NFCID2."); - return false; - } - return true; - } -} |