Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fcc2e117 authored by Brad Lassey's avatar Brad Lassey
Browse files

Implement Observe Mode and Preferred Service event listeners with

functional callbacks.

Bug: 356447790
Test: CTS tests
Flag: android.nfc.Flags.nfcEventListener

Change-Id: I66acbe5d1e41f30149e98f13d2374841d4b1604d
parent c00fdec4
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -207,6 +207,7 @@ package android.nfc.cardemulation {
    method public boolean isDefaultServiceForCategory(android.content.ComponentName, String);
    method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public boolean isEuiccSupported();
    method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>);
    method @FlaggedApi("android.nfc.nfc_event_listener") public void registerNfcEventListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener);
    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean);
    method public boolean removeAidsForService(android.content.ComponentName, String);
@@ -216,6 +217,7 @@ package android.nfc.cardemulation {
    method public boolean setPreferredService(android.app.Activity, android.content.ComponentName);
    method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setShouldDefaultToObserveModeForService(@NonNull android.content.ComponentName, boolean);
    method public boolean supportsAidPrefixRegistration();
    method @FlaggedApi("android.nfc.nfc_event_listener") public void unregisterNfcEventListener(@NonNull android.nfc.cardemulation.CardEmulation.NfcEventListener);
    method @NonNull @RequiresPermission(android.Manifest.permission.NFC) public boolean unsetOffHostForService(@NonNull android.content.ComponentName);
    method public boolean unsetPreferredService(android.app.Activity);
    field @Deprecated public static final String ACTION_CHANGE_DEFAULT = "android.nfc.cardemulation.action.ACTION_CHANGE_DEFAULT";
@@ -233,13 +235,16 @@ package android.nfc.cardemulation {
    field public static final int SELECTION_MODE_PREFER_DEFAULT = 0; // 0x0
  }

  @FlaggedApi("android.nfc.nfc_event_listener") public static interface CardEmulation.NfcEventListener {
    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onObserveModeStateChanged(boolean);
    method @FlaggedApi("android.nfc.nfc_event_listener") public default void onPreferredServiceChanged(boolean);
  }

  public abstract class HostApduService extends android.app.Service {
    ctor public HostApduService();
    method public final void notifyUnhandled();
    method public final android.os.IBinder onBind(android.content.Intent);
    method public abstract void onDeactivated(int);
    method @FlaggedApi("android.nfc.nfc_event_listener") public void onObserveModeStateChanged(boolean);
    method @FlaggedApi("android.nfc.nfc_event_listener") public void onPreferredServiceChanged(boolean);
    method public abstract byte[] processCommandApdu(byte[], android.os.Bundle);
    method @FlaggedApi("android.nfc.nfc_read_polling_loop") public void processPollingFrames(@NonNull java.util.List<android.nfc.cardemulation.PollingFrame>);
    method public final void sendResponseApdu(byte[]);
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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;

parcelable ComponentNameAndUser;
 No newline at end of file
+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 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;

import android.annotation.UserIdInt;
import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcelable;

import java.util.Objects;

/**
 * @hide
 */
public class ComponentNameAndUser implements Parcelable {
    @UserIdInt private final int mUserId;
    private ComponentName mComponentName;

    public ComponentNameAndUser(@UserIdInt int userId, ComponentName componentName) {
        mUserId = userId;
        mComponentName = componentName;
    }

    /**
     * @hide
     */
    public int describeContents() {
        return 0;
    }

    /**
     * @hide
     */
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mUserId);
        out.writeParcelable(mComponentName, flags);
    }

    public static final Parcelable.Creator<ComponentNameAndUser> CREATOR =
            new Parcelable.Creator<ComponentNameAndUser>() {
                public ComponentNameAndUser createFromParcel(Parcel in) {
                    return new ComponentNameAndUser(in);
                }

                public ComponentNameAndUser[] newArray(int size) {
                    return new ComponentNameAndUser[size];
                }
            };

    private ComponentNameAndUser(Parcel in) {
        mUserId = in.readInt();
        mComponentName = in.readParcelable(null, ComponentName.class);
    }

    @UserIdInt
    public int getUserId() {
        return mUserId;
    }

    public ComponentName getComponentName() {
        return mComponentName;
    }

    @Override
    public String toString() {
        return mComponentName + " for user id: " + mUserId;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj != null && obj instanceof ComponentNameAndUser) {
            ComponentNameAndUser other = (ComponentNameAndUser) obj;
            return other.getUserId() == mUserId
                    && Objects.equals(other.getComponentName(), mComponentName);
        }
        return false;
    }

    @Override
    public int hashCode() {
        if (mComponentName == null) {
            return mUserId;
        }
        return mComponentName.hashCode() + mUserId;
    }
}
+5 −0
Original line number Diff line number Diff line
@@ -17,6 +17,8 @@
package android.nfc;

import android.content.ComponentName;
import android.nfc.INfcEventListener;

import android.nfc.cardemulation.AidGroup;
import android.nfc.cardemulation.ApduServiceInfo;
import android.os.RemoteCallback;
@@ -55,4 +57,7 @@ interface INfcCardEmulation
    boolean isAutoChangeEnabled();
    List<String> getRoutingStatus();
    void overwriteRoutingTable(int userHandle, String emptyAid, String protocol, String tech, String sc);

    void registerNfcEventListener(in INfcEventListener listener);
    void unregisterNfcEventListener(in INfcEventListener listener);
}
+11 −0
Original line number Diff line number Diff line
package android.nfc;

import android.nfc.ComponentNameAndUser;

/**
 * @hide
 */
oneway interface INfcEventListener {
    void onPreferredServiceChanged(in ComponentNameAndUser ComponentNameAndUser);
    void onObserveModeStateChanged(boolean isEnabled);
}
 No newline at end of file
Loading