1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.ambientcontext; 18 19 import static android.provider.DeviceConfig.NAMESPACE_AMBIENT_CONTEXT_MANAGER_SERVICE; 20 import static android.provider.DeviceConfig.NAMESPACE_WEARABLE_SENSING; 21 22 import android.Manifest; 23 import android.annotation.NonNull; 24 import android.annotation.Nullable; 25 import android.annotation.UserIdInt; 26 import android.app.PendingIntent; 27 import android.app.ambientcontext.AmbientContextEvent; 28 import android.app.ambientcontext.AmbientContextEventRequest; 29 import android.app.ambientcontext.AmbientContextManager; 30 import android.app.ambientcontext.IAmbientContextManager; 31 import android.app.ambientcontext.IAmbientContextObserver; 32 import android.content.ComponentName; 33 import android.content.Context; 34 import android.content.pm.PackageManagerInternal; 35 import android.os.RemoteCallback; 36 import android.os.RemoteException; 37 import android.os.ResultReceiver; 38 import android.os.ShellCallback; 39 import android.os.UserHandle; 40 import android.provider.DeviceConfig; 41 import android.util.ArraySet; 42 import android.util.Slog; 43 44 import com.android.internal.R; 45 import com.android.internal.util.DumpUtils; 46 import com.android.server.LocalServices; 47 import com.android.server.SystemService; 48 import com.android.server.ambientcontext.AmbientContextManagerPerUserService.ServiceType; 49 import com.android.server.infra.AbstractMasterSystemService; 50 import com.android.server.infra.FrameworkResourcesServiceNameResolver; 51 import com.android.server.pm.KnownPackages; 52 53 import com.google.android.collect.Sets; 54 55 import java.io.FileDescriptor; 56 import java.io.PrintWriter; 57 import java.util.ArrayList; 58 import java.util.Arrays; 59 import java.util.HashSet; 60 import java.util.List; 61 import java.util.Objects; 62 import java.util.Set; 63 import java.util.concurrent.ConcurrentHashMap; 64 65 /** 66 * System service for managing {@link AmbientContextEvent}s. 67 */ 68 public class AmbientContextManagerService extends 69 AbstractMasterSystemService<AmbientContextManagerService, 70 AmbientContextManagerPerUserService> { 71 private static final String TAG = AmbientContextManagerService.class.getSimpleName(); 72 private static final String KEY_SERVICE_ENABLED = "service_enabled"; 73 private static final Set<Integer> DEFAULT_EVENT_SET = Sets.newHashSet( 74 AmbientContextEvent.EVENT_COUGH, 75 AmbientContextEvent.EVENT_SNORE, 76 AmbientContextEvent.EVENT_BACK_DOUBLE_TAP); 77 78 /** Default value in absence of {@link DeviceConfig} override. */ 79 private static final boolean DEFAULT_SERVICE_ENABLED = true; 80 public static final int MAX_TEMPORARY_SERVICE_DURATION_MS = 30000; 81 82 static class ClientRequest { 83 private final int mUserId; 84 private final AmbientContextEventRequest mRequest; 85 private final String mPackageName; 86 private final IAmbientContextObserver mObserver; 87 ClientRequest(int userId, AmbientContextEventRequest request, String packageName, IAmbientContextObserver observer)88 ClientRequest(int userId, AmbientContextEventRequest request, 89 String packageName, IAmbientContextObserver observer) { 90 this.mUserId = userId; 91 this.mRequest = request; 92 this.mPackageName = packageName; 93 this.mObserver = observer; 94 } 95 getPackageName()96 String getPackageName() { 97 return mPackageName; 98 } 99 getRequest()100 AmbientContextEventRequest getRequest() { 101 return mRequest; 102 } 103 getObserver()104 IAmbientContextObserver getObserver() { 105 return mObserver; 106 } 107 hasUserId(int userId)108 boolean hasUserId(int userId) { 109 return mUserId == userId; 110 } 111 hasUserIdAndPackageName(int userId, String packageName)112 boolean hasUserIdAndPackageName(int userId, String packageName) { 113 return (userId == mUserId) && packageName.equals(getPackageName()); 114 } 115 } 116 117 private final Context mContext; 118 boolean mIsServiceEnabled; 119 boolean mIsWearableServiceEnabled; 120 private Set<ClientRequest> mExistingClientRequests; 121 AmbientContextManagerService(Context context)122 public AmbientContextManagerService(Context context) { 123 super(context, 124 new FrameworkResourcesServiceNameResolver( 125 context, 126 R.array.config_defaultAmbientContextServices, 127 /*isMultiple=*/ true), 128 /*disallowProperty=*/null, 129 PACKAGE_UPDATE_POLICY_REFRESH_EAGER 130 | /*To avoid high latency*/ PACKAGE_RESTART_POLICY_REFRESH_EAGER); 131 mContext = context; 132 mExistingClientRequests = new ArraySet<>(); 133 } 134 135 @Override onStart()136 public void onStart() { 137 publishBinderService(Context.AMBIENT_CONTEXT_SERVICE, new AmbientContextManagerInternal()); 138 } 139 140 @Override onBootPhase(int phase)141 public void onBootPhase(int phase) { 142 if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { 143 DeviceConfig.addOnPropertiesChangedListener( 144 NAMESPACE_AMBIENT_CONTEXT_MANAGER_SERVICE, 145 getContext().getMainExecutor(), 146 (properties) -> onDeviceConfigChange(properties.getKeyset())); 147 148 mIsServiceEnabled = DeviceConfig.getBoolean( 149 NAMESPACE_AMBIENT_CONTEXT_MANAGER_SERVICE, 150 KEY_SERVICE_ENABLED, DEFAULT_SERVICE_ENABLED); 151 mIsWearableServiceEnabled = DeviceConfig.getBoolean( 152 NAMESPACE_WEARABLE_SENSING, 153 KEY_SERVICE_ENABLED, DEFAULT_SERVICE_ENABLED); 154 } 155 } 156 newClientAdded(int userId, AmbientContextEventRequest request, String callingPackage, IAmbientContextObserver observer)157 void newClientAdded(int userId, AmbientContextEventRequest request, 158 String callingPackage, IAmbientContextObserver observer) { 159 Slog.d(TAG, "New client added: " + callingPackage); 160 161 // Remove any existing ClientRequest for this user and package. 162 mExistingClientRequests.removeAll( 163 findExistingRequests(userId, callingPackage)); 164 165 // Add to existing ClientRequests 166 mExistingClientRequests.add( 167 new ClientRequest(userId, request, callingPackage, observer)); 168 } 169 clientRemoved(int userId, String packageName)170 void clientRemoved(int userId, String packageName) { 171 Slog.d(TAG, "Remove client: " + packageName); 172 mExistingClientRequests.removeAll(findExistingRequests(userId, packageName)); 173 } 174 findExistingRequests(int userId, String packageName)175 private Set<ClientRequest> findExistingRequests(int userId, String packageName) { 176 Set<ClientRequest> existingRequests = new ArraySet<>(); 177 for (ClientRequest clientRequest : mExistingClientRequests) { 178 if (clientRequest.hasUserIdAndPackageName(userId, packageName)) { 179 existingRequests.add(clientRequest); 180 } 181 } 182 return existingRequests; 183 } 184 185 @Nullable getClientRequestObserver(int userId, String packageName)186 IAmbientContextObserver getClientRequestObserver(int userId, String packageName) { 187 for (ClientRequest clientRequest : mExistingClientRequests) { 188 if (clientRequest.hasUserIdAndPackageName(userId, packageName)) { 189 return clientRequest.getObserver(); 190 } 191 } 192 return null; 193 } 194 onDeviceConfigChange(@onNull Set<String> keys)195 private void onDeviceConfigChange(@NonNull Set<String> keys) { 196 if (keys.contains(KEY_SERVICE_ENABLED)) { 197 mIsServiceEnabled = DeviceConfig.getBoolean( 198 NAMESPACE_AMBIENT_CONTEXT_MANAGER_SERVICE, 199 KEY_SERVICE_ENABLED, DEFAULT_SERVICE_ENABLED); 200 mIsWearableServiceEnabled = DeviceConfig.getBoolean( 201 NAMESPACE_WEARABLE_SENSING, 202 KEY_SERVICE_ENABLED, DEFAULT_SERVICE_ENABLED); 203 } 204 } 205 206 @Override newServiceLocked(int resolvedUserId, boolean disabled)207 protected AmbientContextManagerPerUserService newServiceLocked(int resolvedUserId, 208 boolean disabled) { 209 // This service uses newServiceListLocked, it is configured in multiple mode. 210 return null; 211 } 212 213 @Override // from AbstractMasterSystemService newServiceListLocked(int resolvedUserId, boolean disabled, String[] serviceNames)214 protected List<AmbientContextManagerPerUserService> newServiceListLocked(int resolvedUserId, 215 boolean disabled, String[] serviceNames) { 216 if (serviceNames == null || serviceNames.length == 0) { 217 Slog.i(TAG, "serviceNames sent in newServiceListLocked is null, or empty"); 218 return new ArrayList<>(); 219 } 220 221 List<AmbientContextManagerPerUserService> serviceList = 222 new ArrayList<>(serviceNames.length); 223 if (serviceNames.length == 2) { 224 Slog.i(TAG, "Not using default services, " 225 + "services provided for testing should be exactly two services."); 226 if (!isDefaultService(serviceNames[0]) && !isDefaultWearableService(serviceNames[1])) { 227 serviceList.add(new DefaultAmbientContextManagerPerUserService( 228 this, mLock, resolvedUserId, 229 AmbientContextManagerPerUserService.ServiceType.DEFAULT, serviceNames[0])); 230 serviceList.add(new WearableAmbientContextManagerPerUserService( 231 this, mLock, resolvedUserId, 232 AmbientContextManagerPerUserService.ServiceType.WEARABLE, 233 serviceNames[1])); 234 } 235 return serviceList; 236 } else { 237 Slog.i(TAG, "Incorrect number of services provided for testing."); 238 } 239 240 for (String serviceName : serviceNames) { 241 Slog.d(TAG, "newServicesListLocked with service name: " + serviceName); 242 if (getServiceType(serviceName) 243 == AmbientContextManagerPerUserService.ServiceType.WEARABLE) { 244 serviceList.add(new 245 WearableAmbientContextManagerPerUserService( 246 this, mLock, resolvedUserId, 247 AmbientContextManagerPerUserService.ServiceType.WEARABLE, serviceName)); 248 } else { 249 serviceList.add(new DefaultAmbientContextManagerPerUserService( 250 this, mLock, resolvedUserId, 251 AmbientContextManagerPerUserService.ServiceType.DEFAULT, serviceName)); 252 } 253 254 } 255 return serviceList; 256 } 257 258 @Override onServiceRemoved( AmbientContextManagerPerUserService service, @UserIdInt int userId)259 protected void onServiceRemoved( 260 AmbientContextManagerPerUserService service, @UserIdInt int userId) { 261 Slog.d(TAG, "onServiceRemoved"); 262 service.destroyLocked(); 263 } 264 265 @Override onServicePackageRestartedLocked(@serIdInt int userId)266 protected void onServicePackageRestartedLocked(@UserIdInt int userId) { 267 Slog.d(TAG, "Restoring remote request. Reason: Service package restarted."); 268 restorePreviouslyEnabledClients(userId); 269 } 270 271 @Override onServicePackageUpdatedLocked(@serIdInt int userId)272 protected void onServicePackageUpdatedLocked(@UserIdInt int userId) { 273 Slog.d(TAG, "Restoring remote request. Reason: Service package updated."); 274 restorePreviouslyEnabledClients(userId); 275 } 276 277 @Override enforceCallingPermissionForManagement()278 protected void enforceCallingPermissionForManagement() { 279 getContext().enforceCallingPermission( 280 Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG); 281 } 282 283 @Override getMaximumTemporaryServiceDurationMs()284 protected int getMaximumTemporaryServiceDurationMs() { 285 return MAX_TEMPORARY_SERVICE_DURATION_MS; 286 } 287 288 /** Returns {@code true} if the detection service is configured on this device. */ isDetectionServiceConfigured()289 public static boolean isDetectionServiceConfigured() { 290 final PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class); 291 final String[] packageNames = pmi.getKnownPackageNames( 292 KnownPackages.PACKAGE_AMBIENT_CONTEXT_DETECTION, UserHandle.USER_SYSTEM); 293 boolean isServiceConfigured = (packageNames.length != 0); 294 Slog.i(TAG, "Detection service configured: " + isServiceConfigured); 295 return isServiceConfigured; 296 } 297 298 /** 299 * Send request to the remote AmbientContextDetectionService impl to start detecting the 300 * specified events. Intended for use by shell command for testing. 301 * Requires ACCESS_AMBIENT_CONTEXT_EVENT permission. 302 */ startDetection(@serIdInt int userId, AmbientContextEventRequest request, String packageName, IAmbientContextObserver observer)303 void startDetection(@UserIdInt int userId, AmbientContextEventRequest request, 304 String packageName, IAmbientContextObserver observer) { 305 mContext.enforceCallingOrSelfPermission( 306 Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG); 307 synchronized (mLock) { 308 AmbientContextManagerPerUserService service = 309 getAmbientContextManagerPerUserServiceForEventTypes( 310 userId, 311 request.getEventTypes()); 312 if (service != null) { 313 service.startDetection(request, packageName, observer); 314 } else { 315 Slog.i(TAG, "service not available for user_id: " + userId); 316 } 317 } 318 } 319 320 /** 321 * Send request to the remote AmbientContextDetectionService impl to stop detecting the 322 * specified events. Intended for use by shell command for testing. 323 * Requires ACCESS_AMBIENT_CONTEXT_EVENT permission. 324 */ stopAmbientContextEvent(@serIdInt int userId, String packageName)325 void stopAmbientContextEvent(@UserIdInt int userId, String packageName) { 326 mContext.enforceCallingOrSelfPermission( 327 Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG); 328 synchronized (mLock) { 329 for (ClientRequest cr : mExistingClientRequests) { 330 Slog.i(TAG, "Looping through clients"); 331 if (cr.hasUserIdAndPackageName(userId, packageName)) { 332 Slog.i(TAG, "we have an existing client"); 333 AmbientContextManagerPerUserService service = 334 getAmbientContextManagerPerUserServiceForEventTypes( 335 userId, cr.getRequest().getEventTypes()); 336 if (service != null) { 337 service.stopDetection(packageName); 338 } else { 339 Slog.i(TAG, "service not available for user_id: " + userId); 340 } 341 } 342 } 343 } 344 } 345 346 /** 347 * Send request to the remote AmbientContextDetectionService impl to query the status of the 348 * specified events. Intended for use by shell command for testing. 349 * Requires ACCESS_AMBIENT_CONTEXT_EVENT permission. 350 */ queryServiceStatus(@serIdInt int userId, String packageName, int[] eventTypes, RemoteCallback callback)351 void queryServiceStatus(@UserIdInt int userId, String packageName, 352 int[] eventTypes, RemoteCallback callback) { 353 mContext.enforceCallingOrSelfPermission( 354 Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG); 355 synchronized (mLock) { 356 AmbientContextManagerPerUserService service = 357 getAmbientContextManagerPerUserServiceForEventTypes( 358 userId, intArrayToIntegerSet(eventTypes)); 359 if (service != null) { 360 service.onQueryServiceStatus(eventTypes, packageName, callback); 361 } else { 362 Slog.i(TAG, "query service not available for user_id: " + userId); 363 } 364 } 365 } 366 restorePreviouslyEnabledClients(int userId)367 private void restorePreviouslyEnabledClients(int userId) { 368 synchronized (mLock) { 369 final List<AmbientContextManagerPerUserService> services = 370 getServiceListForUserLocked(userId); 371 for (AmbientContextManagerPerUserService service : services) { 372 for (ClientRequest clientRequest : mExistingClientRequests) { 373 // Start detection for previously enabled clients 374 if (clientRequest.hasUserId(userId)) { 375 Slog.d(TAG, "Restoring detection for " 376 + clientRequest.getPackageName()); 377 service.startDetection(clientRequest.getRequest(), 378 clientRequest.getPackageName(), 379 clientRequest.getObserver()); 380 } 381 } 382 } 383 } 384 } 385 386 /** 387 * Returns the AmbientContextManagerPerUserService component for this user. 388 */ getComponentName( @serIdInt int userId, AmbientContextManagerPerUserService.ServiceType serviceType)389 public ComponentName getComponentName( 390 @UserIdInt int userId, 391 AmbientContextManagerPerUserService.ServiceType serviceType) { 392 synchronized (mLock) { 393 final AmbientContextManagerPerUserService service = 394 getServiceForType(userId, serviceType); 395 if (service != null) { 396 return service.getComponentName(); 397 } 398 } 399 return null; 400 } 401 getAmbientContextManagerPerUserServiceForEventTypes( @serIdInt int userId, Set<Integer> eventTypes)402 private AmbientContextManagerPerUserService getAmbientContextManagerPerUserServiceForEventTypes( 403 @UserIdInt int userId, Set<Integer> eventTypes) { 404 if (isWearableEventTypesOnly(eventTypes)) { 405 return getServiceForType(userId, 406 AmbientContextManagerPerUserService.ServiceType.WEARABLE); 407 } else { 408 return getServiceForType(userId, 409 AmbientContextManagerPerUserService.ServiceType.DEFAULT); 410 } 411 } 412 getServiceType(String serviceName)413 private AmbientContextManagerPerUserService.ServiceType getServiceType(String serviceName) { 414 final String wearableService = mContext.getResources() 415 .getString(R.string.config_defaultWearableSensingService); 416 if (wearableService != null && wearableService.equals(serviceName)) { 417 return AmbientContextManagerPerUserService.ServiceType.WEARABLE; 418 } 419 420 return AmbientContextManagerPerUserService.ServiceType.DEFAULT; 421 } 422 isDefaultService(String serviceName)423 private boolean isDefaultService(String serviceName) { 424 final String defaultService = mContext.getResources() 425 .getString(R.string.config_defaultAmbientContextDetectionService); 426 if (defaultService != null && defaultService.equals(serviceName)) { 427 return true; 428 } 429 return false; 430 } 431 isDefaultWearableService(String serviceName)432 private boolean isDefaultWearableService(String serviceName) { 433 final String wearableService = mContext.getResources() 434 .getString(R.string.config_defaultWearableSensingService); 435 if (wearableService != null && wearableService.equals(serviceName)) { 436 return true; 437 } 438 return false; 439 } 440 getServiceForType(int userId, AmbientContextManagerPerUserService.ServiceType serviceType)441 private AmbientContextManagerPerUserService getServiceForType(int userId, 442 AmbientContextManagerPerUserService.ServiceType serviceType) { 443 Slog.d(TAG, "getServiceForType with userid: " 444 + userId + " service type: " + serviceType.name()); 445 synchronized (mLock) { 446 final List<AmbientContextManagerPerUserService> services = 447 getServiceListForUserLocked(userId); 448 Slog.d(TAG, "Services that are available: " 449 + (services == null ? "null services" : services.size() 450 + " number of services")); 451 if (services == null) { 452 return null; 453 } 454 455 for (AmbientContextManagerPerUserService service : services) { 456 if (service.getServiceType() == serviceType) { 457 return service; 458 } 459 } 460 } 461 return null; 462 } 463 isWearableEventTypesOnly(Set<Integer> eventTypes)464 private boolean isWearableEventTypesOnly(Set<Integer> eventTypes) { 465 if (eventTypes.isEmpty()) { 466 Slog.d(TAG, "empty event types."); 467 return false; 468 } 469 for (Integer eventType : eventTypes) { 470 if (eventType < AmbientContextEvent.EVENT_VENDOR_WEARABLE_START) { 471 Slog.d(TAG, "Not all events types are wearable events."); 472 return false; 473 } 474 } 475 Slog.d(TAG, "only wearable events."); 476 return true; 477 } 478 isWearableEventTypesOnly(int[] eventTypes)479 private boolean isWearableEventTypesOnly(int[] eventTypes) { 480 Integer[] events = intArrayToIntegerArray(eventTypes); 481 return isWearableEventTypesOnly(new HashSet<>(Arrays.asList(events))); 482 } 483 containsMixedEvents(int[] eventTypes)484 private boolean containsMixedEvents(int[] eventTypes) { 485 if (isWearableEventTypesOnly(eventTypes)) { 486 return false; 487 } 488 // It's not only wearable events so check if it's only default events. 489 for (Integer event : eventTypes) { 490 if (!DEFAULT_EVENT_SET.contains(event)) { 491 // mixed events. 492 Slog.w(TAG, "Received mixed event types, this is not supported."); 493 return true; 494 } 495 } 496 // Only default events. 497 return false; 498 } 499 integerSetToIntArray(@onNull Set<Integer> integerSet)500 private static int[] integerSetToIntArray(@NonNull Set<Integer> integerSet) { 501 int[] intArray = new int[integerSet.size()]; 502 int i = 0; 503 for (Integer type : integerSet) { 504 intArray[i++] = type; 505 } 506 return intArray; 507 } 508 intArrayToIntegerSet(int[] eventTypes)509 private Set<Integer> intArrayToIntegerSet(int[] eventTypes) { 510 Set<Integer> types = new HashSet<>(); 511 for (Integer i : eventTypes) { 512 types.add(i); 513 } 514 return types; 515 } 516 517 @NonNull intArrayToIntegerArray(@onNull int[] integerSet)518 private static Integer[] intArrayToIntegerArray(@NonNull int[] integerSet) { 519 Integer[] intArray = new Integer[integerSet.length]; 520 int i = 0; 521 for (Integer type : integerSet) { 522 intArray[i++] = type; 523 } 524 return intArray; 525 } 526 527 private final class AmbientContextManagerInternal extends IAmbientContextManager.Stub { 528 @Override registerObserver( AmbientContextEventRequest request, PendingIntent resultPendingIntent, RemoteCallback statusCallback)529 public void registerObserver( 530 AmbientContextEventRequest request, PendingIntent resultPendingIntent, 531 RemoteCallback statusCallback) { 532 Objects.requireNonNull(request); 533 Objects.requireNonNull(resultPendingIntent); 534 Objects.requireNonNull(statusCallback); 535 AmbientContextManagerPerUserService service = 536 getAmbientContextManagerPerUserServiceForEventTypes( 537 UserHandle.getCallingUserId(), 538 request.getEventTypes()); 539 // Wrap the PendingIntent and statusCallback in a IAmbientContextObserver to make the 540 // code unified 541 IAmbientContextObserver observer = new IAmbientContextObserver.Stub() { 542 @Override 543 public void onEvents(List<AmbientContextEvent> events) throws RemoteException { 544 service.sendDetectionResultIntent(resultPendingIntent, events); 545 } 546 547 @Override 548 public void onRegistrationComplete(int statusCode) throws RemoteException { 549 service.sendStatusCallback(statusCallback, 550 statusCode); 551 } 552 }; 553 registerObserverWithCallback(request, resultPendingIntent.getCreatorPackage(), 554 observer); 555 } 556 557 /** 558 * Register an observer for Ambient Context events. 559 */ 560 @Override registerObserverWithCallback(AmbientContextEventRequest request, String packageName, IAmbientContextObserver observer)561 public void registerObserverWithCallback(AmbientContextEventRequest request, 562 String packageName, 563 IAmbientContextObserver observer) { 564 Slog.i(TAG, "AmbientContextManagerService registerObserverWithCallback."); 565 Objects.requireNonNull(request); 566 Objects.requireNonNull(packageName); 567 Objects.requireNonNull(observer); 568 mContext.enforceCallingOrSelfPermission( 569 Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG); 570 assertCalledByPackageOwner(packageName); 571 572 AmbientContextManagerPerUserService service = 573 getAmbientContextManagerPerUserServiceForEventTypes( 574 UserHandle.getCallingUserId(), 575 request.getEventTypes()); 576 if (service == null) { 577 Slog.w(TAG, "onRegisterObserver unavailable user_id: " 578 + UserHandle.getCallingUserId()); 579 return; 580 } 581 582 int statusCode = checkStatusCode( 583 service, integerSetToIntArray(request.getEventTypes())); 584 if (statusCode == AmbientContextManager.STATUS_SUCCESS) { 585 service.onRegisterObserver(request, packageName, observer); 586 } else { 587 service.completeRegistration(observer, statusCode); 588 } 589 } 590 591 @Override unregisterObserver(String callingPackage)592 public void unregisterObserver(String callingPackage) { 593 mContext.enforceCallingOrSelfPermission( 594 Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG); 595 assertCalledByPackageOwner(callingPackage); 596 597 synchronized (mLock) { 598 for (ClientRequest cr : mExistingClientRequests) { 599 if ((cr != null) && cr.getPackageName().equals(callingPackage)) { 600 AmbientContextManagerPerUserService service = 601 getAmbientContextManagerPerUserServiceForEventTypes( 602 UserHandle.getCallingUserId(), 603 cr.getRequest().getEventTypes()); 604 if (service != null) { 605 service.onUnregisterObserver(callingPackage); 606 } else { 607 Slog.w(TAG, "onUnregisterObserver unavailable user_id: " 608 + UserHandle.getCallingUserId()); 609 } 610 } 611 } 612 } 613 } 614 615 @Override queryServiceStatus(int[] eventTypes, String callingPackage, RemoteCallback statusCallback)616 public void queryServiceStatus(int[] eventTypes, String callingPackage, 617 RemoteCallback statusCallback) { 618 Objects.requireNonNull(eventTypes); 619 Objects.requireNonNull(callingPackage); 620 Objects.requireNonNull(statusCallback); 621 mContext.enforceCallingOrSelfPermission( 622 Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG); 623 assertCalledByPackageOwner(callingPackage); 624 synchronized (mLock) { 625 AmbientContextManagerPerUserService service = 626 getAmbientContextManagerPerUserServiceForEventTypes( 627 UserHandle.getCallingUserId(), intArrayToIntegerSet(eventTypes)); 628 if (service == null) { 629 Slog.w(TAG, "queryServiceStatus unavailable user_id: " 630 + UserHandle.getCallingUserId()); 631 return; 632 } 633 634 int statusCode = checkStatusCode(service, eventTypes); 635 if (statusCode == AmbientContextManager.STATUS_SUCCESS) { 636 service.onQueryServiceStatus(eventTypes, callingPackage, 637 statusCallback); 638 } else { 639 service.sendStatusCallback(statusCallback, statusCode); 640 } 641 } 642 } 643 644 @Override startConsentActivity(int[] eventTypes, String callingPackage)645 public void startConsentActivity(int[] eventTypes, String callingPackage) { 646 Objects.requireNonNull(eventTypes); 647 Objects.requireNonNull(callingPackage); 648 assertCalledByPackageOwner(callingPackage); 649 mContext.enforceCallingOrSelfPermission( 650 Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG); 651 652 if (containsMixedEvents(eventTypes)) { 653 Slog.d(TAG, "AmbientContextEventRequest contains mixed events," 654 + " this is not supported."); 655 return; 656 } 657 658 AmbientContextManagerPerUserService service = 659 getAmbientContextManagerPerUserServiceForEventTypes( 660 UserHandle.getCallingUserId(), intArrayToIntegerSet(eventTypes)); 661 662 if (service != null) { 663 service.onStartConsentActivity(eventTypes, callingPackage); 664 } else { 665 Slog.w(TAG, "startConsentActivity unavailable user_id: " 666 + UserHandle.getCallingUserId()); 667 } 668 } 669 670 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)671 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 672 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) { 673 return; 674 } 675 synchronized (mLock) { 676 dumpLocked("", pw); 677 } 678 } 679 680 @Override onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver)681 public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, 682 String[] args, ShellCallback callback, ResultReceiver resultReceiver) { 683 new AmbientContextShellCommand(AmbientContextManagerService.this).exec( 684 this, in, out, err, args, callback, resultReceiver); 685 } 686 checkStatusCode(AmbientContextManagerPerUserService service, int[] eventTypes)687 private int checkStatusCode(AmbientContextManagerPerUserService service, int[] eventTypes) { 688 if (service.getServiceType() == ServiceType.DEFAULT && !mIsServiceEnabled) { 689 Slog.d(TAG, "Service not enabled."); 690 return AmbientContextManager.STATUS_SERVICE_UNAVAILABLE; 691 } 692 if (service.getServiceType() == ServiceType.WEARABLE && !mIsWearableServiceEnabled) { 693 Slog.d(TAG, "Wearable Service not available."); 694 return AmbientContextManager.STATUS_SERVICE_UNAVAILABLE; 695 } 696 if (containsMixedEvents(eventTypes)) { 697 Slog.d(TAG, "AmbientContextEventRequest contains mixed events," 698 + " this is not supported."); 699 return AmbientContextManager.STATUS_NOT_SUPPORTED; 700 } 701 return AmbientContextManager.STATUS_SUCCESS; 702 } 703 } 704 } 705