summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java87
-rw-r--r--services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java122
2 files changed, 156 insertions, 53 deletions
diff --git a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java
index 766283b92d91..028288f73564 100644
--- a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java
+++ b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerPerUserService.java
@@ -43,7 +43,6 @@ import android.os.RemoteException;
import android.service.ambientcontext.AmbientContextDetectionResult;
import android.service.ambientcontext.AmbientContextDetectionServiceStatus;
import android.text.TextUtils;
-import android.util.ArraySet;
import android.util.IndentingPrintWriter;
import android.util.Slog;
@@ -54,7 +53,6 @@ import com.android.server.infra.AbstractPerUserSystemService;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Set;
/**
* Per-user manager service for {@link AmbientContextEvent}s.
@@ -69,19 +67,13 @@ final class AmbientContextManagerPerUserService extends
RemoteAmbientContextDetectionService mRemoteService;
private ComponentName mComponentName;
- private Set<PendingIntent> mExistingPendingIntents;
AmbientContextManagerPerUserService(
@NonNull AmbientContextManagerService master, Object lock, @UserIdInt int userId) {
super(master, lock, userId);
- mExistingPendingIntents = new ArraySet<>();
}
void destroyLocked() {
- if (isVerbose()) {
- Slog.v(TAG, "destroyLocked()");
- }
-
Slog.d(TAG, "Trying to cancel the remote request. Reason: Service destroyed.");
if (mRemoteService != null) {
synchronized (mLock) {
@@ -118,7 +110,19 @@ final class AmbientContextManagerPerUserService extends
if (mComponentName == null) {
mComponentName = updateServiceInfoLocked();
}
- return mComponentName != null;
+ if (mComponentName == null) {
+ return false;
+ }
+
+ ServiceInfo serviceInfo;
+ try {
+ serviceInfo = AppGlobals.getPackageManager().getServiceInfo(
+ mComponentName, 0, mUserId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "RemoteException while setting up service");
+ return false;
+ }
+ return serviceInfo != null;
}
@Override
@@ -171,18 +175,10 @@ final class AmbientContextManagerPerUserService extends
return;
}
- // Remove any existing PendingIntent for this package.
- String callingPackage = pendingIntent.getCreatorPackage();
- PendingIntent duplicatePendingIntent = findExistingRequestByPackage(callingPackage);
- if (duplicatePendingIntent != null) {
- Slog.d(TAG, "Replace duplicate request from " + callingPackage);
- mExistingPendingIntents.remove(duplicatePendingIntent);
- }
-
- // Register package and add pendingIntent to mExistingPendingIntents
- startDetection(request, callingPackage, createDetectionResultRemoteCallback(),
- getServerStatusCallback(clientStatusCallback));
- mExistingPendingIntents.add(pendingIntent);
+ // Register package and add to existing ClientRequests cache
+ startDetection(request, pendingIntent.getCreatorPackage(),
+ createDetectionResultRemoteCallback(), clientStatusCallback);
+ mMaster.newClientAdded(mUserId, request, pendingIntent, clientStatusCallback);
}
}
@@ -214,15 +210,17 @@ final class AmbientContextManagerPerUserService extends
@VisibleForTesting
void startDetection(AmbientContextEventRequest request, String callingPackage,
- RemoteCallback detectionResultCallback, RemoteCallback statusCallback) {
+ RemoteCallback detectionResultCallback, RemoteCallback clientStatusCallback) {
Slog.d(TAG, "Requested detection of " + request.getEventTypes());
synchronized (mLock) {
if (setUpServiceIfNeeded()) {
ensureRemoteServiceInitiated();
mRemoteService.startDetection(request, callingPackage, detectionResultCallback,
- statusCallback);
+ getServerStatusCallback(clientStatusCallback));
} else {
Slog.w(TAG, "No valid component found for AmbientContextDetectionService");
+ sendStatusToCallback(clientStatusCallback,
+ AmbientContextManager.STATUS_NOT_SUPPORTED);
}
}
}
@@ -245,15 +243,8 @@ final class AmbientContextManagerPerUserService extends
*/
public void onUnregisterObserver(String callingPackage) {
synchronized (mLock) {
- PendingIntent pendingIntent = findExistingRequestByPackage(callingPackage);
- if (pendingIntent == null) {
- Slog.d(TAG, "No registration found for " + callingPackage);
- return;
- }
-
- // Remove from existing requests
- mExistingPendingIntents.remove(pendingIntent);
- stopDetection(pendingIntent.getCreatorPackage());
+ stopDetection(callingPackage);
+ mMaster.clientRemoved(mUserId, callingPackage);
}
}
@@ -265,7 +256,7 @@ final class AmbientContextManagerPerUserService extends
if (!setUpServiceIfNeeded()) {
Slog.w(TAG, "Detection service is not available at this moment.");
sendStatusToCallback(statusCallback,
- AmbientContextManager.STATUS_SERVICE_UNAVAILABLE);
+ AmbientContextManager.STATUS_NOT_SUPPORTED);
return;
}
ensureRemoteServiceInitiated();
@@ -382,16 +373,6 @@ final class AmbientContextManagerPerUserService extends
}
}
- @Nullable
- private PendingIntent findExistingRequestByPackage(String callingPackage) {
- for (PendingIntent pendingIntent : mExistingPendingIntents) {
- if (pendingIntent.getCreatorPackage().equals(callingPackage)) {
- return pendingIntent;
- }
- }
- return null;
- }
-
/**
* Sends out the Intent to the client after the event is detected.
*
@@ -418,22 +399,22 @@ final class AmbientContextManagerPerUserService extends
}
@NonNull
- private RemoteCallback createDetectionResultRemoteCallback() {
+ RemoteCallback createDetectionResultRemoteCallback() {
return new RemoteCallback(result -> {
AmbientContextDetectionResult detectionResult =
(AmbientContextDetectionResult) result.get(
AmbientContextDetectionResult.RESULT_RESPONSE_BUNDLE_KEY);
+ String packageName = detectionResult.getPackageName();
+ PendingIntent pendingIntent = mMaster.getPendingIntent(mUserId, packageName);
+ if (pendingIntent == null) {
+ return;
+ }
+
final long token = Binder.clearCallingIdentity();
try {
- for (PendingIntent pendingIntent : mExistingPendingIntents) {
- // Send PendingIntent to requesting packages
- String creatorPackage = pendingIntent.getCreatorPackage();
- if (detectionResult.getPackageName().equals(creatorPackage)) {
- sendDetectionResultIntent(pendingIntent, detectionResult);
- Slog.i(TAG, "Got detection result of " + detectionResult.getEvents()
- + " for " + creatorPackage);
- }
- }
+ sendDetectionResultIntent(pendingIntent, detectionResult);
+ Slog.i(TAG, "Got detection result of " + detectionResult.getEvents()
+ + " for " + packageName);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
index cfca7ec6f568..4206262398c7 100644
--- a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
+++ b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
@@ -20,6 +20,7 @@ import static android.provider.DeviceConfig.NAMESPACE_AMBIENT_CONTEXT_MANAGER_SE
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.PendingIntent;
import android.app.ambientcontext.AmbientContextEvent;
@@ -34,6 +35,7 @@ import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.UserHandle;
import android.provider.DeviceConfig;
+import android.util.ArraySet;
import android.util.Slog;
import com.android.internal.R;
@@ -60,9 +62,50 @@ public class AmbientContextManagerService extends
/** Default value in absence of {@link DeviceConfig} override. */
private static final boolean DEFAULT_SERVICE_ENABLED = true;
+ public static final int MAX_TEMPORARY_SERVICE_DURATION_MS = 30000;
+
+ static class ClientRequest {
+ private final int mUserId;
+ private final AmbientContextEventRequest mRequest;
+ private final PendingIntent mPendingIntent;
+ private final RemoteCallback mClientStatusCallback;
+
+ ClientRequest(int userId, AmbientContextEventRequest request,
+ PendingIntent pendingIntent, RemoteCallback clientStatusCallback) {
+ this.mUserId = userId;
+ this.mRequest = request;
+ this.mPendingIntent = pendingIntent;
+ this.mClientStatusCallback = clientStatusCallback;
+ }
+
+ String getPackageName() {
+ return mPendingIntent.getCreatorPackage();
+ }
+
+ AmbientContextEventRequest getRequest() {
+ return mRequest;
+ }
+
+ PendingIntent getPendingIntent() {
+ return mPendingIntent;
+ }
+
+ RemoteCallback getClientStatusCallback() {
+ return mClientStatusCallback;
+ }
+
+ boolean hasUserId(int userId) {
+ return mUserId == userId;
+ }
+
+ boolean hasUserIdAndPackageName(int userId, String packageName) {
+ return (userId == mUserId) && packageName.equals(getPackageName());
+ }
+ }
private final Context mContext;
boolean mIsServiceEnabled;
+ private Set<ClientRequest> mExistingClientRequests;
public AmbientContextManagerService(Context context) {
super(context,
@@ -73,6 +116,7 @@ public class AmbientContextManagerService extends
PACKAGE_UPDATE_POLICY_REFRESH_EAGER
| /*To avoid high latency*/ PACKAGE_RESTART_POLICY_REFRESH_EAGER);
mContext = context;
+ mExistingClientRequests = new ArraySet<>();
}
@Override
@@ -94,6 +138,44 @@ public class AmbientContextManagerService extends
}
}
+ void newClientAdded(int userId, AmbientContextEventRequest request,
+ PendingIntent pendingIntent, RemoteCallback clientStatusCallback) {
+ Slog.d(TAG, "New client added: " + pendingIntent.getCreatorPackage());
+
+ // Remove any existing ClientRequest for this user and package.
+ mExistingClientRequests.removeAll(
+ findExistingRequests(userId, pendingIntent.getCreatorPackage()));
+
+ // Add to existing ClientRequests
+ mExistingClientRequests.add(
+ new ClientRequest(userId, request, pendingIntent, clientStatusCallback));
+ }
+
+ void clientRemoved(int userId, String packageName) {
+ Slog.d(TAG, "Remove client: " + packageName);
+ mExistingClientRequests.removeAll(findExistingRequests(userId, packageName));
+ }
+
+ private Set<ClientRequest> findExistingRequests(int userId, String packageName) {
+ Set<ClientRequest> existingRequests = new ArraySet<>();
+ for (ClientRequest clientRequest : mExistingClientRequests) {
+ if (clientRequest.hasUserIdAndPackageName(userId, packageName)) {
+ existingRequests.add(clientRequest);
+ }
+ }
+ return existingRequests;
+ }
+
+ @Nullable
+ PendingIntent getPendingIntent(int userId, String packageName) {
+ for (ClientRequest clientRequest : mExistingClientRequests) {
+ if (clientRequest.hasUserIdAndPackageName(userId, packageName)) {
+ return clientRequest.getPendingIntent();
+ }
+ }
+ return null;
+ }
+
private void onDeviceConfigChange(@NonNull Set<String> keys) {
if (keys.contains(KEY_SERVICE_ENABLED)) {
mIsServiceEnabled = DeviceConfig.getBoolean(
@@ -111,9 +193,33 @@ public class AmbientContextManagerService extends
@Override
protected void onServiceRemoved(
AmbientContextManagerPerUserService service, @UserIdInt int userId) {
+ Slog.d(TAG, "onServiceRemoved");
service.destroyLocked();
}
+ @Override
+ protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+ Slog.d(TAG, "Restoring remote request. Reason: Service package restarted.");
+ restorePreviouslyEnabledClients(userId);
+ }
+
+ @Override
+ protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+ Slog.d(TAG, "Restoring remote request. Reason: Service package updated.");
+ restorePreviouslyEnabledClients(userId);
+ }
+
+ @Override
+ protected void enforceCallingPermissionForManagement() {
+ getContext().enforceCallingPermission(
+ Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG);
+ }
+
+ @Override
+ protected int getMaximumTemporaryServiceDurationMs() {
+ return MAX_TEMPORARY_SERVICE_DURATION_MS;
+ }
+
/** Returns {@code true} if the detection service is configured on this device. */
public static boolean isDetectionServiceConfigured() {
final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
@@ -182,6 +288,22 @@ public class AmbientContextManagerService extends
}
}
+ private void restorePreviouslyEnabledClients(int userId) {
+ synchronized (mLock) {
+ final AmbientContextManagerPerUserService service = getServiceForUserLocked(userId);
+ for (ClientRequest clientRequest : mExistingClientRequests) {
+ // Start detection for previously enabled clients
+ if (clientRequest.hasUserId(userId)) {
+ Slog.d(TAG, "Restoring detection for " + clientRequest.getPackageName());
+ service.startDetection(clientRequest.getRequest(),
+ clientRequest.getPackageName(),
+ service.createDetectionResultRemoteCallback(),
+ clientRequest.getClientStatusCallback());
+ }
+ }
+ }
+ }
+
/**
* Returns the AmbientContextManagerPerUserService component for this user.
*/