Loading core/java/android/hardware/location/ContextHubManager.java +11 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.ActivityThread; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; Loading Loading @@ -849,9 +850,18 @@ public final class ContextHubManager { attributionTag = context.getAttributionTag(); } // Workaround for old APIs not providing a context String packageName; if (context != null) { packageName = context.getPackageName(); } else { packageName = ActivityThread.currentPackageName(); } IContextHubClient clientProxy; try { clientProxy = mService.createClient(hubInfo.getId(), clientInterface, attributionTag); clientProxy = mService.createClient( hubInfo.getId(), clientInterface, attributionTag, packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading core/java/android/hardware/location/IContextHubService.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,8 @@ interface IContextHubService { // Creates a client to send and receive messages IContextHubClient createClient( int contextHubId, in IContextHubClientCallback client, in String attributionTag); int contextHubId, in IContextHubClientCallback client, in String attributionTag, in String packageName); // Creates a PendingIntent-based client to send and receive messages IContextHubClient createPendingIntentClient( Loading services/core/java/com/android/server/location/contexthub/AuthStateDenialTimer.java 0 → 100644 +105 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.contexthub; import static java.util.concurrent.TimeUnit.SECONDS; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; /** * A class that manages a timer used to keep track of how much time is left before a * {@link ContextHubClientBroker} has its authorization state changed with a nanoapp from * DENIED_GRACE_PERIOD to DENIED. Much of this implementation is copied from * {@link android.os.CountDownTimer} while adding the ability to specify the provided looper. * * @hide */ public class AuthStateDenialTimer { private static final long TIMEOUT_MS = SECONDS.toMillis(60); private final ContextHubClientBroker mClient; private final long mNanoAppId; private final Handler mHandler; /** * Indicates when the timer should stop in the future. */ private long mStopTimeInFuture; /** * boolean representing if the timer was cancelled */ private boolean mCancelled = false; public AuthStateDenialTimer(ContextHubClientBroker client, long nanoAppId, Looper looper) { mClient = client; mNanoAppId = nanoAppId; mHandler = new CountDownHandler(looper); } /** * Cancel the countdown. */ public synchronized void cancel() { mCancelled = true; mHandler.removeMessages(MSG); } /** * Start the countdown. */ public synchronized void start() { mCancelled = false; mStopTimeInFuture = SystemClock.elapsedRealtime() + TIMEOUT_MS; mHandler.sendMessage(mHandler.obtainMessage(MSG)); } /** * Called when the timer has expired. */ public void onFinish() { mClient.handleAuthStateTimerExpiry(mNanoAppId); } // Message type used to trigger the timer. private static final int MSG = 1; private class CountDownHandler extends Handler { CountDownHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { synchronized (AuthStateDenialTimer.this) { if (mCancelled) { return; } final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); if (millisLeft <= 0) { onFinish(); } else { sendMessageDelayed(obtainMessage(MSG), millisLeft); } } } }; } services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java +355 −37 File changed.Preview size limit exceeded, changes collapsed. Show changes services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java +32 −12 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; Loading Loading @@ -136,8 +137,7 @@ import java.util.function.Consumer; } } /* package */ ContextHubClientManager( Context context, IContextHubWrapper contextHubProxy) { /* package */ ContextHubClientManager(Context context, IContextHubWrapper contextHubProxy) { mContext = context; mContextHubProxy = contextHubProxy; } Loading @@ -155,13 +155,15 @@ import java.util.function.Consumer; */ /* package */ IContextHubClient registerClient( ContextHubInfo contextHubInfo, IContextHubClientCallback clientCallback, String attributionTag) { String attributionTag, ContextHubTransactionManager transactionManager, String packageName) { ContextHubClientBroker broker; synchronized (this) { short hostEndPointId = getHostEndPointId(); broker = new ContextHubClientBroker( mContext, mContextHubProxy, this /* clientManager */, contextHubInfo, hostEndPointId, clientCallback, attributionTag); hostEndPointId, clientCallback, attributionTag, transactionManager, packageName); mHostEndPointIdToClientMap.put(hostEndPointId, broker); mRegistrationRecordDeque.add( new RegistrationRecord(broker.toString(), ACTION_REGISTERED)); Loading Loading @@ -194,7 +196,7 @@ import java.util.function.Consumer; */ /* package */ IContextHubClient registerClient( ContextHubInfo contextHubInfo, PendingIntent pendingIntent, long nanoAppId, String attributionTag) { String attributionTag, ContextHubTransactionManager transactionManager) { ContextHubClientBroker broker; String registerString = "Regenerated"; synchronized (this) { Loading @@ -204,7 +206,8 @@ import java.util.function.Consumer; short hostEndPointId = getHostEndPointId(); broker = new ContextHubClientBroker( mContext, mContextHubProxy, this /* clientManager */, contextHubInfo, hostEndPointId, pendingIntent, nanoAppId, attributionTag); hostEndPointId, pendingIntent, nanoAppId, attributionTag, transactionManager); mHostEndPointIdToClientMap.put(hostEndPointId, broker); registerString = "Registered"; mRegistrationRecordDeque.add( Loading @@ -225,8 +228,13 @@ import java.util.function.Consumer; * * @param contextHubId the ID of the hub where the nanoapp sent the message from * @param message the message send by a nanoapp * @param nanoappPermissions the set of permissions the nanoapp holds * @param messagePermissions the set of permissions that should be used for attributing * permissions when this message is consumed by a client */ /* package */ void onMessageFromNanoApp(int contextHubId, ContextHubMsg message) { /* package */ void onMessageFromNanoApp( int contextHubId, ContextHubMsg message, List<String> nanoappPermissions, List<String> messagePermissions) { NanoAppMessage clientMessage = ContextHubServiceUtil.createNanoAppMessage(message); if (DEBUG_LOG_ENABLED) { Loading @@ -234,11 +242,19 @@ import java.util.function.Consumer; } if (clientMessage.isBroadcastMessage()) { broadcastMessage(contextHubId, clientMessage); // Broadcast messages shouldn't be sent with any permissions tagged per CHRE API // requirements. if (!messagePermissions.isEmpty()) { Log.wtf(TAG, "Received broadcast message with permissions from " + message.appName); } broadcastMessage( contextHubId, clientMessage, nanoappPermissions, messagePermissions); } else { ContextHubClientBroker proxy = mHostEndPointIdToClientMap.get(message.hostEndPoint); if (proxy != null) { proxy.sendMessageToClient(clientMessage); proxy.sendMessageToClient( clientMessage, nanoappPermissions, messagePermissions); } else { Log.e(TAG, "Cannot send message to unregistered client (host endpoint ID = " + message.hostEndPoint + ")"); Loading Loading @@ -333,8 +349,12 @@ import java.util.function.Consumer; * @param contextHubId the ID of the hub where the nanoapp sent the message from * @param message the message send by a nanoapp */ private void broadcastMessage(int contextHubId, NanoAppMessage message) { forEachClientOfHub(contextHubId, client -> client.sendMessageToClient(message)); private void broadcastMessage( int contextHubId, NanoAppMessage message, List<String> nanoappPermissions, List<String> messagePermissions) { forEachClientOfHub(contextHubId, client -> client.sendMessageToClient( message, nanoappPermissions, messagePermissions)); } /** Loading Loading
core/java/android/hardware/location/ContextHubManager.java +11 −1 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; import android.app.ActivityThread; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; Loading Loading @@ -849,9 +850,18 @@ public final class ContextHubManager { attributionTag = context.getAttributionTag(); } // Workaround for old APIs not providing a context String packageName; if (context != null) { packageName = context.getPackageName(); } else { packageName = ActivityThread.currentPackageName(); } IContextHubClient clientProxy; try { clientProxy = mService.createClient(hubInfo.getId(), clientInterface, attributionTag); clientProxy = mService.createClient( hubInfo.getId(), clientInterface, attributionTag, packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } Loading
core/java/android/hardware/location/IContextHubService.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -60,7 +60,8 @@ interface IContextHubService { // Creates a client to send and receive messages IContextHubClient createClient( int contextHubId, in IContextHubClientCallback client, in String attributionTag); int contextHubId, in IContextHubClientCallback client, in String attributionTag, in String packageName); // Creates a PendingIntent-based client to send and receive messages IContextHubClient createPendingIntentClient( Loading
services/core/java/com/android/server/location/contexthub/AuthStateDenialTimer.java 0 → 100644 +105 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 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.contexthub; import static java.util.concurrent.TimeUnit.SECONDS; import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; /** * A class that manages a timer used to keep track of how much time is left before a * {@link ContextHubClientBroker} has its authorization state changed with a nanoapp from * DENIED_GRACE_PERIOD to DENIED. Much of this implementation is copied from * {@link android.os.CountDownTimer} while adding the ability to specify the provided looper. * * @hide */ public class AuthStateDenialTimer { private static final long TIMEOUT_MS = SECONDS.toMillis(60); private final ContextHubClientBroker mClient; private final long mNanoAppId; private final Handler mHandler; /** * Indicates when the timer should stop in the future. */ private long mStopTimeInFuture; /** * boolean representing if the timer was cancelled */ private boolean mCancelled = false; public AuthStateDenialTimer(ContextHubClientBroker client, long nanoAppId, Looper looper) { mClient = client; mNanoAppId = nanoAppId; mHandler = new CountDownHandler(looper); } /** * Cancel the countdown. */ public synchronized void cancel() { mCancelled = true; mHandler.removeMessages(MSG); } /** * Start the countdown. */ public synchronized void start() { mCancelled = false; mStopTimeInFuture = SystemClock.elapsedRealtime() + TIMEOUT_MS; mHandler.sendMessage(mHandler.obtainMessage(MSG)); } /** * Called when the timer has expired. */ public void onFinish() { mClient.handleAuthStateTimerExpiry(mNanoAppId); } // Message type used to trigger the timer. private static final int MSG = 1; private class CountDownHandler extends Handler { CountDownHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { synchronized (AuthStateDenialTimer.this) { if (mCancelled) { return; } final long millisLeft = mStopTimeInFuture - SystemClock.elapsedRealtime(); if (millisLeft <= 0) { onFinish(); } else { sendMessageDelayed(obtainMessage(MSG), millisLeft); } } } }; }
services/core/java/com/android/server/location/contexthub/ContextHubClientBroker.java +355 −37 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/core/java/com/android/server/location/contexthub/ContextHubClientManager.java +32 −12 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; Loading Loading @@ -136,8 +137,7 @@ import java.util.function.Consumer; } } /* package */ ContextHubClientManager( Context context, IContextHubWrapper contextHubProxy) { /* package */ ContextHubClientManager(Context context, IContextHubWrapper contextHubProxy) { mContext = context; mContextHubProxy = contextHubProxy; } Loading @@ -155,13 +155,15 @@ import java.util.function.Consumer; */ /* package */ IContextHubClient registerClient( ContextHubInfo contextHubInfo, IContextHubClientCallback clientCallback, String attributionTag) { String attributionTag, ContextHubTransactionManager transactionManager, String packageName) { ContextHubClientBroker broker; synchronized (this) { short hostEndPointId = getHostEndPointId(); broker = new ContextHubClientBroker( mContext, mContextHubProxy, this /* clientManager */, contextHubInfo, hostEndPointId, clientCallback, attributionTag); hostEndPointId, clientCallback, attributionTag, transactionManager, packageName); mHostEndPointIdToClientMap.put(hostEndPointId, broker); mRegistrationRecordDeque.add( new RegistrationRecord(broker.toString(), ACTION_REGISTERED)); Loading Loading @@ -194,7 +196,7 @@ import java.util.function.Consumer; */ /* package */ IContextHubClient registerClient( ContextHubInfo contextHubInfo, PendingIntent pendingIntent, long nanoAppId, String attributionTag) { String attributionTag, ContextHubTransactionManager transactionManager) { ContextHubClientBroker broker; String registerString = "Regenerated"; synchronized (this) { Loading @@ -204,7 +206,8 @@ import java.util.function.Consumer; short hostEndPointId = getHostEndPointId(); broker = new ContextHubClientBroker( mContext, mContextHubProxy, this /* clientManager */, contextHubInfo, hostEndPointId, pendingIntent, nanoAppId, attributionTag); hostEndPointId, pendingIntent, nanoAppId, attributionTag, transactionManager); mHostEndPointIdToClientMap.put(hostEndPointId, broker); registerString = "Registered"; mRegistrationRecordDeque.add( Loading @@ -225,8 +228,13 @@ import java.util.function.Consumer; * * @param contextHubId the ID of the hub where the nanoapp sent the message from * @param message the message send by a nanoapp * @param nanoappPermissions the set of permissions the nanoapp holds * @param messagePermissions the set of permissions that should be used for attributing * permissions when this message is consumed by a client */ /* package */ void onMessageFromNanoApp(int contextHubId, ContextHubMsg message) { /* package */ void onMessageFromNanoApp( int contextHubId, ContextHubMsg message, List<String> nanoappPermissions, List<String> messagePermissions) { NanoAppMessage clientMessage = ContextHubServiceUtil.createNanoAppMessage(message); if (DEBUG_LOG_ENABLED) { Loading @@ -234,11 +242,19 @@ import java.util.function.Consumer; } if (clientMessage.isBroadcastMessage()) { broadcastMessage(contextHubId, clientMessage); // Broadcast messages shouldn't be sent with any permissions tagged per CHRE API // requirements. if (!messagePermissions.isEmpty()) { Log.wtf(TAG, "Received broadcast message with permissions from " + message.appName); } broadcastMessage( contextHubId, clientMessage, nanoappPermissions, messagePermissions); } else { ContextHubClientBroker proxy = mHostEndPointIdToClientMap.get(message.hostEndPoint); if (proxy != null) { proxy.sendMessageToClient(clientMessage); proxy.sendMessageToClient( clientMessage, nanoappPermissions, messagePermissions); } else { Log.e(TAG, "Cannot send message to unregistered client (host endpoint ID = " + message.hostEndPoint + ")"); Loading Loading @@ -333,8 +349,12 @@ import java.util.function.Consumer; * @param contextHubId the ID of the hub where the nanoapp sent the message from * @param message the message send by a nanoapp */ private void broadcastMessage(int contextHubId, NanoAppMessage message) { forEachClientOfHub(contextHubId, client -> client.sendMessageToClient(message)); private void broadcastMessage( int contextHubId, NanoAppMessage message, List<String> nanoappPermissions, List<String> messagePermissions) { forEachClientOfHub(contextHubId, client -> client.sendMessageToClient( message, nanoappPermissions, messagePermissions)); } /** Loading