OSDN Git Service

Add support for multiple callback registration in.
authordestradaa <destradaa@google.com>
Fri, 15 Apr 2016 01:40:14 +0000 (18:40 -0700)
committerdestradaa <destradaa@google.com>
Wed, 20 Apr 2016 00:45:18 +0000 (17:45 -0700)
- Allows several callbacks from different processes to register with
  the ContextHub service.
- Add an 'internal' callback that can be used for primary clients.
- Fix issue with parceling NanoApp info

Change-Id: Iec203e8b8bc847cb9274f3f4157d0773984dd87c

core/java/android/hardware/location/ContextHubManager.java
core/java/android/hardware/location/ContextHubService.java
core/java/android/hardware/location/NanoAppInstanceInfo.java

index 89edaa9..0c3d4b3 100644 (file)
@@ -43,6 +43,12 @@ public final class ContextHubManager {
     private Handler mCallbackHandler;
 
     /**
+     * @deprecated Use {@code mCallback} instead.
+     */
+    @Deprecated
+    private ICallback mLocalCallback;
+
+    /**
      * An interface to receive asynchronous communication from the context hub.
      */
     public abstract static class Callback {
@@ -64,6 +70,24 @@ public final class ContextHubManager {
     }
 
     /**
+     * @deprecated Use {@link Callback} instead.
+     * @hide
+     */
+    @Deprecated
+    public interface ICallback {
+        /**
+         * Callback function called on message receipt from context hub.
+         *
+         * @param hubHandle Handle (system-wide unique identifier) of the hub of the message.
+         * @param nanoAppHandle Handle (unique identifier) for app instance that sent the message.
+         * @param message The context hub message.
+         *
+         * @see ContextHubMessage
+         */
+        void onMessageReceipt(int hubHandle, int nanoAppHandle, ContextHubMessage message);
+    }
+
+    /**
      * Get a handle to all the context hubs in the system
      * @return array of context hub handles
      */
@@ -223,6 +247,20 @@ public final class ContextHubManager {
     }
 
     /**
+     * @deprecated Use {@link #registerCallback(Callback)} instead.
+     * @hide
+     */
+    @Deprecated
+    public int registerCallback(ICallback callback) {
+        if (mLocalCallback != null) {
+            Log.w(TAG, "Max number of local callbacks reached!");
+            return -1;
+        }
+        mLocalCallback = callback;
+        return 0;
+    }
+
+    /**
      * Set a callback to receive messages from the context hub
      *
      * @param callback Callback object
@@ -266,6 +304,19 @@ public final class ContextHubManager {
       return 0;
     }
 
+    /**
+     * @deprecated Use {@link #unregisterCallback(Callback)} instead.
+     * @hide
+     */
+    public synchronized int unregisterCallback(ICallback callback) {
+        if (callback != mLocalCallback) {
+            Log.w(TAG, "Cannot recognize local callback!");
+            return -1;
+        }
+        mLocalCallback = null;
+        return 0;
+    }
+
     private IContextHubCallback.Stub mClientCallback = new IContextHubCallback.Stub() {
         @Override
         public void onMessageReceipt(final int hubId, final int nanoAppId,
@@ -282,6 +333,12 @@ public final class ContextHubManager {
                         }
                     });
                 }
+            } else if (mLocalCallback != null) {
+                // we always ensure that mCallback takes precedence, because mLocalCallback is only
+                // for internal compatibility
+                synchronized (this) {
+                    mLocalCallback.onMessageReceipt(hubId, nanoAppId, message);
+                }
             } else {
                 Log.d(TAG, "Context hub manager client callback is NULL");
             }
index 2b9b974..8176189 100644 (file)
@@ -19,6 +19,7 @@ package android.hardware.location;
 import android.Manifest;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.util.Log;
 
@@ -57,19 +58,17 @@ public class ContextHubService extends IContextHubService.Stub {
     private static final int OS_APP_INSTANCE = -1;
 
     private final Context mContext;
-
-    private HashMap<Integer, NanoAppInstanceInfo> mNanoAppHash;
-    private ContextHubInfo[] mContextHubInfo;
-    private IContextHubCallback mCallback;
+    private final HashMap<Integer, NanoAppInstanceInfo> mNanoAppHash = new HashMap<>();
+    private final ContextHubInfo[] mContextHubInfo;
+    private final RemoteCallbackList<IContextHubCallback> mCallbacksList =
+            new RemoteCallbackList<>();
 
     private native int nativeSendMessage(int[] header, byte[] data);
     private native ContextHubInfo[] nativeInitialize();
 
-
     public ContextHubService(Context context) {
         mContext = context;
         mContextHubInfo = nativeInitialize();
-        mNanoAppHash = new HashMap<Integer, NanoAppInstanceInfo>();
 
         for (int i = 0; i < mContextHubInfo.length; i++) {
             Log.d(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
@@ -80,9 +79,7 @@ public class ContextHubService extends IContextHubService.Stub {
     @Override
     public int registerCallback(IContextHubCallback callback) throws RemoteException {
         checkPermissions();
-        synchronized (this) {
-            mCallback = callback;
-        }
+        mCallbacksList.register(callback);
         return 0;
     }
 
@@ -237,26 +234,26 @@ public class ContextHubService extends IContextHubService.Stub {
         if (header == null || data == null || header.length < MSG_HEADER_SIZE) {
             return  -1;
         }
-
-        synchronized (this) {
-            if (mCallback != null) {
-                ContextHubMessage msg = new ContextHubMessage(header[MSG_FIELD_TYPE],
-                                                              header[MSG_FIELD_VERSION],
-                                                              data);
-
-                try {
-                    mCallback.onMessageReceipt(header[MSG_FIELD_HUB_HANDLE],
-                                               header[MSG_FIELD_APP_INSTANCE],
-                                               msg);
-                } catch (Exception e) {
-                    Log.w(TAG, "Exception " + e + " when calling remote callback");
-                    return -1;
-                }
-            } else {
-                Log.d(TAG, "Message Callback is NULL");
+        int callbacksCount = mCallbacksList.beginBroadcast();
+        if (callbacksCount < 1) {
+            Log.v(TAG, "No message callbacks registered.");
+            return 0;
+        }
+        ContextHubMessage message =
+                new ContextHubMessage(header[MSG_FIELD_TYPE], header[MSG_FIELD_VERSION], data);
+        for (int i = 0; i < callbacksCount; ++i) {
+            IContextHubCallback callback = mCallbacksList.getBroadcastItem(i);
+            try {
+                callback.onMessageReceipt(
+                        header[MSG_FIELD_HUB_HANDLE],
+                        header[MSG_FIELD_APP_INSTANCE],
+                        message);
+            } catch (RemoteException e) {
+                Log.i(TAG, "Exception (" + e + ") calling remote callback (" + callback + ").");
+                continue;
             }
         }
-
+        mCallbacksList.finishBroadcast();
         return 0;
     }
 
index e842ec6..71a5a88 100644 (file)
 package android.hardware.location;
 
 
+import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.SystemApi;
 import android.os.Parcel;
 import android.os.Parcelable;
 
+import libcore.util.EmptyArray;
+
 /**
  * @hide
  */
@@ -43,6 +47,8 @@ public class NanoAppInstanceInfo {
     private int mHandle;
 
     public NanoAppInstanceInfo() {
+        mNeededSensors = EmptyArray.INT;
+        mOutputEvents = EmptyArray.INT;
     }
 
     /**
@@ -193,6 +199,7 @@ public class NanoAppInstanceInfo {
      *
      * @return int[] all the required sensors needed by this app
      */
+    @NonNull
     public int[] getNeededSensors() {
         return mNeededSensors;
     }
@@ -204,8 +211,8 @@ public class NanoAppInstanceInfo {
      *
      * @hide
      */
-    public void setNeededSensors(int[] neededSensors) {
-        mNeededSensors = neededSensors;
+    public void setNeededSensors(@Nullable int[] neededSensors) {
+        mNeededSensors = neededSensors != null ? neededSensors : EmptyArray.INT;
     }
 
     /**
@@ -213,6 +220,7 @@ public class NanoAppInstanceInfo {
      *
      * @return all the events that can be generated by this app
      */
+    @NonNull
     public int[] getOutputEvents() {
         return mOutputEvents;
     }
@@ -225,8 +233,8 @@ public class NanoAppInstanceInfo {
      *
      * @hide
      */
-    public void setOutputEvents(int[] outputEvents) {
-        mOutputEvents = outputEvents;
+    public void setOutputEvents(@Nullable int[] outputEvents) {
+        mOutputEvents = outputEvents != null ? outputEvents : EmptyArray.INT;
     }
 
     /**
@@ -280,12 +288,12 @@ public class NanoAppInstanceInfo {
         mNeededWriteMemBytes = in.readInt();
         mNeededExecMemBytes = in.readInt();
 
-        int mNeededSensorsLength = in.readInt();
-        mNeededSensors = new int[mNeededSensorsLength];
+        int neededSensorsLength = in.readInt();
+        mNeededSensors = new int[neededSensorsLength];
         in.readIntArray(mNeededSensors);
 
-        int mOutputEventsLength = in.readInt();
-        mOutputEvents = new int[mOutputEventsLength];
+        int outputEventsLength = in.readInt();
+        mOutputEvents = new int[outputEventsLength];
         in.readIntArray(mOutputEvents);
     }
 
@@ -303,9 +311,9 @@ public class NanoAppInstanceInfo {
         out.writeInt(mNeededWriteMemBytes);
         out.writeInt(mNeededExecMemBytes);
 
+        // arrays are never null
         out.writeInt(mNeededSensors.length);
         out.writeIntArray(mNeededSensors);
-
         out.writeInt(mOutputEvents.length);
         out.writeIntArray(mOutputEvents);
     }