Creates framework for new API messaging
- Creates IContextHubClientCallback as a proxy to invoke messaging/life-cycle callbacks for the client. - Creates IContextHubClient as a proxy to send messages at the client side. - Creates a ContextHubClientManager at the service to manage clients and messaging/lifecycle event callbacks. - Implements generation of clients at ContextHubManager and sending messages through ContextHubClient Bug: 67734082 Test: make from root Change-Id: I3a7e69f89cd70ea59160a651dcdb729e18027e9f
This commit is contained in:
@@ -219,6 +219,8 @@ LOCAL_SRC_FILES += \
|
||||
core/java/android/hardware/location/IGeofenceHardwareCallback.aidl \
|
||||
core/java/android/hardware/location/IGeofenceHardwareMonitorCallback.aidl \
|
||||
core/java/android/hardware/location/IContextHubCallback.aidl \
|
||||
core/java/android/hardware/location/IContextHubClient.aidl \
|
||||
core/java/android/hardware/location/IContextHubClientCallback.aidl \
|
||||
core/java/android/hardware/location/IContextHubService.aidl \
|
||||
core/java/android/hardware/location/IContextHubTransactionCallback.aidl \
|
||||
core/java/android/hardware/radio/IRadioService.aidl \
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
package android.hardware.location;
|
||||
|
||||
import android.annotation.RequiresPermission;
|
||||
import android.os.Handler;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
@@ -29,29 +29,25 @@ import java.io.Closeable;
|
||||
*/
|
||||
public class ContextHubClient implements Closeable {
|
||||
/*
|
||||
* The ContextHubClient interface associated with this client.
|
||||
* The proxy to the client interface at the service.
|
||||
*/
|
||||
// TODO: Implement this interface and associate with ContextHubClient object
|
||||
// private final IContextHubClient mClientInterface;
|
||||
private final IContextHubClient mClientProxy;
|
||||
|
||||
/*
|
||||
* The listening callback associated with this client.
|
||||
* The callback interface associated with this client.
|
||||
*/
|
||||
private ContextHubClientCallback mCallback;
|
||||
private final IContextHubClientCallback mCallbackInterface;
|
||||
|
||||
/*
|
||||
* The Context Hub that this client is attached to.
|
||||
*/
|
||||
private ContextHubInfo mAttachedHub;
|
||||
private final ContextHubInfo mAttachedHub;
|
||||
|
||||
/*
|
||||
* The handler to invoke mCallback.
|
||||
*/
|
||||
private Handler mCallbackHandler;
|
||||
|
||||
ContextHubClient(ContextHubClientCallback callback, Handler handler, ContextHubInfo hubInfo) {
|
||||
mCallback = callback;
|
||||
mCallbackHandler = handler;
|
||||
/* package */ ContextHubClient(
|
||||
IContextHubClient clientProxy, IContextHubClientCallback callback,
|
||||
ContextHubInfo hubInfo) {
|
||||
mClientProxy = clientProxy;
|
||||
mCallbackInterface = callback;
|
||||
mAttachedHub = hubInfo;
|
||||
}
|
||||
|
||||
@@ -90,6 +86,10 @@ public class ContextHubClient implements Closeable {
|
||||
@RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
|
||||
@ContextHubTransaction.Result
|
||||
public int sendMessageToNanoApp(NanoAppMessage message) {
|
||||
throw new UnsupportedOperationException("TODO: Implement this");
|
||||
try {
|
||||
return mClientProxy.sendMessageToNanoApp(message);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,6 +455,54 @@ public final class ContextHubManager {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an interface to the ContextHubClient to send down to the service.
|
||||
*
|
||||
* @param callback the callback to invoke at the client process
|
||||
* @param handler the handler to post callbacks for this client
|
||||
*
|
||||
* @return the callback interface
|
||||
*/
|
||||
private IContextHubClientCallback createClientCallback(
|
||||
ContextHubClientCallback callback, Handler handler) {
|
||||
return new IContextHubClientCallback.Stub() {
|
||||
@Override
|
||||
public void onMessageFromNanoApp(NanoAppMessage message) {
|
||||
handler.post(() -> callback.onMessageFromNanoApp(message));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHubReset() {
|
||||
handler.post(() -> callback.onHubReset());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNanoAppAborted(long nanoAppId, int abortCode) {
|
||||
handler.post(() -> callback.onNanoAppAborted(nanoAppId, abortCode));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNanoAppLoaded(long nanoAppId) {
|
||||
handler.post(() -> callback.onNanoAppLoaded(nanoAppId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNanoAppUnloaded(long nanoAppId) {
|
||||
handler.post(() -> callback.onNanoAppUnloaded(nanoAppId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNanoAppEnabled(long nanoAppId) {
|
||||
handler.post(() -> callback.onNanoAppEnabled(nanoAppId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNanoAppDisabled(long nanoAppId) {
|
||||
handler.post(() -> callback.onNanoAppDisabled(nanoAppId));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and registers a client and its callback with the Context Hub Service.
|
||||
*
|
||||
@@ -463,19 +511,37 @@ public final class ContextHubManager {
|
||||
* {@link ContextHubClient} object, and receive notifications through the provided callback.
|
||||
*
|
||||
* @param callback the notification callback to register
|
||||
* @param hubInfo the hub to attach this client to
|
||||
* @param handler the handler to invoke the callback, if null uses the main thread's Looper
|
||||
*
|
||||
* @param hubInfo the hub to attach this client to
|
||||
* @param handler the handler to invoke the callback, if null uses the main thread's Looper
|
||||
* @return the registered client object
|
||||
*
|
||||
* @see ContextHubClientCallback
|
||||
* @throws IllegalArgumentException if hubInfo does not represent a valid hub
|
||||
* @throws IllegalStateException if there were too many registered clients at the service
|
||||
* @throws NullPointerException if callback or hubInfo is null
|
||||
*
|
||||
* @hide
|
||||
* @see ContextHubClientCallback
|
||||
*/
|
||||
public ContextHubClient createClient(
|
||||
ContextHubClientCallback callback, ContextHubInfo hubInfo, @Nullable Handler handler) {
|
||||
throw new UnsupportedOperationException(
|
||||
"TODO: Implement this, and throw an exception on error");
|
||||
if (callback == null) {
|
||||
throw new NullPointerException("Callback cannot be null");
|
||||
}
|
||||
if (hubInfo == null) {
|
||||
throw new NullPointerException("Hub info cannot be null");
|
||||
}
|
||||
|
||||
Handler realHandler = (handler == null) ? new Handler(mMainLooper) : handler;
|
||||
IContextHubClientCallback clientInterface = createClientCallback(callback, realHandler);
|
||||
|
||||
IContextHubClient client;
|
||||
try {
|
||||
client = mService.createClient(clientInterface, hubInfo.getId());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
return new ContextHubClient(client, clientInterface, hubInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
28
core/java/android/hardware/location/IContextHubClient.aidl
Normal file
28
core/java/android/hardware/location/IContextHubClient.aidl
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.hardware.location;
|
||||
|
||||
import android.hardware.location.NanoAppMessage;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
interface IContextHubClient {
|
||||
|
||||
// Sends a message to a nanoapp
|
||||
int sendMessageToNanoApp(in NanoAppMessage message);
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.hardware.location;
|
||||
|
||||
import android.hardware.location.NanoAppMessage;
|
||||
|
||||
/**
|
||||
* An interface used by the Context Hub Service to invoke callbacks for lifecycle notifications of a
|
||||
* Context Hub and nanoapps, as well as for nanoapp messaging.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
oneway interface IContextHubClientCallback {
|
||||
|
||||
// Callback invoked when receiving a message from a nanoapp.
|
||||
void onMessageFromNanoApp(in NanoAppMessage message);
|
||||
|
||||
// Callback invoked when the attached Context Hub has reset.
|
||||
void onHubReset();
|
||||
|
||||
// Callback invoked when a nanoapp aborts at the attached Context Hub.
|
||||
void onNanoAppAborted(long nanoAppId, int abortCode);
|
||||
|
||||
// Callback invoked when a nanoapp is loaded at the attached Context Hub.
|
||||
void onNanoAppLoaded(long nanoAppId);
|
||||
|
||||
// Callback invoked when a nanoapp is unloaded from the attached Context Hub.
|
||||
void onNanoAppUnloaded(long nanoAppId);
|
||||
|
||||
// Callback invoked when a nanoapp is enabled at the attached Context Hub.
|
||||
void onNanoAppEnabled(long nanoAppId);
|
||||
|
||||
// Callback invoked when a nanoapp is disabled at the attached Context Hub.
|
||||
void onNanoAppDisabled(long nanoAppId);
|
||||
}
|
||||
@@ -17,12 +17,14 @@
|
||||
package android.hardware.location;
|
||||
|
||||
// Declare any non-default types here with import statements
|
||||
import android.hardware.location.ContextHubMessage;
|
||||
import android.hardware.location.ContextHubInfo;
|
||||
import android.hardware.location.ContextHubMessage;
|
||||
import android.hardware.location.NanoApp;
|
||||
import android.hardware.location.NanoAppInstanceInfo;
|
||||
import android.hardware.location.NanoAppFilter;
|
||||
import android.hardware.location.NanoAppInstanceInfo;
|
||||
import android.hardware.location.IContextHubCallback;
|
||||
import android.hardware.location.IContextHubClient;
|
||||
import android.hardware.location.IContextHubClientCallback;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
@@ -52,4 +54,7 @@ interface IContextHubService {
|
||||
|
||||
// send a message to a nanoApp
|
||||
int sendMessage(int hubHandle, int nanoAppHandle, in ContextHubMessage msg);
|
||||
|
||||
// Creates a client to send and receive messages
|
||||
IContextHubClient createClient(in IContextHubClientCallback client, int contextHubId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.contexthub.V1_0.ContextHubMsg;
|
||||
import android.hardware.contexthub.V1_0.IContexthub;
|
||||
import android.hardware.contexthub.V1_0.Result;
|
||||
import android.hardware.location.ContextHubTransaction;
|
||||
import android.hardware.location.IContextHubClient;
|
||||
import android.hardware.location.IContextHubClientCallback;
|
||||
import android.hardware.location.NanoAppMessage;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* A broker for the ContextHubClient that handles messaging and life-cycle notification callbacks.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class ContextHubClientBroker extends IContextHubClient.Stub {
|
||||
private static final String TAG = "ContextHubClientBroker";
|
||||
|
||||
/*
|
||||
* The context of the service.
|
||||
*/
|
||||
private final Context mContext;
|
||||
|
||||
/*
|
||||
* The proxy to talk to the Context Hub HAL.
|
||||
*/
|
||||
private final IContexthub mContextHubProxy;
|
||||
|
||||
/*
|
||||
* The ID of the hub that this client is attached to.
|
||||
*/
|
||||
private final int mAttachedContextHubId;
|
||||
|
||||
/*
|
||||
* The host end point ID of this client.
|
||||
*/
|
||||
private final short mHostEndPointId;
|
||||
|
||||
/*
|
||||
* The remote callback interface for this client.
|
||||
*/
|
||||
private final IContextHubClientCallback mCallbackInterface;
|
||||
|
||||
/* package */ ContextHubClientBroker(
|
||||
Context context, IContexthub contextHubProxy, int contextHubId, short hostEndPointId,
|
||||
IContextHubClientCallback callback) {
|
||||
mContext = context;
|
||||
mContextHubProxy = contextHubProxy;
|
||||
mAttachedContextHubId = contextHubId;
|
||||
mHostEndPointId = hostEndPointId;
|
||||
mCallbackInterface = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends from this client to a nanoapp.
|
||||
*
|
||||
* @param message the message to send
|
||||
* @return the error code of sending the message
|
||||
*/
|
||||
@ContextHubTransaction.Result
|
||||
@Override
|
||||
public int sendMessageToNanoApp(NanoAppMessage message) {
|
||||
ContextHubServiceUtil.checkPermissions(mContext);
|
||||
ContextHubMsg messageToNanoApp =
|
||||
ContextHubServiceUtil.createHidlContextHubMessage(mHostEndPointId, message);
|
||||
|
||||
int result;
|
||||
try {
|
||||
result = mContextHubProxy.sendMessageToHub(mAttachedContextHubId, messageToNanoApp);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException in sendMessageToNanoApp (target hub ID = "
|
||||
+ mAttachedContextHubId + ")", e);
|
||||
result = Result.UNKNOWN_FAILURE;
|
||||
}
|
||||
return ContextHubServiceUtil.toTransactionResult(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the ID of the context hub this client is attached to
|
||||
*/
|
||||
/* package */ int getAttachedContextHubId() {
|
||||
return mAttachedContextHubId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the host endpoint ID of this client
|
||||
*/
|
||||
/* package */ short getHostEndPointId() {
|
||||
return mHostEndPointId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message to the client associated with this object.
|
||||
*
|
||||
* @param message the message that came from a nanoapp
|
||||
*/
|
||||
/* package */ void sendMessageToClient(NanoAppMessage message) {
|
||||
try {
|
||||
mCallbackInterface.onMessageFromNanoApp(message);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException while sending message to client (host endpoint ID = "
|
||||
+ mHostEndPointId + ")", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.location;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.contexthub.V1_0.ContextHubMsg;
|
||||
import android.hardware.contexthub.V1_0.IContexthub;
|
||||
import android.hardware.location.IContextHubClient;
|
||||
import android.hardware.location.IContextHubClientCallback;
|
||||
import android.hardware.location.NanoAppMessage;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* A class that manages registration/unregistration of clients and manages messages to/from clients.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
/* package */ class ContextHubClientManager {
|
||||
private static final String TAG = "ContextHubClientManager";
|
||||
|
||||
/*
|
||||
* The maximum host endpoint ID value that a client can be assigned.
|
||||
*/
|
||||
private static final int MAX_CLIENT_ID = 0x7fff;
|
||||
|
||||
/*
|
||||
* Local flag to enable debug logging.
|
||||
*/
|
||||
private static final boolean DEBUG_LOG_ENABLED = true;
|
||||
|
||||
/*
|
||||
* The context of the service.
|
||||
*/
|
||||
private final Context mContext;
|
||||
|
||||
/*
|
||||
* The proxy to talk to the Context Hub.
|
||||
*/
|
||||
private final IContexthub mContextHubProxy;
|
||||
|
||||
/*
|
||||
* A mapping of host endpoint IDs to the ContextHubClientBroker object of registered clients.
|
||||
* A concurrent data structure is used since the registration/unregistration can occur in
|
||||
* multiple threads.
|
||||
*/
|
||||
private final ConcurrentHashMap<Short, ContextHubClientBroker> mHostEndPointIdToClientMap =
|
||||
new ConcurrentHashMap<>();
|
||||
|
||||
/*
|
||||
* The next host endpoint ID to start iterating for the next available host endpoint ID.
|
||||
*/
|
||||
private int mNextHostEndpointId = 0;
|
||||
|
||||
/* package */ ContextHubClientManager(
|
||||
Context context, IContexthub contextHubProxy) {
|
||||
mContext = context;
|
||||
mContextHubProxy = contextHubProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new client with the service.
|
||||
*
|
||||
* @param clientCallback the callback interface of the client to register
|
||||
* @param contextHubId the ID of the hub this client is attached to
|
||||
*
|
||||
* @return the client interface
|
||||
*
|
||||
* @throws IllegalStateException if max number of clients have already registered
|
||||
*/
|
||||
/* package */ IContextHubClient registerClient(
|
||||
IContextHubClientCallback clientCallback, int contextHubId) {
|
||||
ContextHubClientBroker broker = createNewClientBroker(clientCallback, contextHubId);
|
||||
|
||||
Log.d(TAG, "Registered client with host endpoint ID " + broker.getHostEndPointId());
|
||||
return IContextHubClient.Stub.asInterface(broker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles a message sent from a nanoapp.
|
||||
*
|
||||
* @param contextHubId the ID of the hub where the nanoapp sent the message from
|
||||
* @param message the message send by a nanoapp
|
||||
*/
|
||||
/* package */ void onMessageFromNanoApp(int contextHubId, ContextHubMsg message) {
|
||||
NanoAppMessage clientMessage = ContextHubServiceUtil.createNanoAppMessage(message);
|
||||
|
||||
if (DEBUG_LOG_ENABLED) {
|
||||
String targetAudience = clientMessage.isBroadcastMessage() ? "broadcast" : "unicast";
|
||||
Log.v(TAG, "Received a " + targetAudience + " message from nanoapp 0x"
|
||||
+ Long.toHexString(clientMessage.getNanoAppId()));
|
||||
}
|
||||
|
||||
if (clientMessage.isBroadcastMessage()) {
|
||||
broadcastMessage(contextHubId, clientMessage);
|
||||
} else {
|
||||
ContextHubClientBroker proxy = mHostEndPointIdToClientMap.get(message.hostEndPoint);
|
||||
if (proxy != null) {
|
||||
proxy.sendMessageToClient(clientMessage);
|
||||
} else {
|
||||
Log.e(TAG, "Cannot send message to unregistered client (host endpoint ID = "
|
||||
+ message.hostEndPoint + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ContextHubClientBroker object for a client and registers it with the client
|
||||
* manager.
|
||||
*
|
||||
* @param clientCallback the callback interface of the client to register
|
||||
* @param contextHubId the ID of the hub this client is attached to
|
||||
*
|
||||
* @return the ContextHubClientBroker object
|
||||
*
|
||||
* @throws IllegalStateException if max number of clients have already registered
|
||||
*/
|
||||
private synchronized ContextHubClientBroker createNewClientBroker(
|
||||
IContextHubClientCallback clientCallback, int contextHubId) {
|
||||
if (mHostEndPointIdToClientMap.size() == MAX_CLIENT_ID + 1) {
|
||||
throw new IllegalStateException("Could not register client - max limit exceeded");
|
||||
}
|
||||
|
||||
ContextHubClientBroker broker = null;
|
||||
int id = mNextHostEndpointId;
|
||||
for (int i = 0; i <= MAX_CLIENT_ID; i++) {
|
||||
if (!mHostEndPointIdToClientMap.containsKey(id)) {
|
||||
broker = new ContextHubClientBroker(
|
||||
mContext, mContextHubProxy, contextHubId, (short)id, clientCallback);
|
||||
mHostEndPointIdToClientMap.put((short)id, broker);
|
||||
mNextHostEndpointId = (id == MAX_CLIENT_ID) ? 0 : id + 1;
|
||||
break;
|
||||
}
|
||||
|
||||
id = (id == MAX_CLIENT_ID) ? 0 : id + 1;
|
||||
}
|
||||
|
||||
return broker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts a message from a nanoapp to all clients attached to the associated hub.
|
||||
*
|
||||
* @param contextHubId the ID of the hub where the nanoapp sent the message from
|
||||
* @param message the message send by a nanoapp
|
||||
*/
|
||||
private void broadcastMessage(int contextHubId, NanoAppMessage message) {
|
||||
for (ContextHubClientBroker proxy : mHostEndPointIdToClientMap.values()) {
|
||||
if (proxy.getAttachedContextHubId() == contextHubId) {
|
||||
proxy.sendMessageToClient(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.server.location;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.hardware.contexthub.V1_0.AsyncEventType;
|
||||
import android.hardware.contexthub.V1_0.ContextHub;
|
||||
@@ -30,6 +29,8 @@ import android.hardware.contexthub.V1_0.TransactionResult;
|
||||
import android.hardware.location.ContextHubInfo;
|
||||
import android.hardware.location.ContextHubMessage;
|
||||
import android.hardware.location.IContextHubCallback;
|
||||
import android.hardware.location.IContextHubClient;
|
||||
import android.hardware.location.IContextHubClientCallback;
|
||||
import android.hardware.location.IContextHubService;
|
||||
import android.hardware.location.IContextHubTransactionCallback;
|
||||
import android.hardware.location.NanoApp;
|
||||
@@ -58,9 +59,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
*/
|
||||
public class ContextHubService extends IContextHubService.Stub {
|
||||
private static final String TAG = "ContextHubService";
|
||||
private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
|
||||
private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
|
||||
+ HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
|
||||
|
||||
/*
|
||||
* Constants for the type of transaction that is defined by ContextHubService.
|
||||
@@ -104,6 +102,9 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
// The manager for transaction queue
|
||||
private final ContextHubTransactionManager mTransactionManager;
|
||||
|
||||
// The manager for sending messages to/from clients
|
||||
private final ContextHubClientManager mClientManager;
|
||||
|
||||
/**
|
||||
* Class extending the callback to register with a Context Hub.
|
||||
*/
|
||||
@@ -146,17 +147,19 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
mContextHubProxy = getContextHubProxy();
|
||||
if (mContextHubProxy == null) {
|
||||
mTransactionManager = null;
|
||||
mClientManager = null;
|
||||
mContextHubInfo = new ContextHubInfo[0];
|
||||
return;
|
||||
}
|
||||
|
||||
mClientManager = new ContextHubClientManager(mContext, mContextHubProxy);
|
||||
mTransactionManager = new ContextHubTransactionManager(mContextHubProxy);
|
||||
|
||||
List<ContextHub> hubList;
|
||||
try {
|
||||
hubList = mContextHubProxy.getHubs();
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException while getting Context Hub info");
|
||||
Log.e(TAG, "RemoteException while getting Context Hub info", e);
|
||||
hubList = Collections.emptyList();
|
||||
}
|
||||
mContextHubInfo = ContextHubServiceUtil.createContextHubInfoArray(hubList);
|
||||
@@ -168,7 +171,7 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
contextHubId, new ContextHubServiceCallback(contextHubId));
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException while registering service callback for hub (ID = "
|
||||
+ contextHubId + ")");
|
||||
+ contextHubId + ")", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +195,7 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
try {
|
||||
proxy = IContexthub.getService(true /* retry */);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "RemoteException while attaching to Context Hub HAL proxy");
|
||||
Log.e(TAG, "RemoteException while attaching to Context Hub HAL proxy", e);
|
||||
} catch (NoSuchElementException e) {
|
||||
Log.i(TAG, "Context Hub HAL service not found");
|
||||
}
|
||||
@@ -292,7 +295,7 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
@Override
|
||||
public void onQueryResponse(int result, List<NanoAppState> nanoAppStateList) {
|
||||
byte[] data = {(byte) result};
|
||||
onMessageReceipt(MSG_QUERY_NANO_APPS, contextHubId, OS_APP_INSTANCE, data);
|
||||
onMessageReceiptOldApi(MSG_QUERY_NANO_APPS, contextHubId, OS_APP_INSTANCE, data);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -473,7 +476,7 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
try {
|
||||
result = mContextHubProxy.sendMessageToHub(hubHandle, hubMessage);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to send nanoapp message - RemoteException");
|
||||
Log.e(TAG, "Failed to send nanoapp message - RemoteException", e);
|
||||
result = Result.UNKNOWN_FAILURE;
|
||||
}
|
||||
} else {
|
||||
@@ -493,12 +496,13 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
* @param message the message contents
|
||||
*/
|
||||
private void handleClientMessageCallback(int contextHubId, ContextHubMsg message) {
|
||||
// TODO(b/67734082): Send to new API clients
|
||||
byte[] data = ContextHubServiceUtil.createPrimitiveByteArray(message.msg);
|
||||
|
||||
int nanoAppInstanceId = mNanoAppIdToInstanceMap.containsKey(message.appName) ?
|
||||
mNanoAppIdToInstanceMap.get(message.appName) : -1;
|
||||
onMessageReceipt(message.msgType, contextHubId, nanoAppInstanceId, data);
|
||||
onMessageReceiptOldApi(message.msgType, contextHubId, nanoAppInstanceId, data);
|
||||
|
||||
mClientManager.onMessageFromNanoApp(contextHubId, message);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -534,7 +538,7 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
data[0] = (byte) result;
|
||||
ByteBuffer.wrap(data, 1, 4).order(ByteOrder.nativeOrder()).putInt(instanceId);
|
||||
|
||||
onMessageReceipt(MSG_LOAD_NANO_APP, contextHubId, OS_APP_INSTANCE, data);
|
||||
onMessageReceiptOldApi(MSG_LOAD_NANO_APP, contextHubId, OS_APP_INSTANCE, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -552,7 +556,7 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
|
||||
byte[] data = new byte[1];
|
||||
data[0] = (byte) result;
|
||||
onMessageReceipt(MSG_UNLOAD_NANO_APP, contextHubId, OS_APP_INSTANCE, data);
|
||||
onMessageReceiptOldApi(MSG_UNLOAD_NANO_APP, contextHubId, OS_APP_INSTANCE, data);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -578,7 +582,7 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
queryNanoAppsInternal(contextHubId);
|
||||
|
||||
byte[] data = {TransactionResult.SUCCESS};
|
||||
onMessageReceipt(MSG_HUB_RESET, contextHubId, OS_APP_INSTANCE, data);
|
||||
onMessageReceiptOldApi(MSG_HUB_RESET, contextHubId, OS_APP_INSTANCE, data);
|
||||
} else {
|
||||
Log.i(TAG, "Received unknown hub event (hub ID = " + contextHubId + ", type = "
|
||||
+ eventType + ")");
|
||||
@@ -641,6 +645,45 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param contextHubId the hub ID to validate
|
||||
* @return {@code true} if the ID represents that of an available hub, {@code false} otherwise
|
||||
*/
|
||||
private boolean isValidContextHubId(int contextHubId) {
|
||||
for (ContextHubInfo hubInfo : mContextHubInfo) {
|
||||
if (hubInfo.getId() == contextHubId) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and registers a client at the service for the specified Context Hub.
|
||||
*
|
||||
* @param clientCallback the client interface to register with the service
|
||||
* @param contextHubId the ID of the hub this client is attached to
|
||||
* @return the generated client interface, null if registration was unsuccessful
|
||||
*
|
||||
* @throws IllegalArgumentException if contextHubId is not a valid ID
|
||||
* @throws IllegalStateException if max number of clients have already registered
|
||||
* @throws NullPointerException if clientCallback is null
|
||||
*/
|
||||
@Override
|
||||
public IContextHubClient createClient(
|
||||
IContextHubClientCallback clientCallback, int contextHubId) throws RemoteException {
|
||||
checkPermissions();
|
||||
if (!isValidContextHubId(contextHubId)) {
|
||||
throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
|
||||
}
|
||||
if (clientCallback == null) {
|
||||
throw new NullPointerException("Cannot register client with null callback");
|
||||
}
|
||||
|
||||
return mClientManager.registerClient(clientCallback, contextHubId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
|
||||
@@ -664,10 +707,10 @@ public class ContextHubService extends IContextHubService.Stub {
|
||||
}
|
||||
|
||||
private void checkPermissions() {
|
||||
mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
|
||||
ContextHubServiceUtil.checkPermissions(mContext);
|
||||
}
|
||||
|
||||
private int onMessageReceipt(int msgType, int hubHandle, int appInstance, byte[] data) {
|
||||
private int onMessageReceiptOldApi(int msgType, int hubHandle, int appInstance, byte[] data) {
|
||||
if (data == null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -16,11 +16,15 @@
|
||||
|
||||
package com.android.server.location;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.hardware.contexthub.V1_0.ContextHub;
|
||||
import android.hardware.contexthub.V1_0.ContextHubMsg;
|
||||
import android.hardware.contexthub.V1_0.HostEndPoint;
|
||||
import android.hardware.contexthub.V1_0.HubAppInfo;
|
||||
import android.hardware.contexthub.V1_0.Result;
|
||||
import android.hardware.location.ContextHubInfo;
|
||||
import android.hardware.location.ContextHubTransaction;
|
||||
import android.hardware.location.NanoAppBinary;
|
||||
import android.hardware.location.NanoAppMessage;
|
||||
import android.hardware.location.NanoAppState;
|
||||
@@ -34,6 +38,9 @@ import java.util.ArrayList;
|
||||
*/
|
||||
/* package */ class ContextHubServiceUtil {
|
||||
private static final String TAG = "ContextHubServiceUtil";
|
||||
private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
|
||||
private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
|
||||
+ HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
|
||||
|
||||
/**
|
||||
* Creates a ContextHubInfo array from an ArrayList of HIDL ContextHub objects.
|
||||
@@ -165,4 +172,40 @@ import java.util.ArrayList;
|
||||
message.appName, message.msgType, messageArray,
|
||||
message.hostEndPoint == HostEndPoint.BROADCAST);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for location hardware permissions.
|
||||
*
|
||||
* @param context the context of the service
|
||||
*/
|
||||
/* package */
|
||||
static void checkPermissions(Context context) {
|
||||
context.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to convert from the HAL Result enum error code to the
|
||||
* ContextHubTransaction.Result type.
|
||||
*
|
||||
* @param halResult the Result enum error code
|
||||
* @return the ContextHubTransaction.Result equivalent
|
||||
*/
|
||||
@ContextHubTransaction.Result
|
||||
/* package */
|
||||
static int toTransactionResult(int halResult) {
|
||||
switch (halResult) {
|
||||
case Result.OK:
|
||||
return ContextHubTransaction.TRANSACTION_SUCCESS;
|
||||
case Result.BAD_PARAMS:
|
||||
return ContextHubTransaction.TRANSACTION_FAILED_BAD_PARAMS;
|
||||
case Result.NOT_INIT:
|
||||
return ContextHubTransaction.TRANSACTION_FAILED_UNINITIALIZED;
|
||||
case Result.TRANSACTION_PENDING:
|
||||
return ContextHubTransaction.TRANSACTION_FAILED_PENDING;
|
||||
case Result.TRANSACTION_FAILED:
|
||||
case Result.UNKNOWN_FAILURE:
|
||||
default: /* fall through */
|
||||
return ContextHubTransaction.TRANSACTION_FAILED_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user