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

Commit 913b79a6 authored by Brian Duddie's avatar Brian Duddie Committed by Android (Google) Code Review
Browse files

Merge changes from topic "contexthub_hal_update"

* changes:
  Update the Contexthub with location setting changes
  Create IContextHubWrapper
parents b073a3eb e0001a12
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -346,6 +346,7 @@ java_library {
        "android.hardware.cas-V1.1-java",
        "android.hardware.cas-V1.2-java",
        "android.hardware.contexthub-V1.0-java",
        "android.hardware.contexthub-V1.1-java",
        "android.hardware.gnss-V1.0-java",
        "android.hardware.gnss-V2.1-java",
        "android.hardware.health-V1.0-java-constants",
+51 −25
Original line number Diff line number Diff line
@@ -18,14 +18,16 @@ package com.android.server.location;

import android.app.PendingIntent;
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.contexthub.V1_0.AsyncEventType;
import android.hardware.contexthub.V1_0.ContextHub;
import android.hardware.contexthub.V1_0.ContextHubMsg;
import android.hardware.contexthub.V1_0.HubAppInfo;
import android.hardware.contexthub.V1_0.IContexthub;
import android.hardware.contexthub.V1_0.IContexthubCallback;
import android.hardware.contexthub.V1_0.Result;
import android.hardware.contexthub.V1_0.TransactionResult;
import android.hardware.contexthub.V1_1.Setting;
import android.hardware.contexthub.V1_1.SettingValue;
import android.hardware.location.ContextHubInfo;
import android.hardware.location.ContextHubMessage;
import android.hardware.location.ContextHubTransaction;
@@ -40,8 +42,11 @@ import android.hardware.location.NanoAppFilter;
import android.hardware.location.NanoAppInstanceInfo;
import android.hardware.location.NanoAppMessage;
import android.hardware.location.NanoAppState;
import android.location.LocationManager;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
import android.util.proto.ProtoOutputStream;

@@ -56,7 +61,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

/**
 * @hide
@@ -92,7 +96,7 @@ public class ContextHubService extends IContextHubService.Stub {
            new RemoteCallbackList<>();

    // Proxy object to communicate with the Context Hub HAL
    private final IContexthub mContextHubProxy;
    private final IContextHubWrapper mContextHubWrapper;

    // The manager for transaction queue
    private final ContextHubTransactionManager mTransactionManager;
@@ -145,8 +149,8 @@ public class ContextHubService extends IContextHubService.Stub {
    public ContextHubService(Context context) {
        mContext = context;

        mContextHubProxy = getContextHubProxy();
        if (mContextHubProxy == null) {
        mContextHubWrapper = getContextHubWrapper();
        if (mContextHubWrapper == null) {
            mTransactionManager = null;
            mClientManager = null;
            mDefaultClientMap = Collections.emptyMap();
@@ -155,13 +159,13 @@ public class ContextHubService extends IContextHubService.Stub {
            return;
        }

        mClientManager = new ContextHubClientManager(mContext, mContextHubProxy);
        mClientManager = new ContextHubClientManager(mContext, mContextHubWrapper.getHub());
        mTransactionManager = new ContextHubTransactionManager(
                mContextHubProxy, mClientManager, mNanoAppStateManager);
                mContextHubWrapper.getHub(), mClientManager, mNanoAppStateManager);

        List<ContextHub> hubList;
        try {
            hubList = mContextHubProxy.getHubs();
            hubList = mContextHubWrapper.getHub().getHubs();
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException while getting Context Hub info", e);
            hubList = Collections.emptyList();
@@ -178,7 +182,7 @@ public class ContextHubService extends IContextHubService.Stub {
            defaultClientMap.put(contextHubId, client);

            try {
                mContextHubProxy.registerCallback(
                mContextHubWrapper.getHub().registerCallback(
                        contextHubId, new ContextHubServiceCallback(contextHubId));
            } catch (RemoteException e) {
                Log.e(TAG, "RemoteException while registering service callback for hub (ID = "
@@ -190,6 +194,19 @@ public class ContextHubService extends IContextHubService.Stub {
            queryNanoAppsInternal(contextHubId);
        }
        mDefaultClientMap = Collections.unmodifiableMap(defaultClientMap);

        if (mContextHubWrapper.supportsSettingNotifications()) {
            sendLocationSettingUpdate();
            mContext.getContentResolver().registerContentObserver(
                    Settings.Secure.getUriFor(Settings.Secure.LOCATION_MODE),
                    true /* notifyForDescendants */,
                    new ContentObserver(null /* handler */) {
                        @Override
                        public void onChange(boolean selfChange) {
                            sendLocationSettingUpdate();
                        }
                    }, UserHandle.USER_ALL);
        }
    }

    /**
@@ -239,19 +256,15 @@ public class ContextHubService extends IContextHubService.Stub {
    }

    /**
     * @return the IContexthub proxy interface
     * @return the IContextHubWrapper interface
     */
    private IContexthub getContextHubProxy() {
        IContexthub proxy = null;
        try {
            proxy = IContexthub.getService(true /* retry */);
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException while attaching to Context Hub HAL proxy", e);
        } catch (NoSuchElementException e) {
            Log.i(TAG, "Context Hub HAL service not found");
    private IContextHubWrapper getContextHubWrapper() {
        IContextHubWrapper wrapper = IContextHubWrapper.maybeConnectTo1_1();
        if (wrapper == null) {
            wrapper = IContextHubWrapper.maybeConnectTo1_0();
        }

        return proxy;
        return wrapper;
    }

    @Override
@@ -355,7 +368,7 @@ public class ContextHubService extends IContextHubService.Stub {
    @Override
    public int loadNanoApp(int contextHubHandle, NanoApp nanoApp) throws RemoteException {
        checkPermissions();
        if (mContextHubProxy == null) {
        if (mContextHubWrapper == null) {
            return -1;
        }
        if (!isValidContextHubId(contextHubHandle)) {
@@ -382,7 +395,7 @@ public class ContextHubService extends IContextHubService.Stub {
    @Override
    public int unloadNanoApp(int nanoAppHandle) throws RemoteException {
        checkPermissions();
        if (mContextHubProxy == null) {
        if (mContextHubWrapper == null) {
            return -1;
        }

@@ -444,7 +457,7 @@ public class ContextHubService extends IContextHubService.Stub {
     * @throws IllegalStateException if the transaction queue is full
     */
    private int queryNanoAppsInternal(int contextHubId) {
        if (mContextHubProxy == null) {
        if (mContextHubWrapper == null) {
            return Result.UNKNOWN_FAILURE;
        }

@@ -461,7 +474,7 @@ public class ContextHubService extends IContextHubService.Stub {
    public int sendMessage(int contextHubHandle, int nanoAppHandle, ContextHubMessage msg)
            throws RemoteException {
        checkPermissions();
        if (mContextHubProxy == null) {
        if (mContextHubWrapper == null) {
            return -1;
        }
        if (msg == null) {
@@ -563,6 +576,8 @@ public class ContextHubService extends IContextHubService.Stub {
     */
    private void handleHubEventCallback(int contextHubId, int eventType) {
        if (eventType == AsyncEventType.RESTARTED) {
            sendLocationSettingUpdate();

            mTransactionManager.onHubReset();
            queryNanoAppsInternal(contextHubId);

@@ -870,12 +885,12 @@ public class ContextHubService extends IContextHubService.Stub {
     * @param callback        the client transaction callback interface
     * @param transactionType the type of the transaction
     *
     * @return {@code true} if mContextHubProxy and contextHubId is valid, {@code false} otherwise
     * @return {@code true} if mContextHubWrapper and contextHubId is valid, {@code false} otherwise
     */
    private boolean checkHalProxyAndContextHubId(
            int contextHubId, IContextHubTransactionCallback callback,
            @ContextHubTransaction.Type int transactionType) {
        if (mContextHubProxy == null) {
        if (mContextHubWrapper == null) {
            try {
                callback.onTransactionComplete(
                        ContextHubTransaction.RESULT_FAILED_HAL_UNAVAILABLE);
@@ -898,4 +913,15 @@ public class ContextHubService extends IContextHubService.Stub {

        return true;
    }

    /**
     * Obtains the latest location setting value and notifies the Contexthub.
     */
    private void sendLocationSettingUpdate() {
        boolean enabled = mContext.getSystemService(LocationManager.class)
                .isLocationEnabledForUser(UserHandle.CURRENT);

        mContextHubWrapper.onSettingChanged(Setting.LOCATION,
                enabled ? SettingValue.ENABLED : SettingValue.DISABLED);
    }
}
+141 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.annotation.Nullable;
import android.hardware.contexthub.V1_1.Setting;
import android.hardware.contexthub.V1_1.SettingValue;
import android.os.RemoteException;
import android.util.Log;

import java.util.NoSuchElementException;

/**
 * @hide
 */
public abstract class IContextHubWrapper {
    private static final String TAG = "IContextHubWrapper";

    /**
     * Attempts to connect to the Contexthub HAL 1.0 service, if it exists.
     *
     * @return A valid IContextHubWrapper if the connection was successful, null otherwise.
     */
    @Nullable
    public static IContextHubWrapper maybeConnectTo1_0() {
        android.hardware.contexthub.V1_0.IContexthub proxy = null;
        try {
            proxy = android.hardware.contexthub.V1_0.IContexthub.getService(true /* retry */);
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException while attaching to Context Hub HAL proxy", e);
        } catch (NoSuchElementException e) {
            Log.i(TAG, "Context Hub HAL service not found");
        }

        ContextHubWrapperV1_0 wrapper = null;
        if (proxy != null) {
            wrapper = new ContextHubWrapperV1_0(proxy);
        }

        return wrapper;
    }

    /**
     * Attempts to connect to the Contexthub HAL 1.1 service, if it exists.
     *
     * @return A valid IContextHubWrapper if the connection was successful, null otherwise.
     */
    @Nullable
    public static IContextHubWrapper maybeConnectTo1_1() {
        android.hardware.contexthub.V1_1.IContexthub proxy = null;
        try {
            proxy = android.hardware.contexthub.V1_1.IContexthub.getService(true /* retry */);
        } catch (RemoteException e) {
            Log.e(TAG, "RemoteException while attaching to Context Hub HAL proxy", e);
        } catch (NoSuchElementException e) {
            Log.i(TAG, "Context Hub HAL service not found");
        }

        ContextHubWrapperV1_1 wrapper = null;
        if (proxy != null) {
            wrapper = new ContextHubWrapperV1_1(proxy);
        }

        return wrapper;
    }

    /**
     * @return A valid instance of Contexthub HAL 1.0.
     */
    public abstract android.hardware.contexthub.V1_0.IContexthub getHub();

    /**
     * @return True if this version of the Contexthub HAL supports setting notifications.
     */
    public abstract boolean supportsSettingNotifications();

    /**
     * Notifies the Contexthub implementation of a user setting change.
     *
     * @param setting The user setting that has changed. MUST be one of the values from the
     *     {@link Setting} enum
     * @param newValue The value of the user setting that changed. MUST be one of the values
     *     from the {@link SettingValue} enum.
     */
    public abstract void onSettingChanged(byte setting, byte newValue);

    private static class ContextHubWrapperV1_0 extends IContextHubWrapper {
        private android.hardware.contexthub.V1_0.IContexthub mHub;

        ContextHubWrapperV1_0(android.hardware.contexthub.V1_0.IContexthub hub) {
            mHub = hub;
        }

        public android.hardware.contexthub.V1_0.IContexthub getHub() {
            return mHub;
        }

        public boolean supportsSettingNotifications() {
            return false;
        }

        public void onSettingChanged(byte setting, byte newValue) {}
    }

    private static class ContextHubWrapperV1_1 extends IContextHubWrapper {
        private android.hardware.contexthub.V1_1.IContexthub mHub;

        ContextHubWrapperV1_1(android.hardware.contexthub.V1_1.IContexthub hub) {
            mHub = hub;
        }

        public android.hardware.contexthub.V1_0.IContexthub getHub() {
            return mHub;
        }

        public boolean supportsSettingNotifications() {
            return true;
        }

        public void onSettingChanged(byte setting, byte newValue) {
            try {
                mHub.onSettingChanged(setting, newValue);
            } catch  (RemoteException e) {
                Log.e(TAG, "Failed to send setting change to Contexthub", e);
            }
        }
    }
}