Split IntelligenceManager / IntelligenceService.

This name is too generic, so we split it in 2 parts:

- ContentCaptureManager: the public API used by views and apps to report their
  structure.
- SmartSuggestionsServiec: the system service use to consume these events and
  provide autofill suggestions.

This CL also:

- Optimizes ContentCaptureManager allocation so they are not created on contexts that are not
  capturing events (such as views from the system server).
- Uses a generic ContentCaptureEventsRequest (rather than a list of events) to make it easier
  to be extended.
- Fixed IntelligencePerUserService so it clears the sessions when the
  implementation changes.

Test: manual verification

Bug: 119776618
Bug: 117944706
Bug: 119638877

Change-Id: I069bcd23dda94afe18b2781fd3981b8b555afa56
This commit is contained in:
Felipe Leme
2018-11-27 15:48:47 -08:00
parent 719883458c
commit ecb08be22e
29 changed files with 388 additions and 249 deletions

View File

@@ -19,9 +19,9 @@ import android.annotation.NonNull;
import android.content.ComponentName;
import android.content.Context;
import android.os.IBinder;
import android.service.intelligence.IntelligenceService;
import android.service.intelligence.InteractionContext;
import android.service.intelligence.InteractionSessionId;
import android.service.intelligence.SmartSuggestionsService;
import android.service.intelligence.SnapshotData;
import android.util.Slog;
import android.view.autofill.AutofillId;
@@ -59,7 +59,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
mService = service;
mId = Preconditions.checkNotNull(sessionId);
mRemoteService = new RemoteIntelligenceService(context,
IntelligenceService.SERVICE_INTERFACE, serviceComponentName, userId, this,
SmartSuggestionsService.SERVICE_INTERFACE, serviceComponentName, userId, this,
bindInstantServiceAllowed, verbose);
mInterationContext = new InteractionContext(appComponentName, taskId, displayId, flags);
}
@@ -72,7 +72,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
}
/**
* Notifies the {@link IntelligenceService} that the service started.
* Notifies the {@link SmartSuggestionsService} that the service started.
*/
@GuardedBy("mLock")
public void notifySessionStartedLocked() {
@@ -80,14 +80,14 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
}
/**
* Notifies the {@link IntelligenceService} of a batch of events.
* Notifies the {@link SmartSuggestionsService} of a batch of events.
*/
public void sendEventsLocked(@NonNull List<ContentCaptureEvent> events) {
mRemoteService.onContentCaptureEventsRequest(mId, events);
}
/**
* Notifies the {@link IntelligenceService} of a snapshot of an activity.
* Notifies the {@link SmartSuggestionsService} of a snapshot of an activity.
*/
@GuardedBy("mLock")
public void sendActivitySnapshotLocked(@NonNull SnapshotData snapshotData) {
@@ -110,7 +110,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
* Cleans up the session and removes it from the service.
*
* @param notifyRemoteService whether it should trigger a {@link
* IntelligenceService#onDestroyInteractionSession(InteractionSessionId)}
* SmartSuggestionsService#onDestroyInteractionSession(InteractionSessionId)}
* request.
*/
@GuardedBy("mLock")
@@ -126,7 +126,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
* Cleans up the session, but not removes it from the service.
*
* @param notifyRemoteService whether it should trigger a {@link
* IntelligenceService#onDestroyInteractionSession(InteractionSessionId)}
* SmartSuggestionsService#onDestroyInteractionSession(InteractionSessionId)}
* request.
*/
@GuardedBy("mLock")

View File

@@ -16,7 +16,7 @@
package com.android.server.intelligence;
import static android.content.Context.INTELLIGENCE_MANAGER_SERVICE;
import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -50,6 +50,7 @@ import java.util.List;
* <p>The data collected by this service can be analyzed and combined with other sources to provide
* contextual data in other areas of the system such as Autofill.
*/
//TODO(b/111276913): rename once the final name is defined
public final class IntelligenceManagerService extends
AbstractMasterSystemService<IntelligenceManagerService, IntelligencePerUserService> {
@@ -67,7 +68,7 @@ public final class IntelligenceManagerService extends
@Override // from AbstractMasterSystemService
protected String getServiceSettingsProperty() {
// TODO(b/111276913): STOPSHIP temporary settings, until it's set by resourcs + cmd
return "intel_service";
return "smart_suggestions_service";
}
@Override // from AbstractMasterSystemService
@@ -78,7 +79,7 @@ public final class IntelligenceManagerService extends
@Override // from SystemService
public void onStart() {
publishBinderService(INTELLIGENCE_MANAGER_SERVICE,
publishBinderService(CONTENT_CAPTURE_MANAGER_SERVICE,
new IntelligenceManagerServiceStub());
publishLocalService(IntelligenceManagerInternal.class, mLocalService);
}

View File

@@ -41,7 +41,7 @@ import android.util.Slog;
import android.view.autofill.AutofillId;
import android.view.autofill.IAutoFillManagerClient;
import android.view.intelligence.ContentCaptureEvent;
import android.view.intelligence.IntelligenceManager;
import android.view.intelligence.ContentCaptureManager;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.IResultReceiver;
@@ -54,6 +54,7 @@ import java.util.List;
/**
* Per-user instance of {@link IntelligenceManagerService}.
*/
//TODO(b/111276913): rename once the final name is defined
final class IntelligencePerUserService
extends AbstractPerUserSystemService<IntelligencePerUserService,
IntelligenceManagerService> {
@@ -86,16 +87,23 @@ final class IntelligencePerUserService
Slog.w(TAG, "Could not get service for " + serviceComponent + ": " + e);
return null;
}
if (!Manifest.permission.BIND_INTELLIGENCE_SERVICE.equals(si.permission)) {
Slog.w(TAG, "IntelligenceService from '" + si.packageName
if (!Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE.equals(si.permission)) {
Slog.w(TAG, "SmartSuggestionsService from '" + si.packageName
+ "' does not require permission "
+ Manifest.permission.BIND_INTELLIGENCE_SERVICE);
+ Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE);
throw new SecurityException("Service does not require permission "
+ Manifest.permission.BIND_INTELLIGENCE_SERVICE);
+ Manifest.permission.BIND_SMART_SUGGESTIONS_SERVICE);
}
return si;
}
@Override // from PerUserSystemService
@GuardedBy("mLock")
protected boolean updateLocked(boolean disabled) {
destroyLocked();
return super.updateLocked(disabled);
}
// TODO(b/111276913): log metrics
@GuardedBy("mLock")
public void startSessionLocked(@NonNull IBinder activityToken,
@@ -103,7 +111,7 @@ final class IntelligencePerUserService
@NonNull InteractionSessionId sessionId, int flags,
@NonNull IResultReceiver resultReceiver) {
if (!isEnabledLocked()) {
sendToClient(resultReceiver, IntelligenceManager.STATE_DISABLED);
sendToClient(resultReceiver, ContentCaptureManager.STATE_DISABLED);
return;
}
final ComponentName serviceComponentName = getServiceComponentName();
@@ -126,7 +134,7 @@ final class IntelligencePerUserService
// TODO(b/111276913): check if local ids match and decide what to do if they don't
// TODO(b/111276913): should we call session.notifySessionStartedLocked() again??
// if not, move notifySessionStartedLocked() into session constructor
sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
sendToClient(resultReceiver, ContentCaptureManager.STATE_ACTIVE);
return;
}
@@ -142,7 +150,7 @@ final class IntelligencePerUserService
}
mSessions.put(sessionId, session);
session.notifySessionStartedLocked();
sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
sendToClient(resultReceiver, ContentCaptureManager.STATE_ACTIVE);
}
// TODO(b/111276913): log metrics

View File

@@ -23,6 +23,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.IInterface;
import android.os.RemoteException;
import android.service.intelligence.ContentCaptureEventsRequest;
import android.service.intelligence.IIntelligenceService;
import android.service.intelligence.InteractionContext;
import android.service.intelligence.InteractionSessionId;
@@ -39,6 +40,7 @@ import com.android.server.AbstractRemoteService;
import java.util.List;
//TODO(b/111276913): rename once the final name is defined
final class RemoteIntelligenceService extends AbstractRemoteService {
private static final String TAG = "RemoteIntelligenceService";
@@ -194,7 +196,8 @@ final class RemoteIntelligenceService extends AbstractRemoteService {
@Override // from MyPendingRequest
public void myRun(@NonNull RemoteIntelligenceService remoteService) throws RemoteException {
remoteService.mService.onContentCaptureEvents(mSessionId, mEvents);
remoteService.mService.onContentCaptureEventsRequest(mSessionId,
new ContentCaptureEventsRequest(mEvents));
}
}