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

Commit 1fa2aff2 authored by Martijn Coenen's avatar Martijn Coenen
Browse files

Add direct NDEF push API.

Hidden for now. Also, modified callback that is called
from NfcService to pass all data in a single object
(BeamShareData). This avoids having to do multiple IPCs
at touch time.

Bug: 5134061
Change-Id: I235f608cef9935041b33b4b7a6980f109c15576c
parent e450c3cd
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
/*
 * 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;

parcelable BeamShareData;
+62 −0
Original line number Diff line number Diff line
package android.nfc;

import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * Class to IPC data to be shared over Android Beam.
 * Allows bundling NdefMessage, Uris and flags in a single
 * IPC call. This is important as we want to reduce the
 * amount of IPC calls at "touch time".
 * @hide
 */
public final class BeamShareData implements Parcelable {
    public final NdefMessage ndefMessage;
    public final Uri[] uris;
    public final int flags;

    public BeamShareData(NdefMessage msg, Uri[] uris, int flags) {
        this.ndefMessage = msg;
        this.uris = uris;
        this.flags = flags;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        int urisLength = (uris != null) ? uris.length : 0;
        dest.writeParcelable(ndefMessage, 0);
        dest.writeInt(urisLength);
        if (urisLength > 0) {
            dest.writeTypedArray(uris, 0);
        }
        dest.writeInt(this.flags);
    }

    public static final Parcelable.Creator<BeamShareData> CREATOR =
            new Parcelable.Creator<BeamShareData>() {
        @Override
        public BeamShareData createFromParcel(Parcel source) {
            Uri[] uris = null;
            NdefMessage msg = source.readParcelable(NdefMessage.class.getClassLoader());
            int numUris = source.readInt();
            if (numUris > 0) {
                uris = new Uri[numUris];
                source.readTypedArray(uris, Uri.CREATOR);
            }
            int flags = source.readInt();

            return new BeamShareData(msg, uris, flags);
        }

        @Override
        public BeamShareData[] newArray(int size) {
            return new BeamShareData[size];
        }
    };
}
+2 −4
Original line number Diff line number Diff line
@@ -16,15 +16,13 @@

package android.nfc;

import android.nfc.NdefMessage;
import android.net.Uri;
import android.nfc.BeamShareData;

/**
 * @hide
 */
interface INdefPushCallback
{
    NdefMessage createMessage();
    Uri[] getUris();
    BeamShareData createBeamShareData();
    void onNdefPushComplete();
}
+21 −28
Original line number Diff line number Diff line
@@ -110,6 +110,7 @@ public final class NfcActivityManager extends INdefPushCallback.Stub
        NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
        NfcAdapter.CreateBeamUrisCallback uriCallback = null;
        Uri[] uris = null;
        int flags = 0;
        public NfcActivityState(Activity activity) {
            if (activity.getWindow().isDestroyed()) {
                throw new IllegalStateException("activity is already destroyed");
@@ -215,11 +216,12 @@ public final class NfcActivityManager extends INdefPushCallback.Stub
        }
    }

    public void setNdefPushMessage(Activity activity, NdefMessage message) {
    public void setNdefPushMessage(Activity activity, NdefMessage message, int flags) {
        boolean isResumed;
        synchronized (NfcActivityManager.this) {
            NfcActivityState state = getActivityState(activity);
            state.ndefMessage = message;
            state.flags = flags;
            isResumed = state.resumed;
        }
        if (isResumed) {
@@ -228,11 +230,12 @@ public final class NfcActivityManager extends INdefPushCallback.Stub
    }

    public void setNdefPushMessageCallback(Activity activity,
            NfcAdapter.CreateNdefMessageCallback callback) {
            NfcAdapter.CreateNdefMessageCallback callback, int flags) {
        boolean isResumed;
        synchronized (NfcActivityManager.this) {
            NfcActivityState state = getActivityState(activity);
            state.ndefMessageCallback = callback;
            state.flags = flags;
            isResumed = state.resumed;
        }
        if (isResumed) {
@@ -267,38 +270,29 @@ public final class NfcActivityManager extends INdefPushCallback.Stub

    /** Callback from NFC service, usually on binder thread */
    @Override
    public NdefMessage createMessage() {
        NfcAdapter.CreateNdefMessageCallback callback;
    public BeamShareData createBeamShareData() {
        NfcAdapter.CreateNdefMessageCallback ndefCallback;
        NfcAdapter.CreateBeamUrisCallback urisCallback;
        NdefMessage message;
        Uri[] uris;
        int flags;
        synchronized (NfcActivityManager.this) {
            NfcActivityState state = findResumedActivityState();
            if (state == null) return null;

            callback = state.ndefMessageCallback;
            ndefCallback = state.ndefMessageCallback;
            urisCallback = state.uriCallback;
            message = state.ndefMessage;
            uris = state.uris;
            flags = state.flags;
        }

        // Make callback without lock
        if (callback != null) {
            return callback.createNdefMessage(mDefaultEvent);
        } else {
            return message;
        }
    }

    /** Callback from NFC service, usually on binder thread */
    @Override
    public Uri[] getUris() {
        Uri[] uris;
        NfcAdapter.CreateBeamUrisCallback callback;
        synchronized (NfcActivityManager.this) {
            NfcActivityState state = findResumedActivityState();
            if (state == null) return null;
            uris = state.uris;
            callback = state.uriCallback;
        // Make callbacks without lock
        if (ndefCallback != null) {
            message  = ndefCallback.createNdefMessage(mDefaultEvent);
        }
        if (callback != null) {
            uris = callback.createBeamUris(mDefaultEvent);
        if (urisCallback != null) {
            uris = urisCallback.createBeamUris(mDefaultEvent);
            if (uris != null) {
                for (Uri uri : uris) {
                    if (uri == null) {
@@ -314,10 +308,9 @@ public final class NfcActivityManager extends INdefPushCallback.Stub
                    }
                }
            }
            return uris;
        } else {
            return uris;
        }

        return new BeamShareData(message, uris, flags);
    }

    /** Callback from NFC service, usually on binder thread */
+31 −7
Original line number Diff line number Diff line
@@ -195,6 +195,9 @@ public final class NfcAdapter {
    public static final int STATE_ON = 3;
    public static final int STATE_TURNING_OFF = 4;

    /** @hide */
    public static final int FLAG_NDEF_PUSH_NO_CONFIRM = 0x1;

    /** @hide */
    public static final String ACTION_HANDOVER_TRANSFER_STARTED =
            "android.nfc.action.HANDOVER_TRANSFER_STARTED";
@@ -796,12 +799,12 @@ public final class NfcAdapter {
            if (activity == null) {
                throw new NullPointerException("activity cannot be null");
            }
            mNfcActivityManager.setNdefPushMessage(activity, message);
            mNfcActivityManager.setNdefPushMessage(activity, message, 0);
            for (Activity a : activities) {
                if (a == null) {
                    throw new NullPointerException("activities cannot contain null");
                }
                mNfcActivityManager.setNdefPushMessage(a, message);
                mNfcActivityManager.setNdefPushMessage(a, message, 0);
            }
        } catch (IllegalStateException e) {
            if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) {
@@ -815,6 +818,16 @@ public final class NfcAdapter {
        }
    }

    /**
     * @hide
     */
    public void setNdefPushMessage(NdefMessage message, Activity activity, int flags) {
        if (activity == null) {
            throw new NullPointerException("activity cannot be null");
        }
        mNfcActivityManager.setNdefPushMessage(activity, message, flags);
    }

    /**
     * Set a callback that dynamically generates NDEF messages to send using Android Beam (TM).
     *
@@ -887,12 +900,12 @@ public final class NfcAdapter {
            if (activity == null) {
                throw new NullPointerException("activity cannot be null");
            }
            mNfcActivityManager.setNdefPushMessageCallback(activity, callback);
            mNfcActivityManager.setNdefPushMessageCallback(activity, callback, 0);
            for (Activity a : activities) {
                if (a == null) {
                    throw new NullPointerException("activities cannot contain null");
                }
                mNfcActivityManager.setNdefPushMessageCallback(a, callback);
                mNfcActivityManager.setNdefPushMessageCallback(a, callback, 0);
            }
        } catch (IllegalStateException e) {
            if (targetSdkVersion < android.os.Build.VERSION_CODES.JELLY_BEAN) {
@@ -906,6 +919,17 @@ public final class NfcAdapter {
        }
    }

    /**
     * @hide
     */
    public void setNdefPushMessageCallback(CreateNdefMessageCallback callback, Activity activity,
            int flags) {
        if (activity == null) {
            throw new NullPointerException("activity cannot be null");
        }
        mNfcActivityManager.setNdefPushMessageCallback(activity, callback, flags);
    }

    /**
     * Set a callback on successful Android Beam (TM).
     *
@@ -1095,7 +1119,7 @@ public final class NfcAdapter {
            throw new NullPointerException();
        }
        enforceResumed(activity);
        mNfcActivityManager.setNdefPushMessage(activity, message);
        mNfcActivityManager.setNdefPushMessage(activity, message, 0);
    }

    /**
@@ -1123,8 +1147,8 @@ public final class NfcAdapter {
            throw new NullPointerException();
        }
        enforceResumed(activity);
        mNfcActivityManager.setNdefPushMessage(activity, null);
        mNfcActivityManager.setNdefPushMessageCallback(activity, null);
        mNfcActivityManager.setNdefPushMessage(activity, null, 0);
        mNfcActivityManager.setNdefPushMessageCallback(activity, null, 0);
        mNfcActivityManager.setOnNdefPushCompleteCallback(activity, null);
    }