First cut at Bluetooth Beam

Change-Id: I37e5759515ff8779095b6d8adf5ad9c456fa8529
diff --git a/core/java/android/nfc/INdefPushCallback.aidl b/core/java/android/nfc/INdefPushCallback.aidl
index e60a5b0..4e79822 100644
--- a/core/java/android/nfc/INdefPushCallback.aidl
+++ b/core/java/android/nfc/INdefPushCallback.aidl
@@ -17,6 +17,7 @@
 package android.nfc;
 
 import android.nfc.NdefMessage;
+import android.net.Uri;
 
 /**
  * @hide
@@ -24,5 +25,7 @@
 interface INdefPushCallback
 {
     NdefMessage createMessage();
+    Uri getUri();
+    String getMimeType();
     void onNdefPushComplete();
 }
diff --git a/core/java/android/nfc/NfcActivityManager.java b/core/java/android/nfc/NfcActivityManager.java
index 2c73056..8335459 100644
--- a/core/java/android/nfc/NfcActivityManager.java
+++ b/core/java/android/nfc/NfcActivityManager.java
@@ -18,6 +18,7 @@
 
 import android.app.Activity;
 import android.app.Application;
+import android.net.Uri;
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.util.Log;
@@ -107,6 +108,8 @@
         NdefMessage ndefMessage = null;  // static NDEF message
         NfcAdapter.CreateNdefMessageCallback ndefMessageCallback = null;
         NfcAdapter.OnNdefPushCompleteCallback onNdefPushCompleteCallback = null;
+        Uri uri = null;
+        String mimeType = null;
         public NfcActivityState(Activity activity) {
             if (activity.getWindow().isDestroyed()) {
                 throw new IllegalStateException("activity is already destroyed");
@@ -121,12 +124,14 @@
             ndefMessage = null;
             ndefMessageCallback = null;
             onNdefPushCompleteCallback = null;
+            uri = null;
+            mimeType = null;
         }
         @Override
         public String toString() {
             StringBuilder s = new StringBuilder("[").append(" ");
             s.append(ndefMessage).append(" ").append(ndefMessageCallback).append(" ");
-            s.append(onNdefPushCompleteCallback).append("]");
+            s.append(onNdefPushCompleteCallback).append(" ").append(uri).append("]");
             return s.toString();
         }
     }
@@ -175,6 +180,19 @@
         mDefaultEvent = new NfcEvent(mAdapter);
     }
 
+    public void setNdefPushContentUri(Activity activity, String mimeType, Uri uri) {
+        boolean isResumed;
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = getActivityState(activity);
+            state.uri = uri;
+            state.mimeType = mimeType;
+            isResumed = state.resumed;
+        }
+        if (isResumed) {
+            requestNfcServiceCallback(true);
+        }
+    }
+
     public void setNdefPushMessage(Activity activity, NdefMessage message) {
         boolean isResumed;
         synchronized (NfcActivityManager.this) {
@@ -249,6 +267,26 @@
 
     /** Callback from NFC service, usually on binder thread */
     @Override
+    public Uri getUri() {
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = findResumedActivityState();
+            if (state == null) return null;
+
+            return state.uri;
+        }
+    }
+    /** Callback from NFC service, usually on binder thread */
+    @Override
+    public String getMimeType() {
+        synchronized (NfcActivityManager.this) {
+            NfcActivityState state = findResumedActivityState();
+            if (state == null) return null;
+
+            return state.mimeType;
+        }
+    }
+    /** Callback from NFC service, usually on binder thread */
+    @Override
     public void onNdefPushComplete() {
         NfcAdapter.OnNdefPushCompleteCallback callback;
         synchronized (NfcActivityManager.this) {
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index d78e06c..917751c 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -28,6 +28,7 @@
 import android.content.IntentFilter;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageManager;
+import android.net.Uri;
 import android.nfc.tech.MifareClassic;
 import android.nfc.tech.Ndef;
 import android.nfc.tech.NfcA;
@@ -555,6 +556,18 @@
         }
     }
 
+    //TODO: Consider a callback alternative
+    //TOOD: See if we get rid of mimeType
+    //TODO: make sure NFC service has permission for URI
+    //TODO: javadoc
+    /** @hide */
+    public void setBeamPushUri(String mimeType, Uri uri, Activity activity) {
+        if (activity == null) {
+            throw new NullPointerException("activity cannot be null");
+        }
+        mNfcActivityManager.setNdefPushContentUri(activity, mimeType, uri);
+    }
+
     /**
      * Set a static {@link NdefMessage} to send using Android Beam (TM).
      *