Add support for multiple callback registration in.
- 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
This commit is contained in:
@@ -42,6 +42,12 @@ public final class ContextHubManager {
|
||||
private Callback mCallback;
|
||||
private Handler mCallbackHandler;
|
||||
|
||||
/**
|
||||
* @deprecated Use {@code mCallback} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
private ICallback mLocalCallback;
|
||||
|
||||
/**
|
||||
* An interface to receive asynchronous communication from the context hub.
|
||||
*/
|
||||
@@ -63,6 +69,24 @@ public final class ContextHubManager {
|
||||
ContextHubMessage message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
@@ -222,6 +246,20 @@ public final class ContextHubManager {
|
||||
return registerCallback(callback, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,10 +17,14 @@
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user