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 {
}
/**
+ * @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
*/
}
/**
+ * @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
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,
}
});
}
+ } 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");
}
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
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()
@Override
public int registerCallback(IContextHubCallback callback) throws RemoteException {
checkPermissions();
- synchronized (this) {
- mCallback = callback;
- }
+ mCallbacksList.register(callback);
return 0;
}
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;
}
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
*/
private int mHandle;
public NanoAppInstanceInfo() {
+ mNeededSensors = EmptyArray.INT;
+ mOutputEvents = EmptyArray.INT;
}
/**
*
* @return int[] all the required sensors needed by this app
*/
+ @NonNull
public int[] getNeededSensors() {
return mNeededSensors;
}
*
* @hide
*/
- public void setNeededSensors(int[] neededSensors) {
- mNeededSensors = neededSensors;
+ public void setNeededSensors(@Nullable int[] neededSensors) {
+ mNeededSensors = neededSensors != null ? neededSensors : EmptyArray.INT;
}
/**
*
* @return all the events that can be generated by this app
*/
+ @NonNull
public int[] getOutputEvents() {
return mOutputEvents;
}
*
* @hide
*/
- public void setOutputEvents(int[] outputEvents) {
- mOutputEvents = outputEvents;
+ public void setOutputEvents(@Nullable int[] outputEvents) {
+ mOutputEvents = outputEvents != null ? outputEvents : EmptyArray.INT;
}
/**
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);
}
out.writeInt(mNeededWriteMemBytes);
out.writeInt(mNeededExecMemBytes);
+ // arrays are never null
out.writeInt(mNeededSensors.length);
out.writeIntArray(mNeededSensors);
-
out.writeInt(mOutputEvents.length);
out.writeIntArray(mOutputEvents);
}