Loading Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -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", Loading services/core/java/com/android/server/location/ContextHubService.java +51 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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(); Loading @@ -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 = " Loading @@ -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); } } /** Loading Loading @@ -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 Loading Loading @@ -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)) { Loading @@ -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; } Loading Loading @@ -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; } Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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); } } services/core/java/com/android/server/location/IContextHubWrapper.java 0 → 100644 +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); } } } } Loading
Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -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", Loading
services/core/java/com/android/server/location/ContextHubService.java +51 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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 Loading Loading @@ -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; Loading Loading @@ -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(); Loading @@ -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(); Loading @@ -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 = " Loading @@ -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); } } /** Loading Loading @@ -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 Loading Loading @@ -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)) { Loading @@ -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; } Loading Loading @@ -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; } Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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); Loading @@ -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); } }
services/core/java/com/android/server/location/IContextHubWrapper.java 0 → 100644 +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); } } } }