/*
 * Copyright (C) 2016 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.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.content.Intent;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
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;

/**
 * A class that exposes the Context hubs on a device to applications.
 *
 * Please note that this class is not expected to be used by unbundled applications. Also, calling
 * applications are expected to have LOCATION_HARDWARE permissions to use this class.
 *
 * @hide
 */
@SystemApi
@SystemService(Context.CONTEXTHUB_SERVICE)
public final class ContextHubManager {
    private static final String TAG = "ContextHubManager";

    /**
     * An extra of type {@link ContextHubInfo} describing the source of the event.
     */
    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.
     */
    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.
     */
    public static final String EXTRA_NANOAPP_ID = "android.hardware.location.extra.NANOAPP_ID";

    /**
     * An extra of type int describing the nanoapp-specific abort code.
     */
    public static final String EXTRA_NANOAPP_ABORT_CODE =
            "android.hardware.location.extra.NANOAPP_ABORT_CODE";

    /**
     * An extra of type {@link NanoAppMessage} describing contents of a message from a nanoapp.
     */
    public static final String EXTRA_MESSAGE = "android.hardware.location.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.
     */
    public static final int EVENT_NANOAPP_LOADED = 0;

    /**
     * An event describing that a nanoapp has been unloaded. Contains the EXTRA_NANOAPP_ID extra.
     */
    public static final int EVENT_NANOAPP_UNLOADED = 1;

    /**
     * An event describing that a nanoapp has been enabled. Contains the EXTRA_NANOAPP_ID extra.
     */
    public static final int EVENT_NANOAPP_ENABLED = 2;

    /**
     * An event describing that a nanoapp has been disabled. Contains the EXTRA_NANOAPP_ID extra.
     */
    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.
     */
    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.
     */
    public static final int EVENT_NANOAPP_MESSAGE = 5;

    /**
     * An event describing that the Context Hub has reset.
     */
    public static final int EVENT_HUB_RESET = 6;

    private final Looper mMainLooper;
    private final IContextHubService mService;
    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.
     *
     * @deprecated Use the more refined {@link android.hardware.location.ContextHubClientCallback}
     *             instead for notification callbacks.
     */
    @Deprecated
    public abstract static class Callback {
        protected Callback() {}

        /**
         * 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
         */
        public abstract void onMessageReceipt(
                int hubHandle,
                int nanoAppHandle,
                @NonNull 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
     *
     * @deprecated Use {@link #getContextHubs()} instead. The use of handles are deprecated in the
     *             new APIs.
     */
    @Deprecated
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    public int[] getContextHubHandles() {
        try {
            return mService.getContextHubHandles();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Get more information about a specific hub.
     *
     * @param hubHandle Handle (system-wide unique identifier) of a context hub.
     * @return ContextHubInfo Information about the requested context hub.
     *
     * @see ContextHubInfo
     *
     * @deprecated Use {@link #getContextHubs()} instead. The use of handles are deprecated in the
     *             new APIs.
     */
    @Deprecated
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    public ContextHubInfo getContextHubInfo(int hubHandle) {
        try {
            return mService.getContextHubInfo(hubHandle);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Load a nano app on a specified context hub.
     *
     * Note that loading is asynchronous.  When we return from this method,
     * the nano app (probably) hasn't loaded yet.  Assuming a return of 0
     * from this method, then the final success/failure for the load, along
     * with the "handle" for the nanoapp, is all delivered in a byte
     * string via a call to Callback.onMessageReceipt.
     *
     * TODO(b/30784270): Provide a better success/failure and "handle" delivery.
     *
     * @param hubHandle handle of context hub to load the app on.
     * @param app the nanoApp to load on the hub
     *
     * @return 0 if the command for loading was sent to the context hub;
     *         -1 otherwise
     *
     * @see NanoApp
     *
     * @deprecated Use {@link #loadNanoApp(ContextHubInfo, NanoAppBinary)} instead.
     */
    @Deprecated
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    public int loadNanoApp(int hubHandle, @NonNull NanoApp app) {
        try {
            return mService.loadNanoApp(hubHandle, app);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Unload a specified nanoApp
     *
     * Note that unloading is asynchronous.  When we return from this method,
     * the nano app (probably) hasn't unloaded yet.  Assuming a return of 0
     * from this method, then the final success/failure for the unload is
     * delivered in a byte string via a call to Callback.onMessageReceipt.
     *
     * TODO(b/30784270): Provide a better success/failure delivery.
     *
     * @param nanoAppHandle handle of the nanoApp to unload
     *
     * @return 0 if the command for unloading was sent to the context hub;
     *         -1 otherwise
     *
     * @deprecated Use {@link #unloadNanoApp(ContextHubInfo, long)} instead.
     */
    @Deprecated
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    public int unloadNanoApp(int nanoAppHandle) {
        try {
            return mService.unloadNanoApp(nanoAppHandle);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * get information about the nano app instance
     *
     * NOTE: The returned NanoAppInstanceInfo does _not_ contain correct
     * information for several fields, specifically:
     * - getName()
     * - getPublisher()
     * - getNeededExecMemBytes()
     * - getNeededReadMemBytes()
     * - getNeededWriteMemBytes()
     *
     * For example, say you call loadNanoApp() with a NanoApp that has
     * getName() returning "My Name".  Later, if you call getNanoAppInstanceInfo
     * for that nanoapp, the returned NanoAppInstanceInfo's getName()
     * method will claim "Preloaded app, unknown", even though you would
     * have expected "My Name".  For now, as the user, you'll need to
     * separately track the above fields if they are of interest to you.
     *
     * TODO(b/30943489): Have the returned NanoAppInstanceInfo contain the
     *     correct information.
     *
     * @param nanoAppHandle handle of the nanoapp instance
     * @return NanoAppInstanceInfo the NanoAppInstanceInfo of the nanoapp, or null if the nanoapp
     *                             does not exist
     *
     * @see NanoAppInstanceInfo
     *
     * @deprecated Use {@link #queryNanoApps(ContextHubInfo)} instead to explicitly query the hub
     *             for loaded nanoapps.
     */
    @Deprecated
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @Nullable public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppHandle) {
        try {
            return mService.getNanoAppInstanceInfo(nanoAppHandle);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Find a specified nano app on the system
     *
     * @param hubHandle handle of hub to search for nano app
     * @param filter filter specifying the search criteria for app
     *
     * @see NanoAppFilter
     *
     * @return int[] Array of handles to any found nano apps
     *
     * @deprecated Use {@link #queryNanoApps(ContextHubInfo)} instead to explicitly query the hub
     *             for loaded nanoapps.
     */
    @Deprecated
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public int[] findNanoAppOnHub(int hubHandle, @NonNull NanoAppFilter filter) {
        try {
            return mService.findNanoAppOnHub(hubHandle, filter);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Send a message to a specific nano app instance on a context hub.
     *
     * Note that the return value of this method only speaks of success
     * up to the point of sending this to the Context Hub.  It is not
     * an assurance that the Context Hub successfully sent this message
     * on to the nanoapp.  If assurance is desired, a protocol should be
     * established between your code and the nanoapp, with the nanoapp
     * sending a confirmation message (which will be reported via
     * Callback.onMessageReceipt).
     *
     * @param hubHandle handle of the hub to send the message to
     * @param nanoAppHandle  handle of the nano app to send to
     * @param message Message to be sent
     *
     * @see ContextHubMessage
     *
     * @return int 0 on success, -1 otherwise
     *
     * @deprecated Use {@link android.hardware.location.ContextHubClient#sendMessageToNanoApp(
     *             NanoAppMessage)} instead, after creating a
     *             {@link android.hardware.location.ContextHubClient} with
     *             {@link #createClient(ContextHubInfo, ContextHubClientCallback, Executor)}
     *             or {@link #createClient(ContextHubInfo, ContextHubClientCallback)}.
     */
    @Deprecated
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    public int sendMessage(int hubHandle, int nanoAppHandle, @NonNull ContextHubMessage message) {
        try {
            return mService.sendMessage(hubHandle, nanoAppHandle, message);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Returns the list of ContextHubInfo objects describing the available Context Hubs.
     *
     * @return the list of ContextHubInfo objects
     *
     * @see ContextHubInfo
     */
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public List<ContextHubInfo> getContextHubs() {
        try {
            return mService.getContextHubs();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Helper function to generate a stub for a non-query transaction callback.
     *
     * @param transaction the transaction to unblock when complete
     *
     * @return the callback
     *
     * @hide
     */
    private IContextHubTransactionCallback createTransactionCallback(
            ContextHubTransaction<Void> transaction) {
        return new IContextHubTransactionCallback.Stub() {
            @Override
            public void onQueryResponse(int result, List<NanoAppState> nanoappList) {
                Log.e(TAG, "Received a query callback on a non-query request");
                transaction.setResponse(new ContextHubTransaction.Response<Void>(
                        ContextHubTransaction.RESULT_FAILED_SERVICE_INTERNAL_FAILURE, null));
            }

            @Override
            public void onTransactionComplete(int result) {
                transaction.setResponse(new ContextHubTransaction.Response<Void>(result, null));
            }
        };
    }

   /**
    * Helper function to generate a stub for a query transaction callback.
    *
    * @param transaction the transaction to unblock when complete
    *
    * @return the callback
    *
    * @hide
    */
    private IContextHubTransactionCallback createQueryCallback(
            ContextHubTransaction<List<NanoAppState>> transaction) {
        return new IContextHubTransactionCallback.Stub() {
            @Override
            public void onQueryResponse(int result, List<NanoAppState> nanoappList) {
                transaction.setResponse(new ContextHubTransaction.Response<List<NanoAppState>>(
                        result, nanoappList));
            }

            @Override
            public void onTransactionComplete(int result) {
                Log.e(TAG, "Received a non-query callback on a query request");
                transaction.setResponse(new ContextHubTransaction.Response<List<NanoAppState>>(
                        ContextHubTransaction.RESULT_FAILED_SERVICE_INTERNAL_FAILURE, null));
            }
        };
    }

    /**
     * Loads a nanoapp at the specified Context Hub.
     *
     * After the nanoapp binary is successfully loaded at the specified hub, the nanoapp will be in
     * the enabled state.
     *
     * @param hubInfo the hub to load the nanoapp on
     * @param appBinary The app binary to load
     *
     * @return the ContextHubTransaction of the request
     *
     * @throws NullPointerException if hubInfo or NanoAppBinary is null
     *
     * @see NanoAppBinary
     */
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public ContextHubTransaction<Void> loadNanoApp(
            @NonNull ContextHubInfo hubInfo, @NonNull NanoAppBinary appBinary) {
        Preconditions.checkNotNull(hubInfo, "ContextHubInfo cannot be null");
        Preconditions.checkNotNull(appBinary, "NanoAppBinary cannot be null");

        ContextHubTransaction<Void> transaction =
                new ContextHubTransaction<>(ContextHubTransaction.TYPE_LOAD_NANOAPP);
        IContextHubTransactionCallback callback = createTransactionCallback(transaction);

        try {
            mService.loadNanoAppOnHub(hubInfo.getId(), callback, appBinary);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        return transaction;
    }

    /**
     * Unloads a nanoapp at the specified Context Hub.
     *
     * @param hubInfo the hub to unload the nanoapp from
     * @param nanoAppId the app to unload
     *
     * @return the ContextHubTransaction of the request
     *
     * @throws NullPointerException if hubInfo is null
     */
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public ContextHubTransaction<Void> unloadNanoApp(
            @NonNull ContextHubInfo hubInfo, long nanoAppId) {
        Preconditions.checkNotNull(hubInfo, "ContextHubInfo cannot be null");

        ContextHubTransaction<Void> transaction =
                new ContextHubTransaction<>(ContextHubTransaction.TYPE_UNLOAD_NANOAPP);
        IContextHubTransactionCallback callback = createTransactionCallback(transaction);

        try {
            mService.unloadNanoAppFromHub(hubInfo.getId(), callback, nanoAppId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        return transaction;
    }

    /**
     * Enables a nanoapp at the specified Context Hub.
     *
     * @param hubInfo the hub to enable the nanoapp on
     * @param nanoAppId the app to enable
     *
     * @return the ContextHubTransaction of the request
     *
     * @throws NullPointerException if hubInfo is null
     */
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public ContextHubTransaction<Void> enableNanoApp(
            @NonNull ContextHubInfo hubInfo, long nanoAppId) {
        Preconditions.checkNotNull(hubInfo, "ContextHubInfo cannot be null");

        ContextHubTransaction<Void> transaction =
                new ContextHubTransaction<>(ContextHubTransaction.TYPE_ENABLE_NANOAPP);
        IContextHubTransactionCallback callback = createTransactionCallback(transaction);

        try {
            mService.enableNanoApp(hubInfo.getId(), callback, nanoAppId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        return transaction;
    }

    /**
     * Disables a nanoapp at the specified Context Hub.
     *
     * @param hubInfo the hub to disable the nanoapp on
     * @param nanoAppId the app to disable
     *
     * @return the ContextHubTransaction of the request
     *
     * @throws NullPointerException if hubInfo is null
     */
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public ContextHubTransaction<Void> disableNanoApp(
            @NonNull ContextHubInfo hubInfo, long nanoAppId) {
        Preconditions.checkNotNull(hubInfo, "ContextHubInfo cannot be null");

        ContextHubTransaction<Void> transaction =
                new ContextHubTransaction<>(ContextHubTransaction.TYPE_DISABLE_NANOAPP);
        IContextHubTransactionCallback callback = createTransactionCallback(transaction);

        try {
            mService.disableNanoApp(hubInfo.getId(), callback, nanoAppId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        return transaction;
    }

    /**
     * Requests a query for nanoapps loaded at the specified Context Hub.
     *
     * @param hubInfo the hub to query a list of nanoapps from
     *
     * @return the ContextHubTransaction of the request
     *
     * @throws NullPointerException if hubInfo is null
     */
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public ContextHubTransaction<List<NanoAppState>> queryNanoApps(
            @NonNull ContextHubInfo hubInfo) {
        Preconditions.checkNotNull(hubInfo, "ContextHubInfo cannot be null");

        ContextHubTransaction<List<NanoAppState>> transaction =
                new ContextHubTransaction<>(ContextHubTransaction.TYPE_QUERY_NANOAPPS);
        IContextHubTransactionCallback callback = createQueryCallback(transaction);

        try {
            mService.queryNanoApps(hubInfo.getId(), callback);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        return transaction;
    }

    /**
     * Set a callback to receive messages from the context hub
     *
     * @param callback Callback object
     *
     * @see Callback
     *
     * @return int 0 on success, -1 otherwise
     *
     * @deprecated Use {@link #createClient(ContextHubInfo, ContextHubClientCallback, Executor)}
     *             or {@link #createClient(ContextHubInfo, ContextHubClientCallback)} instead to
     *             register a {@link android.hardware.location.ContextHubClientCallback}.
     */
    @Deprecated
    @SuppressLint("Doclava125")
    public int registerCallback(@NonNull Callback callback) {
        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
     *
     * @param callback Callback object
     * @param handler Handler object, if null uses the Handler of the main Looper
     *
     * @see Callback
     *
     * @return int 0 on success, -1 otherwise
     *
     * @deprecated Use {@link #createClient(ContextHubInfo, ContextHubClientCallback, Executor)}
     *             or {@link #createClient(ContextHubInfo, ContextHubClientCallback)} instead to
     *             register a {@link android.hardware.location.ContextHubClientCallback}.
     */
    @Deprecated
    @SuppressLint("Doclava125")
    public int registerCallback(Callback callback, Handler handler) {
        synchronized(this) {
            if (mCallback != null) {
                Log.w(TAG, "Max number of callbacks reached!");
                return -1;
            }
            mCallback = callback;
            mCallbackHandler = (handler == null) ? new Handler(mMainLooper) : handler;
        }
        return 0;
    }

    /**
     * Creates an interface to the ContextHubClient to send down to the service.
     *
     * @param client the ContextHubClient object associated with this callback
     * @param callback the callback to invoke at the client process
     * @param executor the executor to invoke callbacks for this client
     *
     * @return the callback interface
     */
    private IContextHubClientCallback createClientCallback(
            ContextHubClient client, ContextHubClientCallback callback, Executor executor) {
        return new IContextHubClientCallback.Stub() {
            @Override
            public void onMessageFromNanoApp(NanoAppMessage message) {
                executor.execute(() -> callback.onMessageFromNanoApp(client, message));
            }

            @Override
            public void onHubReset() {
                executor.execute(() -> callback.onHubReset(client));
            }

            @Override
            public void onNanoAppAborted(long nanoAppId, int abortCode) {
                executor.execute(() -> callback.onNanoAppAborted(client, nanoAppId, abortCode));
            }

            @Override
            public void onNanoAppLoaded(long nanoAppId) {
                executor.execute(() -> callback.onNanoAppLoaded(client, nanoAppId));
            }

            @Override
            public void onNanoAppUnloaded(long nanoAppId) {
                executor.execute(() -> callback.onNanoAppUnloaded(client, nanoAppId));
            }

            @Override
            public void onNanoAppEnabled(long nanoAppId) {
                executor.execute(() -> callback.onNanoAppEnabled(client, nanoAppId));
            }

            @Override
            public void onNanoAppDisabled(long nanoAppId) {
                executor.execute(() -> callback.onNanoAppDisabled(client, nanoAppId));
            }
        };
    }

    /**
     * Creates and registers a client and its callback with the Context Hub Service.
     *
     * A client is registered with the Context Hub Service for a specified Context Hub. When the
     * registration succeeds, the client can send messages to nanoapps through the returned
     * {@link ContextHubClient} object, and receive notifications through the provided callback.
     *
     * @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
     * @throws IllegalStateException    if there were too many registered clients at the service
     * @throws NullPointerException     if callback, hubInfo, or executor is null
     *
     * @see ContextHubClientCallback
     */
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public ContextHubClient createClient(
            @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback,
            @NonNull @CallbackExecutor Executor executor) {
        Preconditions.checkNotNull(callback, "Callback cannot be null");
        Preconditions.checkNotNull(hubInfo, "ContextHubInfo cannot be null");
        Preconditions.checkNotNull(executor, "Executor cannot be null");

        ContextHubClient client = new ContextHubClient(hubInfo, false /* persistent */);
        IContextHubClientCallback clientInterface = createClientCallback(
                client, callback, executor);

        IContextHubClient clientProxy;
        try {
            clientProxy = mService.createClient(hubInfo.getId(), clientInterface);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        client.setClientProxy(clientProxy);
        return client;
    }

    /**
     * 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(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public ContextHubClient createClient(
            @NonNull ContextHubInfo hubInfo, @NonNull ContextHubClientCallback callback) {
        return createClient(hubInfo, callback, new HandlerExecutor(Handler.getMain()));
    }

    /**
     * Creates a ContextHubClient that will receive notifications based on Intent events.
     *
     * This method should be used instead of {@link #createClient(ContextHubInfo,
     * ContextHubClientCallback)} or {@link #createClient(ContextHubInfo, ContextHubClientCallback,
     * Executor)} if the caller wants to preserve the messaging endpoint of a ContextHubClient, even
     * after a process exits. If the PendingIntent with the provided nanoapp has already been
     * registered at the service, then the same ContextHubClient will be regenerated without
     * creating a new client connection at the service. Note that the PendingIntent, nanoapp, and
     * Context Hub must all match in identifying a previously registered ContextHubClient.
     * If a client is regenerated, the host endpoint identifier attached to messages sent to the
     * nanoapp remains consistent, even if the original process has exited.
     *
     * If registered successfully, intents will be delivered regarding events or messages from the
     * specified nanoapp from the attached Context Hub. The intent will have an extra
     * {@link ContextHubManager.EXTRA_CONTEXT_HUB_INFO} of type {@link ContextHubInfo}, which
     * describes the Context Hub the intent event was for. The intent will also have an extra
     * {@link ContextHubManager.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, along with event-specific extra fields. The client can also use
     * {@link ContextHubIntentEvent.fromIntent(Intent)} to parse the Intent generated by the event.
     *
     * Intent events will be delivered until {@link ContextHubClient.close()} is called. Note that
     * the registration of this ContextHubClient at the Context Hub Service will be maintained until
     * {@link ContextHubClient.close()} is called. If {@link PendingIntent.cancel()} is called
     * on the provided PendingIntent, then the client will be automatically unregistered by the
     * service.
     *
     * @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
     * @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 pendingIntent or hubInfo is null
     */
    @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE)
    @NonNull public ContextHubClient createClient(
            @NonNull ContextHubInfo hubInfo, @NonNull PendingIntent pendingIntent, long nanoAppId) {
        Preconditions.checkNotNull(pendingIntent);
        Preconditions.checkNotNull(hubInfo);

        ContextHubClient client = new ContextHubClient(hubInfo, true /* persistent */);

        IContextHubClient clientProxy;
        try {
            clientProxy = mService.createPendingIntentClient(
                    hubInfo.getId(), pendingIntent, nanoAppId);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        client.setClientProxy(clientProxy);
        return client;
    }

    /**
     * Unregister a callback for receive messages from the context hub.
     *
     * @see Callback
     *
     * @param callback method to deregister
     *
     * @return int 0 on success, -1 otherwise
     *
     * @deprecated Use {@link android.hardware.location.ContextHubClient#close()} to unregister
     *             a {@link android.hardware.location.ContextHubClientCallback}.
     */
    @SuppressLint("Doclava125")
    @Deprecated
    public int unregisterCallback(@NonNull Callback callback) {
      synchronized(this) {
          if (callback != mCallback) {
              Log.w(TAG, "Cannot recognize callback!");
              return -1;
          }

          mCallback = null;
          mCallbackHandler = null;
      }
      return 0;
    }

    /**
     * @deprecated Use {@link #unregisterCallback(Callback)} instead.
     * @hide
     */
    @Deprecated
    public synchronized int unregisterCallback(ICallback callback) {
        if (callback != mLocalCallback) {
            Log.w(TAG, "Cannot recognize local callback!");
            return -1;
        }
        mLocalCallback = null;
        return 0;
    }

    /**
     * Invokes the ContextHubManager.Callback callback registered with the ContextHubManager.
     *
     * @param hubId The ID of the Context Hub the message came from
     * @param nanoAppId The instance ID of the nanoapp the message came from
     * @param message The message to provide the callback
     */
    private synchronized void invokeOnMessageReceiptCallback(
            int hubId, int nanoAppId, ContextHubMessage message) {
        if (mCallback != null) {
            mCallback.onMessageReceipt(hubId, nanoAppId, message);
        }
    }

    private final IContextHubCallback.Stub mClientCallback = new IContextHubCallback.Stub() {
        @Override
        public void onMessageReceipt(
                final int hubId, final int nanoAppId, final ContextHubMessage message) {
            synchronized (ContextHubManager.this) {
                if (mCallback != null) {
                    mCallbackHandler.post(
                            () -> invokeOnMessageReceiptCallback(hubId, nanoAppId, message));
                } else if (mLocalCallback != null) {
                    // We always ensure that mCallback takes precedence, because mLocalCallback is
                    // only for internal compatibility
                    mLocalCallback.onMessageReceipt(hubId, nanoAppId, message);
                }
            }
        }
    };

    /** @throws ServiceNotFoundException
     * @hide */
    public ContextHubManager(Context context, Looper mainLooper) throws ServiceNotFoundException {
        mMainLooper = mainLooper;
        mService = IContextHubService.Stub.asInterface(
                ServiceManager.getServiceOrThrow(Context.CONTEXTHUB_SERVICE));
        try {
            mService.registerCallback(mClientCallback);
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
}
