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:
destradaa
2016-04-14 18:40:14 -07:00
parent 71574c3371
commit 78cebca720
3 changed files with 98 additions and 36 deletions

View File

@@ -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");
}

View 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;
}

View File

@@ -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);
}