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