diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 50b025176aa4c..499b7c2ebc33d 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3214,8 +3214,10 @@ package android.hardware.location { } public final class ContextHubManager { + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@Nullable android.content.Context, @NonNull android.hardware.location.ContextHubInfo, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.location.ContextHubClientCallback); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.ContextHubClientCallback, @NonNull java.util.concurrent.Executor); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.hardware.location.ContextHubClientCallback); + method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@Nullable android.content.Context, @NonNull android.hardware.location.ContextHubInfo, @NonNull android.app.PendingIntent, long); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubClient createClient(@NonNull android.hardware.location.ContextHubInfo, @NonNull android.app.PendingIntent, long); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubTransaction disableNanoApp(@NonNull android.hardware.location.ContextHubInfo, long); method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_CONTEXT_HUB}) public android.hardware.location.ContextHubTransaction enableNanoApp(@NonNull android.hardware.location.ContextHubInfo, long); diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java index 03de891dd7df0..ebb3021bf083d 100644 --- a/core/java/android/hardware/location/ContextHubManager.java +++ b/core/java/android/hardware/location/ContextHubManager.java @@ -816,9 +816,10 @@ public final class ContextHubManager { * registration succeeds, the client can send messages to nanoapps through the returned * {@link ContextHubClient} object, and receive notifications through the provided callback. * + * @param context the context of the application * @param hubInfo the hub to attach this client to - * @param callback the notification callback to register * @param executor the executor to invoke the callback + * @param callback the notification callback to register * @return the registered client object * * @throws IllegalArgumentException if hubInfo does not represent a valid hub @@ -832,8 +833,9 @@ public final class ContextHubManager { android.Manifest.permission.ACCESS_CONTEXT_HUB }) @NonNull public ContextHubClient createClient( - @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback, - @NonNull @CallbackExecutor Executor executor) { + @Nullable Context context, @NonNull ContextHubInfo hubInfo, + @NonNull @CallbackExecutor Executor executor, + @NonNull ContextHubClientCallback callback) { Objects.requireNonNull(callback, "Callback cannot be null"); Objects.requireNonNull(hubInfo, "ContextHubInfo cannot be null"); Objects.requireNonNull(executor, "Executor cannot be null"); @@ -842,9 +844,14 @@ public final class ContextHubManager { IContextHubClientCallback clientInterface = createClientCallback( client, callback, executor); + String attributionTag = null; + if (context != null) { + attributionTag = context.getAttributionTag(); + } + IContextHubClient clientProxy; try { - clientProxy = mService.createClient(hubInfo.getId(), clientInterface); + clientProxy = mService.createClient(hubInfo.getId(), clientInterface, attributionTag); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -853,19 +860,25 @@ public final class ContextHubManager { return client; } + + /** + * Equivalent to + * {@link #createClient(ContextHubInfo, Executor, String, ContextHubClientCallback)} + * with the {@link Context} being set to null. + */ + @RequiresPermission(anyOf = { + android.Manifest.permission.LOCATION_HARDWARE, + android.Manifest.permission.ACCESS_CONTEXT_HUB + }) + @NonNull public ContextHubClient createClient( + @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback, + @NonNull @CallbackExecutor Executor executor) { + return createClient(null /* context */, hubInfo, executor, callback); + } + /** * Equivalent to {@link #createClient(ContextHubInfo, ContextHubClientCallback, Executor)} * with the executor using the main thread's Looper. - * - * @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 - * @throws IllegalStateException if there were too many registered clients at the service - * @throws NullPointerException if callback or hubInfo is null - * - * @see ContextHubClientCallback */ @RequiresPermission(anyOf = { android.Manifest.permission.LOCATION_HARDWARE, @@ -873,7 +886,8 @@ public final class ContextHubManager { }) @NonNull public ContextHubClient createClient( @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback) { - return createClient(hubInfo, callback, new HandlerExecutor(Handler.getMain())); + return createClient(null /* context */, hubInfo, new HandlerExecutor(Handler.getMain()), + callback); } /** @@ -907,6 +921,8 @@ public final class ContextHubManager { * on the provided PendingIntent, then the client will be automatically unregistered by the * service. * + * @param context the context of the application. If a PendingIntent client is recreated, + * the latest state in the context will be used and old state will be discarded * @param hubInfo the hub to attach this client to * @param pendingIntent the PendingIntent to register to the client * @param nanoAppId the ID of the nanoapp that Intent events will be generated for @@ -921,16 +937,22 @@ public final class ContextHubManager { android.Manifest.permission.ACCESS_CONTEXT_HUB }) @NonNull public ContextHubClient createClient( - @NonNull ContextHubInfo hubInfo, @NonNull PendingIntent pendingIntent, long nanoAppId) { + @Nullable Context context, @NonNull ContextHubInfo hubInfo, + @NonNull PendingIntent pendingIntent, long nanoAppId) { Objects.requireNonNull(pendingIntent); Objects.requireNonNull(hubInfo); ContextHubClient client = new ContextHubClient(hubInfo, true /* persistent */); + String attributionTag = null; + if (context != null) { + attributionTag = context.getAttributionTag(); + } + IContextHubClient clientProxy; try { clientProxy = mService.createPendingIntentClient( - hubInfo.getId(), pendingIntent, nanoAppId); + hubInfo.getId(), pendingIntent, nanoAppId, attributionTag); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -939,6 +961,19 @@ public final class ContextHubManager { return client; } + /** + * Equivalent to {@link #createClient(ContextHubInfo, PendingIntent, long, String)} + * with {@link Context} being set to null. + */ + @RequiresPermission(anyOf = { + android.Manifest.permission.LOCATION_HARDWARE, + android.Manifest.permission.ACCESS_CONTEXT_HUB + }) + @NonNull public ContextHubClient createClient( + @NonNull ContextHubInfo hubInfo, @NonNull PendingIntent pendingIntent, long nanoAppId) { + return createClient(null /* context */, hubInfo, pendingIntent, nanoAppId); + } + /** * Unregister a callback for receive messages from the context hub. * diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl index 04cc5634bf2cf..4961195a3017a 100644 --- a/core/java/android/hardware/location/IContextHubService.aidl +++ b/core/java/android/hardware/location/IContextHubService.aidl @@ -59,11 +59,13 @@ interface IContextHubService { int sendMessage(int contextHubHandle, int nanoAppHandle, in ContextHubMessage msg); // Creates a client to send and receive messages - IContextHubClient createClient(int contextHubId, in IContextHubClientCallback client); + IContextHubClient createClient( + int contextHubId, in IContextHubClientCallback client, in String attributionTag); // Creates a PendingIntent-based client to send and receive messages IContextHubClient createPendingIntentClient( - int contextHubId, in PendingIntent pendingIntent, long nanoAppId); + int contextHubId, in PendingIntent pendingIntent, long nanoAppId, + in String attributionTag); // Returns a list of ContextHub objects of available hubs List getContextHubs(); diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java index d3536345ccf1a..785e6745087f7 100644 --- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java +++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java @@ -16,6 +16,7 @@ package com.android.server.location.contexthub; +import android.annotation.Nullable; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; @@ -701,6 +702,7 @@ public class ContextHubService extends IContextHubService.Stub { * * @param contextHubId the ID of the hub this client is attached to * @param clientCallback the client interface to register with the service + * @param attributionTag an optional attribution tag within the given package * @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 @@ -708,7 +710,8 @@ public class ContextHubService extends IContextHubService.Stub { */ @Override public IContextHubClient createClient( - int contextHubId, IContextHubClientCallback clientCallback) throws RemoteException { + int contextHubId, IContextHubClientCallback clientCallback, + @Nullable String attributionTag) throws RemoteException { checkPermissions(); if (!isValidContextHubId(contextHubId)) { throw new IllegalArgumentException("Invalid context hub ID " + contextHubId); @@ -727,13 +730,15 @@ public class ContextHubService extends IContextHubService.Stub { * @param contextHubId the ID of the hub this client is attached to * @param pendingIntent the PendingIntent associated with this client * @param nanoAppId the ID of the nanoapp PendingIntent events will be sent for + * @param attributionTag an optional attribution tag within the given package * @return the generated client interface * @throws IllegalArgumentException if hubInfo does not represent a valid hub * @throws IllegalStateException if there were too many registered clients at the service */ @Override public IContextHubClient createPendingIntentClient( - int contextHubId, PendingIntent pendingIntent, long nanoAppId) throws RemoteException { + int contextHubId, PendingIntent pendingIntent, long nanoAppId, + @Nullable String attributionTag) throws RemoteException { checkPermissions(); if (!isValidContextHubId(contextHubId)) { throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);