Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b73024b authored by Arthur Ishiguro's avatar Arthur Ishiguro Committed by Android (Google) Code Review
Browse files

Merge "Adds new PendingIntent-based APIs for ContextHubManager"

parents c691c052 62a02b63
Loading
Loading
Loading
Loading
+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
    }
}
+52 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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.
     *
+160 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;

@@ -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;
@@ -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.
     *