Loading core/java/android/hardware/location/ContextHubBroadcastReceiver.java 0 → 100644 +102 −0 Original line number Diff line number Diff line /* * Copyright 2018 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.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; /** * A BroadcastReceiver that can be used with the Context Hub Service notifications. * * @hide */ public class ContextHubBroadcastReceiver extends BroadcastReceiver { // The context at which this receiver operates in private Context mContext; // The handler to post callbacks to when receiving Context Hub Service intents private Handler mHandler; // The callback to be invoked when receiving Context Hub Service intents private ContextHubClientCallback mCallback; // The string to use as the broadcast action for this receiver private String mAction; // True when this receiver is registered to receive Intents, false otherwise private boolean mRegistered = false; public ContextHubBroadcastReceiver(Context context, Handler handler, ContextHubClientCallback callback, String tag) { mContext = context; mHandler = handler; mCallback = callback; mAction = tag; } /** * Registers this receiver to receive Intents from the Context Hub Service. This method must * only be invoked when the receiver is not registered. * * @throws IllegalStateException if the receiver is already registered */ public void register() throws IllegalStateException { if (mRegistered) { throw new IllegalStateException( "Cannot register ContextHubBroadcastReceiver multiple times"); } IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(mAction); mContext.registerReceiver(this, intentFilter, null /* broadcastPermission */, mHandler); mRegistered = true; } /** * Unregisters this receiver. This method must only be invoked if {@link #register()} is * previously invoked. * * @throws IllegalStateException if the receiver is not yet registered */ public void unregister() throws IllegalStateException { if (!mRegistered) { throw new IllegalStateException( "Cannot unregister ContextHubBroadcastReceiver when not registered"); } mContext.unregisterReceiver(this); mRegistered = false; } /** * Creates a new PendingIntent associated with this receiver. * * @param flags the flags {@link PendingIntent.Flags} to use for the PendingIntent * * @return a PendingIntent to receive notifications for this receiver */ public PendingIntent getPendingIntent(@PendingIntent.Flags int flags) { return PendingIntent.getBroadcast( mContext, 0 /* requestCode */, new Intent(mAction), flags); } @Override public void onReceive(Context context, Intent intent) { // TODO: Implement this } } core/java/android/hardware/location/ContextHubClient.java +52 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.hardware.location; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.app.PendingIntent; import android.os.RemoteException; import com.android.internal.util.Preconditions; Loading Loading @@ -99,6 +100,57 @@ public class ContextHubClient implements Closeable { } } /** * Registers to receive persistent intents for a given nanoapp. * * This method should be used if the caller wants to receive notifications even after the * process exits. The client must have an open connection with the Context Hub Service (i.e. it * cannot have been closed through the {@link #close()} method). If registered successfully, * intents will be delivered regarding events for the specified nanoapp from the attached * Context Hub. Any unicast messages for this client will also be delivered. The intent will * have an extra {@link #EXTRA_EVENT_TYPE} of type {@link ContextHubManager.Event}, which will * contain the type of the event. See {@link ContextHubManager.Event} for description of each * event type. * * When the intent is received, this client can be recreated through * {@link ContextHubManager.createClient(PendingIntent, ContextHubInfo, * ContextHubClientCallback, Exectutor)}. When recreated, the client can be treated as the * same endpoint entity from a nanoapp's perspective, and can be continued to be used to send * messages even if the original process has exited. * * Intents will be delivered until it is unregistered through * {@link #unregisterIntent(PendingIntent)}. Note that the registration of this client will * continued to be maintained at the Context Hub Service until * {@link #unregisterIntent(PendingIntent)} is called for registered intents. * * See {@link ContextHubBroadcastReceiver} for a helper class to generate the * {@link PendingIntent} through a {@link BroadcastReceiver}, and maps an {@link Intent} to a * {@link ContextHubClientCallback}. * * @param intent The PendingIntent to register for this client * @param nanoAppId the unique ID of the nanoapp to receive events for * @return true on success, false otherwise * * @hide */ public boolean registerIntent(@NonNull PendingIntent intent, long nanoAppId) { // TODO: Implement this return false; } /** * Unregisters an intent previously registered via {@link #registerIntent(PendingIntent, long)}. * If this intent has not been registered for this client, this method returns false. * * @return true on success, false otherwise * * @hide */ public boolean unregisterIntent(@NonNull PendingIntent intent) { // TODO: Implement this return false; } /** * Sends a message to a nanoapp through the Context Hub Service. * Loading core/java/android/hardware/location/ContextHubManager.java +160 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package android.hardware.location; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.PendingIntent; import android.content.Context; import android.os.Handler; import android.os.HandlerExecutor; Loading @@ -33,6 +35,8 @@ import android.util.Log; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.concurrent.Executor; Loading @@ -49,6 +53,111 @@ import java.util.concurrent.Executor; public final class ContextHubManager { private static final String TAG = "ContextHubManager"; /** * An extra of type {@link ContextHubInfo} describing the source of the event. * * @hide */ public static final String EXTRA_CONTEXT_HUB_INFO = "android.hardware.location.extra.CONTEXT_HUB_INFO"; /** * An extra of type {@link ContextHubManager.Event} describing the event type. * * @hide */ public static final String EXTRA_EVENT_TYPE = "android.hardware.location.extra.EVENT_TYPE"; /** * An extra of type long describing the ID of the nanoapp an event is for. * * @hide */ public static final String EXTRA_NANOAPP_ID = "android.location.hardware.extra.NANOAPP_ID"; /** * An extra of type int describing the nanoapp-specific abort code. * * @hide */ public static final String EXTRA_NANOAPP_ABORT_CODE = "android.location.hardware.extra.NANOAPP_ABORT_CODE"; /** * An extra of type {@link NanoAppMessage} describing contents of a message from a nanoapp. * * @hide */ public static final String EXTRA_MESSAGE = "android.location.hardware.extra.MESSAGE"; /** * Constants describing the type of events from a Context Hub. * {@hide} */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "EVENT_" }, value = { EVENT_NANOAPP_LOADED, EVENT_NANOAPP_UNLOADED, EVENT_NANOAPP_ENABLED, EVENT_NANOAPP_DISABLED, EVENT_NANOAPP_ABORTED, EVENT_NANOAPP_MESSAGE, EVENT_HUB_RESET, }) public @interface Event { } /** * An event describing that a nanoapp has been loaded. Contains the EXTRA_NANOAPP_ID extra. * * @hide */ public static final int EVENT_NANOAPP_LOADED = 0; /** * An event describing that a nanoapp has been unloaded. Contains the EXTRA_NANOAPP_ID extra. * * @hide */ public static final int EVENT_NANOAPP_UNLOADED = 1; /** * An event describing that a nanoapp has been enabled. Contains the EXTRA_NANOAPP_ID extra. * * @hide */ public static final int EVENT_NANOAPP_ENABLED = 2; /** * An event describing that a nanoapp has been disabled. Contains the EXTRA_NANOAPP_ID extra. * * @hide */ public static final int EVENT_NANOAPP_DISABLED = 3; /** * An event describing that a nanoapp has aborted. Contains the EXTRA_NANOAPP_ID and * EXTRA_NANOAPP_ABORT_CODE extras. * * @hide */ public static final int EVENT_NANOAPP_ABORTED = 4; /** * An event containing a message sent from a nanoapp. Contains the EXTRA_NANOAPP_ID and * EXTRA_NANOAPP_MESSAGE extras. * * @hide */ public static final int EVENT_NANOAPP_MESSAGE = 5; /** * An event describing that the Context Hub has reset. * * @hide */ public static final int EVENT_HUB_RESET = 6; private final Looper mMainLooper; private final IContextHubService mService; private Callback mCallback; Loading Loading @@ -681,6 +790,57 @@ public final class ContextHubManager { return createClient(hubInfo, callback, new HandlerExecutor(Handler.getMain())); } /** * Creates a ContextHubClient based on an Intent received by the Context Hub Service. * * This method is intended to be used after receiving an Intent received as a result of * {@link ContextHubClient.registerIntent(PendingIntent, long)}, and must have been created * through {@link #createClient(ContextHubInfo, ContextHubClientCallback, Executor)} or * equivalent at an earlier time. * * @param intent the intent that is associated with a client * @param hubInfo the hub to attach this client to * @param callback the notification callback to register * @param executor the executor to invoke the callback * @return the registered client object * * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or the intent * was not associated with a client * @throws IllegalStateException if there were too many registered clients at the service * @throws NullPointerException if intent, hubInfo, callback, or executor is null * * @hide */ @NonNull public ContextHubClient createClient( @NonNull PendingIntent intent, @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback, @NonNull @CallbackExecutor Executor executor) { // TODO: Implement this throw new UnsupportedOperationException("Not implemented yet"); } /** * Equivalent to {@link #createClient(Intent, ContextHubInfo, ContextHubClientCallback, * Executor)} with the executor using the main thread's Looper. * * @param intent the intent that is associated with a client * @param hubInfo the hub to attach this client to * @param callback the notification callback to register * @return the registered client object * * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or the intent * was not associated with a client * @throws IllegalStateException if there were too many registered clients at the service * @throws NullPointerException if intent, hubInfo, or callback is null * * @hide */ @NonNull public ContextHubClient createClient( @NonNull PendingIntent intent, @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback) { return createClient(intent, hubInfo, callback, new HandlerExecutor(Handler.getMain())); } /** * Unregister a callback for receive messages from the context hub. * Loading Loading
core/java/android/hardware/location/ContextHubBroadcastReceiver.java 0 → 100644 +102 −0 Original line number Diff line number Diff line /* * Copyright 2018 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.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; /** * A BroadcastReceiver that can be used with the Context Hub Service notifications. * * @hide */ public class ContextHubBroadcastReceiver extends BroadcastReceiver { // The context at which this receiver operates in private Context mContext; // The handler to post callbacks to when receiving Context Hub Service intents private Handler mHandler; // The callback to be invoked when receiving Context Hub Service intents private ContextHubClientCallback mCallback; // The string to use as the broadcast action for this receiver private String mAction; // True when this receiver is registered to receive Intents, false otherwise private boolean mRegistered = false; public ContextHubBroadcastReceiver(Context context, Handler handler, ContextHubClientCallback callback, String tag) { mContext = context; mHandler = handler; mCallback = callback; mAction = tag; } /** * Registers this receiver to receive Intents from the Context Hub Service. This method must * only be invoked when the receiver is not registered. * * @throws IllegalStateException if the receiver is already registered */ public void register() throws IllegalStateException { if (mRegistered) { throw new IllegalStateException( "Cannot register ContextHubBroadcastReceiver multiple times"); } IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(mAction); mContext.registerReceiver(this, intentFilter, null /* broadcastPermission */, mHandler); mRegistered = true; } /** * Unregisters this receiver. This method must only be invoked if {@link #register()} is * previously invoked. * * @throws IllegalStateException if the receiver is not yet registered */ public void unregister() throws IllegalStateException { if (!mRegistered) { throw new IllegalStateException( "Cannot unregister ContextHubBroadcastReceiver when not registered"); } mContext.unregisterReceiver(this); mRegistered = false; } /** * Creates a new PendingIntent associated with this receiver. * * @param flags the flags {@link PendingIntent.Flags} to use for the PendingIntent * * @return a PendingIntent to receive notifications for this receiver */ public PendingIntent getPendingIntent(@PendingIntent.Flags int flags) { return PendingIntent.getBroadcast( mContext, 0 /* requestCode */, new Intent(mAction), flags); } @Override public void onReceive(Context context, Intent intent) { // TODO: Implement this } }
core/java/android/hardware/location/ContextHubClient.java +52 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package android.hardware.location; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.app.PendingIntent; import android.os.RemoteException; import com.android.internal.util.Preconditions; Loading Loading @@ -99,6 +100,57 @@ public class ContextHubClient implements Closeable { } } /** * Registers to receive persistent intents for a given nanoapp. * * This method should be used if the caller wants to receive notifications even after the * process exits. The client must have an open connection with the Context Hub Service (i.e. it * cannot have been closed through the {@link #close()} method). If registered successfully, * intents will be delivered regarding events for the specified nanoapp from the attached * Context Hub. Any unicast messages for this client will also be delivered. The intent will * have an extra {@link #EXTRA_EVENT_TYPE} of type {@link ContextHubManager.Event}, which will * contain the type of the event. See {@link ContextHubManager.Event} for description of each * event type. * * When the intent is received, this client can be recreated through * {@link ContextHubManager.createClient(PendingIntent, ContextHubInfo, * ContextHubClientCallback, Exectutor)}. When recreated, the client can be treated as the * same endpoint entity from a nanoapp's perspective, and can be continued to be used to send * messages even if the original process has exited. * * Intents will be delivered until it is unregistered through * {@link #unregisterIntent(PendingIntent)}. Note that the registration of this client will * continued to be maintained at the Context Hub Service until * {@link #unregisterIntent(PendingIntent)} is called for registered intents. * * See {@link ContextHubBroadcastReceiver} for a helper class to generate the * {@link PendingIntent} through a {@link BroadcastReceiver}, and maps an {@link Intent} to a * {@link ContextHubClientCallback}. * * @param intent The PendingIntent to register for this client * @param nanoAppId the unique ID of the nanoapp to receive events for * @return true on success, false otherwise * * @hide */ public boolean registerIntent(@NonNull PendingIntent intent, long nanoAppId) { // TODO: Implement this return false; } /** * Unregisters an intent previously registered via {@link #registerIntent(PendingIntent, long)}. * If this intent has not been registered for this client, this method returns false. * * @return true on success, false otherwise * * @hide */ public boolean unregisterIntent(@NonNull PendingIntent intent) { // TODO: Implement this return false; } /** * Sends a message to a nanoapp through the Context Hub Service. * Loading
core/java/android/hardware/location/ContextHubManager.java +160 −0 Original line number Diff line number Diff line Loading @@ -16,12 +16,14 @@ package android.hardware.location; import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.PendingIntent; import android.content.Context; import android.os.Handler; import android.os.HandlerExecutor; Loading @@ -33,6 +35,8 @@ import android.util.Log; import com.android.internal.util.Preconditions; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.List; import java.util.concurrent.Executor; Loading @@ -49,6 +53,111 @@ import java.util.concurrent.Executor; public final class ContextHubManager { private static final String TAG = "ContextHubManager"; /** * An extra of type {@link ContextHubInfo} describing the source of the event. * * @hide */ public static final String EXTRA_CONTEXT_HUB_INFO = "android.hardware.location.extra.CONTEXT_HUB_INFO"; /** * An extra of type {@link ContextHubManager.Event} describing the event type. * * @hide */ public static final String EXTRA_EVENT_TYPE = "android.hardware.location.extra.EVENT_TYPE"; /** * An extra of type long describing the ID of the nanoapp an event is for. * * @hide */ public static final String EXTRA_NANOAPP_ID = "android.location.hardware.extra.NANOAPP_ID"; /** * An extra of type int describing the nanoapp-specific abort code. * * @hide */ public static final String EXTRA_NANOAPP_ABORT_CODE = "android.location.hardware.extra.NANOAPP_ABORT_CODE"; /** * An extra of type {@link NanoAppMessage} describing contents of a message from a nanoapp. * * @hide */ public static final String EXTRA_MESSAGE = "android.location.hardware.extra.MESSAGE"; /** * Constants describing the type of events from a Context Hub. * {@hide} */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = { "EVENT_" }, value = { EVENT_NANOAPP_LOADED, EVENT_NANOAPP_UNLOADED, EVENT_NANOAPP_ENABLED, EVENT_NANOAPP_DISABLED, EVENT_NANOAPP_ABORTED, EVENT_NANOAPP_MESSAGE, EVENT_HUB_RESET, }) public @interface Event { } /** * An event describing that a nanoapp has been loaded. Contains the EXTRA_NANOAPP_ID extra. * * @hide */ public static final int EVENT_NANOAPP_LOADED = 0; /** * An event describing that a nanoapp has been unloaded. Contains the EXTRA_NANOAPP_ID extra. * * @hide */ public static final int EVENT_NANOAPP_UNLOADED = 1; /** * An event describing that a nanoapp has been enabled. Contains the EXTRA_NANOAPP_ID extra. * * @hide */ public static final int EVENT_NANOAPP_ENABLED = 2; /** * An event describing that a nanoapp has been disabled. Contains the EXTRA_NANOAPP_ID extra. * * @hide */ public static final int EVENT_NANOAPP_DISABLED = 3; /** * An event describing that a nanoapp has aborted. Contains the EXTRA_NANOAPP_ID and * EXTRA_NANOAPP_ABORT_CODE extras. * * @hide */ public static final int EVENT_NANOAPP_ABORTED = 4; /** * An event containing a message sent from a nanoapp. Contains the EXTRA_NANOAPP_ID and * EXTRA_NANOAPP_MESSAGE extras. * * @hide */ public static final int EVENT_NANOAPP_MESSAGE = 5; /** * An event describing that the Context Hub has reset. * * @hide */ public static final int EVENT_HUB_RESET = 6; private final Looper mMainLooper; private final IContextHubService mService; private Callback mCallback; Loading Loading @@ -681,6 +790,57 @@ public final class ContextHubManager { return createClient(hubInfo, callback, new HandlerExecutor(Handler.getMain())); } /** * Creates a ContextHubClient based on an Intent received by the Context Hub Service. * * This method is intended to be used after receiving an Intent received as a result of * {@link ContextHubClient.registerIntent(PendingIntent, long)}, and must have been created * through {@link #createClient(ContextHubInfo, ContextHubClientCallback, Executor)} or * equivalent at an earlier time. * * @param intent the intent that is associated with a client * @param hubInfo the hub to attach this client to * @param callback the notification callback to register * @param executor the executor to invoke the callback * @return the registered client object * * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or the intent * was not associated with a client * @throws IllegalStateException if there were too many registered clients at the service * @throws NullPointerException if intent, hubInfo, callback, or executor is null * * @hide */ @NonNull public ContextHubClient createClient( @NonNull PendingIntent intent, @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback, @NonNull @CallbackExecutor Executor executor) { // TODO: Implement this throw new UnsupportedOperationException("Not implemented yet"); } /** * Equivalent to {@link #createClient(Intent, ContextHubInfo, ContextHubClientCallback, * Executor)} with the executor using the main thread's Looper. * * @param intent the intent that is associated with a client * @param hubInfo the hub to attach this client to * @param callback the notification callback to register * @return the registered client object * * @throws IllegalArgumentException if hubInfo does not represent a valid hub, or the intent * was not associated with a client * @throws IllegalStateException if there were too many registered clients at the service * @throws NullPointerException if intent, hubInfo, or callback is null * * @hide */ @NonNull public ContextHubClient createClient( @NonNull PendingIntent intent, @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback) { return createClient(intent, hubInfo, callback, new HandlerExecutor(Handler.getMain())); } /** * Unregister a callback for receive messages from the context hub. * Loading