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

Commit e432de84 authored by Nick Pelly's avatar Nick Pelly Committed by Android (Google) Code Review
Browse files

Merge "Improve NDEF push API"

parents 3ffb8897 c84c89a6
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -107,6 +107,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/common/R/com/android/systemui/R.
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IAudioService.P)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IAudioService.P)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IAudioService.P)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/media/java/android/media/IAudioService.P)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/media/audio/)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/)
# ************************************************
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
# ************************************************
# ************************************************
+15 −6
Original line number Original line Diff line number Diff line
@@ -12413,13 +12413,15 @@ package android.nfc {
  public final class NfcAdapter {
  public final class NfcAdapter {
    method public void disableForegroundDispatch(android.app.Activity);
    method public void disableForegroundDispatch(android.app.Activity);
    method public void disableForegroundNdefPush(android.app.Activity);
    method public deprecated void disableForegroundNdefPush(android.app.Activity);
    method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][]);
    method public void enableForegroundDispatch(android.app.Activity, android.app.PendingIntent, android.content.IntentFilter[], java.lang.String[][]);
    method public void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
    method public deprecated void enableForegroundNdefPush(android.app.Activity, android.nfc.NdefMessage);
    method public void enableForegroundNdefPush(android.app.Activity, android.nfc.NfcAdapter.NdefPushCallback);
    method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
    method public static android.nfc.NfcAdapter getDefaultAdapter(android.content.Context);
    method public static deprecated android.nfc.NfcAdapter getDefaultAdapter();
    method public static deprecated android.nfc.NfcAdapter getDefaultAdapter();
    method public boolean isEnabled();
    method public boolean isEnabled();
    method public void setNdefPushMessage(android.nfc.NdefMessage, android.app.Activity...);
    method public void setNdefPushMessageCallback(android.nfc.NfcAdapter.CreateNdefMessageCallback, android.app.Activity...);
    method public void setOnNdefPushCompleteCallback(android.nfc.NfcAdapter.OnNdefPushCompleteCallback, android.app.Activity...);
    field public static final java.lang.String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
    field public static final java.lang.String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
    field public static final java.lang.String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
    field public static final java.lang.String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
    field public static final java.lang.String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
    field public static final java.lang.String ACTION_TECH_DISCOVERED = "android.nfc.action.TECH_DISCOVERED";
@@ -12428,9 +12430,16 @@ package android.nfc {
    field public static final java.lang.String EXTRA_TAG = "android.nfc.extra.TAG";
    field public static final java.lang.String EXTRA_TAG = "android.nfc.extra.TAG";
  }
  }
  public static abstract interface NfcAdapter.NdefPushCallback {
  public static abstract interface NfcAdapter.CreateNdefMessageCallback {
    method public abstract android.nfc.NdefMessage createMessage();
    method public abstract android.nfc.NdefMessage createNdefMessage(android.nfc.NfcEvent);
    method public abstract void onMessagePushed();
  }
  public static abstract interface NfcAdapter.OnNdefPushCompleteCallback {
    method public abstract void onNdefPushComplete(android.nfc.NfcEvent);
  }
  public final class NfcEvent {
    field public final android.nfc.NfcAdapter nfcAdapter;
  }
  }
  public final class NfcManager {
  public final class NfcManager {
+2 −2
Original line number Original line Diff line number Diff line
@@ -23,6 +23,6 @@ import android.nfc.NdefMessage;
 */
 */
interface INdefPushCallback
interface INdefPushCallback
{
{
    NdefMessage onConnect();
    NdefMessage createMessage();
    void onMessagePushed();
    void onNdefPushComplete();
}
}
+8 −13
Original line number Original line Diff line number Diff line
@@ -23,8 +23,8 @@ import android.nfc.NdefMessage;
import android.nfc.Tag;
import android.nfc.Tag;
import android.nfc.TechListParcel;
import android.nfc.TechListParcel;
import android.nfc.INdefPushCallback;
import android.nfc.INdefPushCallback;
import android.nfc.INfcTag;
import android.nfc.INfcAdapterExtras;
import android.nfc.INfcAdapterExtras;
import android.nfc.INfcTag;


/**
/**
 * @hide
 * @hide
@@ -34,19 +34,14 @@ interface INfcAdapter
    INfcTag getNfcTagInterface();
    INfcTag getNfcTagInterface();
    INfcAdapterExtras getNfcAdapterExtrasInterface();
    INfcAdapterExtras getNfcAdapterExtrasInterface();


    // NfcAdapter-class related methods
    int getState();
    int getState();
    void enableForegroundDispatch(in ComponentName activity, in PendingIntent intent,
            in IntentFilter[] filters, in TechListParcel techLists);
    void disableForegroundDispatch(in ComponentName activity);
    void enableForegroundNdefPush(in ComponentName activity, in NdefMessage msg);
    void enableForegroundNdefPushWithCallback(in ComponentName activity, in INdefPushCallback callback);
    void disableForegroundNdefPush(in ComponentName activity);

    // Non-public methods
    boolean disable();
    boolean disable();
    boolean enable();
    boolean enable();
    boolean enableZeroClick();
    boolean enableNdefPush();
    boolean disableZeroClick();
    boolean disableNdefPush();
    boolean isZeroClickEnabled();
    boolean isNdefPushEnabled();

    void setForegroundDispatch(in PendingIntent intent,
            in IntentFilter[] filters, in TechListParcel techLists);
    void setForegroundNdefPush(in NdefMessage msg, in INdefPushCallback callback);
}
}
+217 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2011 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.app.Activity;
import android.os.RemoteException;
import android.util.Log;

import java.util.HashMap;

/**
 * Manages NFC API's that are coupled to the life-cycle of an Activity.
 *
 * <p>Uses a fragment to hook into onPause() and onResume() of the host
 * activities.
 *
 * <p>Ideally all of this management would be done in the NFC Service,
 * but right now it is much easier to do it in the application process.
 *
 * @hide
 */
public final class NfcActivityManager extends INdefPushCallback.Stub {
    static final String TAG = NfcAdapter.TAG;
    static final Boolean DBG = false;

    final NfcAdapter mAdapter;
    final HashMap<Activity, NfcActivityState> mNfcState;  // contents protected by this
    final NfcEvent mDefaultEvent;  // can re-use one NfcEvent because it just contains adapter

    /**
     * NFC state associated with an {@link Activity}
     */
    class NfcActivityState {
        boolean resumed = false;  // is the activity resumed
        NdefMessage ndefMessage;
        NfcAdapter.CreateNdefMessageCallback ndefMessageCallback;
        NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback;
        @Override
        public String toString() {
            StringBuilder s = new StringBuilder("[").append(resumed).append(" ");
            s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
            s.append(onNdefPushCompleteCallback).append("]");
            return s.toString();
        }
    }

    public NfcActivityManager(NfcAdapter adapter) {
        mAdapter = adapter;
        mNfcState = new HashMap<Activity, NfcActivityState>();
        mDefaultEvent = new NfcEvent(mAdapter);
    }

    /**
     * onResume hook from fragment attached to activity
     */
    public synchronized void onResume(Activity activity) {
        NfcActivityState state = mNfcState.get(activity);
        if (DBG) Log.d(TAG, "onResume() for " + activity + " " + state);
        if (state != null) {
            state.resumed = true;
            updateNfcService(state);
        }
    }

    /**
     * onPause hook from fragment attached to activity
     */
    public synchronized void onPause(Activity activity) {
        NfcActivityState state = mNfcState.get(activity);
        if (DBG) Log.d(TAG, "onPause() for " + activity + " " + state);
        if (state != null) {
            state.resumed = false;
            updateNfcService(state);
        }
    }

    public synchronized void setNdefPushMessage(Activity activity, NdefMessage message) {
        NfcActivityState state = getOrCreateState(activity, message != null);
        if (state == null || state.ndefMessage == message) {
            return;  // nothing more to do;
        }
        state.ndefMessage = message;
        if (message == null) {
            maybeRemoveState(activity, state);
        }
        if (state.resumed) {
            updateNfcService(state);
        }
    }

    public synchronized void setNdefPushMessageCallback(Activity activity,
            NfcAdapter.CreateNdefMessageCallback callback) {
        NfcActivityState state = getOrCreateState(activity, callback != null);
        if (state == null || state.ndefMessageCallback == callback) {
            return;  // nothing more to do;
        }
        state.ndefMessageCallback = callback;
        if (callback == null) {
            maybeRemoveState(activity, state);
        }
        if (state.resumed) {
            updateNfcService(state);
        }
    }

    public synchronized void setOnNdefPushCompleteCallback(Activity activity,
            NfcAdapter.OnNdefPushCompleteCallback callback) {
        NfcActivityState state = getOrCreateState(activity, callback != null);
        if (state == null || state.onNdefPushCompleteCallback == callback) {
            return;  // nothing more to do;
        }
        state.onNdefPushCompleteCallback = callback;
        if (callback == null) {
            maybeRemoveState(activity, state);
        }
        if (state.resumed) {
            updateNfcService(state);
        }
    }

    /**
     * Get the NfcActivityState for the specified Activity.
     * If create is true, then create it if it doesn't already exist,
     * and ensure the NFC fragment is attached to the activity.
     */
    synchronized NfcActivityState getOrCreateState(Activity activity, boolean create) {
        if (DBG) Log.d(TAG, "getOrCreateState " + activity + " " + create);
        NfcActivityState state = mNfcState.get(activity);
        if (state == null && create) {
            state = new NfcActivityState();
            mNfcState.put(activity, state);
            NfcFragment.attach(activity);
        }
        return state;
    }

    /**
     * If the NfcActivityState is empty then remove it, and
     * detach it from the Activity.
     */
    synchronized void maybeRemoveState(Activity activity, NfcActivityState state) {
        if (state.ndefMessage == null && state.ndefMessageCallback == null &&
                state.onNdefPushCompleteCallback == null) {
            mNfcState.remove(activity);
        }
    }

    /**
     * Register NfcActivityState with the NFC service.
     */
    synchronized void updateNfcService(NfcActivityState state) {
        boolean serviceCallbackNeeded = state.ndefMessageCallback != null ||
                state.onNdefPushCompleteCallback != null;

        try {
            NfcAdapter.sService.setForegroundNdefPush(state.resumed ? state.ndefMessage : null,
                    state.resumed && serviceCallbackNeeded ? this : null);
        } catch (RemoteException e) {
            mAdapter.attemptDeadServiceRecovery(e);
        }
    }

    /**
     * Callback from NFC service
     */
    @Override
    public NdefMessage createMessage() {
        NfcAdapter.CreateNdefMessageCallback callback = null;
        synchronized (NfcActivityManager.this) {
            for (NfcActivityState state : mNfcState.values()) {
                if (state.resumed) {
                    callback = state.ndefMessageCallback;
                }
            }
        }

        // drop lock before making callback
        if (callback != null) {
            return callback.createNdefMessage(mDefaultEvent);
        }
        return null;
    }

    /**
     * Callback from NFC service
     */
    @Override
    public void onNdefPushComplete() {
        NfcAdapter.OnNdefPushCompleteCallback callback = null;
        synchronized (NfcActivityManager.this) {
            for (NfcActivityState state : mNfcState.values()) {
                if (state.resumed) {
                    callback = state.onNdefPushCompleteCallback;
                }
            }
        }

        // drop lock before making callback
        if (callback != null) {
            callback.onNdefPushComplete(mDefaultEvent);
        }
    }
}
Loading