diff options
29 files changed, 388 insertions, 249 deletions
diff --git a/Android.bp b/Android.bp index 41d5f28a2680..cbc67d0e3e20 100644 --- a/Android.bp +++ b/Android.bp @@ -290,7 +290,6 @@ java_defaults { "core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl", "core/java/android/service/gatekeeper/IGateKeeperService.aidl", "core/java/android/service/intelligence/IIntelligenceService.aidl", - "core/java/android/service/notification/INotificationListener.aidl", "core/java/android/service/notification/IStatusBarNotificationHolder.aidl", "core/java/android/service/notification/IConditionListener.aidl", diff --git a/api/current.txt b/api/current.txt index 03e01604a483..3b9733f68aad 100644 --- a/api/current.txt +++ b/api/current.txt @@ -51966,8 +51966,8 @@ package android.view.inputmethod { package android.view.intelligence { - public final class IntelligenceManager { - method public android.content.ComponentName getIntelligenceServiceComponentName(); + public final class ContentCaptureManager { + method public android.content.ComponentName getServiceComponentName(); method public boolean isContentCaptureEnabled(); method public android.view.ViewStructure newVirtualViewStructure(android.view.autofill.AutofillId, int); method public void notifyViewAppeared(android.view.ViewStructure); diff --git a/api/system-current.txt b/api/system-current.txt index 62d446f7254e..7a2c233d8e3b 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -25,7 +25,6 @@ package android { field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH"; field public static final java.lang.String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE"; field public static final java.lang.String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE"; - field public static final java.lang.String BIND_INTELLIGENCE_SERVICE = "android.permission.BIND_INTELLIGENCE_SERVICE"; field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET"; field public static final java.lang.String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE"; field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"; @@ -34,6 +33,7 @@ package android { field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE"; field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE"; field public static final java.lang.String BIND_SETTINGS_SUGGESTIONS_SERVICE = "android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE"; + field public static final java.lang.String BIND_SMART_SUGGESTIONS_SERVICE = "android.permission.BIND_SMART_SUGGESTIONS_SERVICE"; field public static final java.lang.String BIND_SOUND_TRIGGER_DETECTION_SERVICE = "android.permission.BIND_SOUND_TRIGGER_DETECTION_SERVICE"; field public static final java.lang.String BIND_TELEPHONY_DATA_SERVICE = "android.permission.BIND_TELEPHONY_DATA_SERVICE"; field public static final java.lang.String BIND_TELEPHONY_NETWORK_SERVICE = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE"; @@ -4980,6 +4980,13 @@ package android.service.euicc { package android.service.intelligence { + public final class ContentCaptureEventsRequest implements android.os.Parcelable { + method public int describeContents(); + method public java.util.List<android.view.intelligence.ContentCaptureEvent> getEvents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.service.intelligence.ContentCaptureEventsRequest> CREATOR; + } + public final class FillCallback { method public void onSuccess(android.service.intelligence.FillResponse); } @@ -5014,16 +5021,6 @@ package android.service.intelligence { field public static final long FLAG_METADATA_ADDRESS = 1L; // 0x1L } - public abstract class IntelligenceService extends android.app.Service { - ctor public IntelligenceService(); - method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData); - method public abstract void onContentCaptureEvent(android.service.intelligence.InteractionSessionId, java.util.List<android.view.intelligence.ContentCaptureEvent>); - method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId); - method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId); - method public void onFillRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.FillRequest, android.os.CancellationSignal, android.service.intelligence.FillController, android.service.intelligence.FillCallback); - field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.IntelligenceService"; - } - public final class InteractionContext implements android.os.Parcelable { method public int describeContents(); method public android.content.ComponentName getActivityComponent(); @@ -5059,6 +5056,21 @@ package android.service.intelligence { method public android.service.intelligence.PresentationParams.Area getSubArea(android.graphics.Rect); } + public abstract class SmartSuggestionsService extends android.app.Service { + ctor public SmartSuggestionsService(); + method public final java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities(); + method public final java.util.Set<java.lang.String> getContentCaptureDisabledPackages(); + method public void onActivitySnapshot(android.service.intelligence.InteractionSessionId, android.service.intelligence.SnapshotData); + method public abstract void onContentCaptureEventsRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.ContentCaptureEventsRequest); + method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId); + method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId); + method public void onFillRequest(android.service.intelligence.InteractionSessionId, android.service.intelligence.FillRequest, android.os.CancellationSignal, android.service.intelligence.FillController, android.service.intelligence.FillCallback); + method public final void setActivityContentCaptureEnabled(android.content.ComponentName, boolean); + method public final void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>); + method public final void setPackageContentCaptureEnabled(java.lang.String, boolean); + field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.SmartSuggestionsService"; + } + public final class SnapshotData implements android.os.Parcelable { method public int describeContents(); method public android.app.assist.AssistContent getAssistContent(); @@ -7243,14 +7255,6 @@ package android.view.intelligence { field public static final int TYPE_VIEW_TEXT_CHANGED = 7; // 0x7 } - public final class IntelligenceManager { - method public java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities(); - method public java.util.Set<java.lang.String> getContentCaptureDisabledPackages(); - method public void setActivityContentCaptureEnabled(android.content.ComponentName, boolean); - method public void setContentCaptureWhitelist(java.util.List<java.lang.String>, java.util.List<android.content.ComponentName>); - method public void setPackageContentCaptureEnabled(java.lang.String, boolean); - } - public final class ViewNode extends android.app.assist.AssistStructure.ViewNode { method public android.view.autofill.AutofillId getParentAutofillId(); } diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 05bb9a1c2139..f3f065a27e6f 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -122,7 +122,7 @@ import android.view.autofill.AutofillManager.AutofillClient; import android.view.autofill.AutofillPopupWindow; import android.view.autofill.IAutofillWindowPresenter; import android.view.intelligence.ContentCaptureEvent; -import android.view.intelligence.IntelligenceManager; +import android.view.intelligence.ContentCaptureManager; import android.widget.AdapterView; import android.widget.Toast; import android.widget.Toolbar; @@ -824,8 +824,8 @@ public class Activity extends ContextThemeWrapper /** The autofill manager. Always access via {@link #getAutofillManager()}. */ @Nullable private AutofillManager mAutofillManager; - /** The screen observation manager. Always access via {@link #getIntelligenceManager()}. */ - @Nullable private IntelligenceManager mIntelligenceManager; + /** The content capture manager. Always access via {@link #getContentCaptureManager()}. */ + @Nullable private ContentCaptureManager mContentCaptureManager; private final ArrayList<Application.ActivityLifecycleCallbacks> mActivityLifecycleCallbacks = new ArrayList<Application.ActivityLifecycleCallbacks>(); @@ -1016,39 +1016,39 @@ public class Activity extends ContextThemeWrapper } /** - * (Creates, sets, and ) returns the intelligence manager + * (Creates, sets, and ) returns the content capture manager * - * @return The intelligence manager + * @return The content capture manager */ - @NonNull private IntelligenceManager getIntelligenceManager() { - if (mIntelligenceManager == null) { - mIntelligenceManager = getSystemService(IntelligenceManager.class); + @NonNull private ContentCaptureManager getContentCaptureManager() { + if (mContentCaptureManager == null) { + mContentCaptureManager = getSystemService(ContentCaptureManager.class); } - return mIntelligenceManager; + return mContentCaptureManager; } - private void notifyIntelligenceManagerIfNeeded(@ContentCaptureEvent.EventType int event) { - final IntelligenceManager im = getIntelligenceManager(); - if (im == null || !im.isContentCaptureEnabled()) { + private void notifyContentCaptureManagerIfNeeded(@ContentCaptureEvent.EventType int event) { + final ContentCaptureManager cm = getContentCaptureManager(); + if (cm == null || !cm.isContentCaptureEnabled()) { return; } switch (event) { case ContentCaptureEvent.TYPE_ACTIVITY_CREATED: //TODO(b/111276913): decide whether the InteractionSessionId should be // saved / restored in the activity bundle. - im.onActivityCreated(mToken, getComponentName()); + cm.onActivityCreated(mToken, getComponentName()); break; case ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED: - im.onActivityDestroyed(); + cm.onActivityDestroyed(); break; case ContentCaptureEvent.TYPE_ACTIVITY_STARTED: case ContentCaptureEvent.TYPE_ACTIVITY_RESUMED: case ContentCaptureEvent.TYPE_ACTIVITY_PAUSED: case ContentCaptureEvent.TYPE_ACTIVITY_STOPPED: - im.onActivityLifecycleEvent(event); + cm.onActivityLifecycleEvent(event); break; default: - Log.w(TAG, "notifyIntelligenceManagerIfNeeded(): invalid type " + event); + Log.w(TAG, "notifyContentCaptureManagerIfNeeded(): invalid type " + event); } } @@ -1057,6 +1057,7 @@ public class Activity extends ContextThemeWrapper super.attachBaseContext(newBase); if (newBase != null) { newBase.setAutofillClient(this); + newBase.setContentCaptureSupported(true); } } @@ -1066,6 +1067,12 @@ public class Activity extends ContextThemeWrapper return this; } + /** @hide */ + @Override + public boolean isContentCaptureSupported() { + return true; + } + /** * Register an {@link Application.ActivityLifecycleCallbacks} instance that receives * lifecycle callbacks for only this Activity. @@ -1410,7 +1417,7 @@ public class Activity extends ContextThemeWrapper mRestoredFromBundle = savedInstanceState != null; mCalled = true; - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED); } /** @@ -1644,7 +1651,7 @@ public class Activity extends ContextThemeWrapper if (mAutoFillResetNeeded) { getAutofillManager().onVisibleForAutofill(); } - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED); } /** @@ -1735,7 +1742,7 @@ public class Activity extends ContextThemeWrapper } } } - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED); mCalled = true; } @@ -2129,7 +2136,7 @@ public class Activity extends ContextThemeWrapper mAutoFillIgnoreFirstResumePause = false; } } - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED); mCalled = true; } @@ -2318,7 +2325,7 @@ public class Activity extends ContextThemeWrapper getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_CANCEL, mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)); } - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED); } } @@ -2390,7 +2397,7 @@ public class Activity extends ContextThemeWrapper dispatchActivityDestroyed(); - notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED); + notifyContentCaptureManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED); } @@ -6806,7 +6813,7 @@ public class Activity extends ContextThemeWrapper } void dumpIntelligenceManager(String prefix, PrintWriter writer) { - final IntelligenceManager im = getIntelligenceManager(); + final ContentCaptureManager im = getContentCaptureManager(); if (im != null) { im.dump(prefix, writer); } else { diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 28ecb27b53d2..6f0b6c8687db 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -217,6 +217,8 @@ class ContextImpl extends Context { private AutofillClient mAutofillClient = null; private boolean mIsAutofillCompatEnabled; + private boolean mIsContentCaptureSupported = false; + private final Object mSync = new Object(); @GuardedBy("mSync") @@ -2376,6 +2378,18 @@ class ContextImpl extends Context { mIsAutofillCompatEnabled = autofillCompatEnabled; } + /** @hide */ + @Override + public boolean isContentCaptureSupported() { + return mIsContentCaptureSupported; + } + + /** @hide */ + @Override + public void setContentCaptureSupported(boolean supported) { + mIsContentCaptureSupported = supported; + } + @UnsupportedAppUsage static ContextImpl createSystemContext(ActivityThread mainThread) { LoadedApk packageInfo = new LoadedApk(mainThread); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 0123551230b0..dfe371c3248e 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -165,8 +165,8 @@ import android.view.accessibility.CaptioningManager; import android.view.autofill.AutofillManager; import android.view.autofill.IAutoFillManager; import android.view.inputmethod.InputMethodManager; +import android.view.intelligence.ContentCaptureManager; import android.view.intelligence.IIntelligenceManager; -import android.view.intelligence.IntelligenceManager; import android.view.textclassifier.TextClassificationManager; import android.view.textservice.TextServicesManager; @@ -199,6 +199,7 @@ final class SystemServiceRegistry { private SystemServiceRegistry() { } static { + //CHECKSTYLE:OFF IndentationCheck registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class, new CachedServiceFetcher<AccessibilityManager>() { @Override @@ -1050,15 +1051,20 @@ final class SystemServiceRegistry { return new AutofillManager(ctx.getOuterContext(), service); }}); - registerService(Context.INTELLIGENCE_MANAGER_SERVICE, IntelligenceManager.class, - new CachedServiceFetcher<IntelligenceManager>() { + registerService(Context.CONTENT_CAPTURE_MANAGER_SERVICE, ContentCaptureManager.class, + new CachedServiceFetcher<ContentCaptureManager>() { @Override - public IntelligenceManager createService(ContextImpl ctx) + public ContentCaptureManager createService(ContextImpl ctx) throws ServiceNotFoundException { // Get the services without throwing as this is an optional feature - IBinder b = ServiceManager.getService(Context.INTELLIGENCE_MANAGER_SERVICE); - IIntelligenceManager service = IIntelligenceManager.Stub.asInterface(b); - return new IntelligenceManager(ctx.getOuterContext(), service); + Context outerContext = ctx.getOuterContext(); + if (outerContext.isContentCaptureSupported()) { + IBinder b = ServiceManager + .getService(Context.CONTENT_CAPTURE_MANAGER_SERVICE); + IIntelligenceManager service = IIntelligenceManager.Stub.asInterface(b); + return new ContentCaptureManager(outerContext, service); + } + return null; }}); registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() { @@ -1138,6 +1144,7 @@ final class SystemServiceRegistry { throws ServiceNotFoundException { return new RoleManager(ctx.getOuterContext()); }}); + //CHECKSTYLE:ON IndentationCheck } /** diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index ff57b0311d60..68aac642ecb0 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -3933,12 +3933,13 @@ public abstract class Context { public static final String AUTOFILL_MANAGER_SERVICE = "autofill"; /** - * Official published name of the intelligence service. + * Official published name of the smart suggestions service. * * @hide * @see #getSystemService(String) */ - public static final String INTELLIGENCE_MANAGER_SERVICE = "intelligence"; + // TODO(b/111276913): rename string (will require SELinux change first) + public static final String CONTENT_CAPTURE_MANAGER_SERVICE = "intelligence"; /** * Use with {@link #getSystemService(String)} to access the @@ -5223,6 +5224,25 @@ public abstract class Context { } /** + * Checks whether this context supports content capture. + * + * @hide + */ + // NOTE: for now we just need to check if it's supported so we can optimize calls that can be + // skipped when it isn't. Eventually, we might need a full + // ContentCaptureManager.ContentCaptureClient interface (as it's done with AutofillClient). + // + public boolean isContentCaptureSupported() { + return false; + } + + /** + * @hide + */ + public void setContentCaptureSupported(@SuppressWarnings("unused") boolean supported) { + } + + /** * Throws an exception if the Context is using system resources, * which are non-runtime-overlay-themable and may show inconsistent UI. * @hide diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java index 2db44b44fd6c..26ed3b736f80 100644 --- a/core/java/android/content/ContextWrapper.java +++ b/core/java/android/content/ContextWrapper.java @@ -1049,4 +1049,20 @@ public class ContextWrapper extends Context { mBase.setAutofillCompatibilityEnabled(autofillCompatEnabled); } } + + /** + * @hide + */ + @Override + public boolean isContentCaptureSupported() { + return mBase.isContentCaptureSupported(); + } + + /** + * @hide + */ + @Override + public void setContentCaptureSupported(boolean supported) { + mBase.setContentCaptureSupported(supported); + } } diff --git a/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl b/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl new file mode 100644 index 000000000000..23d607d9838c --- /dev/null +++ b/core/java/android/service/intelligence/ContentCaptureEventsRequest.aidl @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018, 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 android.service.intelligence; + +parcelable ContentCaptureEventsRequest; diff --git a/core/java/android/service/intelligence/ContentCaptureEventsRequest.java b/core/java/android/service/intelligence/ContentCaptureEventsRequest.java new file mode 100644 index 000000000000..bc5b92bce999 --- /dev/null +++ b/core/java/android/service/intelligence/ContentCaptureEventsRequest.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2018 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 android.service.intelligence; + +import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.intelligence.ContentCaptureEvent; + +import java.util.List; + +/** + * Batch of content capture events. + * + * @hide + */ +@SystemApi +public final class ContentCaptureEventsRequest implements Parcelable { + + private final List<ContentCaptureEvent> mEvents; + + /** @hide */ + public ContentCaptureEventsRequest(@NonNull List<ContentCaptureEvent> events) { + mEvents = events; + } + + /** + * Gets the events. + */ + @NonNull + public List<ContentCaptureEvent> getEvents() { + return mEvents; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int flags) { + parcel.writeTypedList(mEvents, flags); + } + + public static final Parcelable.Creator<ContentCaptureEventsRequest> CREATOR = + new Parcelable.Creator<ContentCaptureEventsRequest>() { + + @Override + public ContentCaptureEventsRequest createFromParcel(Parcel parcel) { + return new ContentCaptureEventsRequest(parcel + .createTypedArrayList(ContentCaptureEvent.CREATOR)); + } + + @Override + public ContentCaptureEventsRequest[] newArray(int size) { + return new ContentCaptureEventsRequest[size]; + } + }; +} diff --git a/core/java/android/service/intelligence/FillController.java b/core/java/android/service/intelligence/FillController.java index c5e1242842bb..4a9c85de1fa2 100644 --- a/core/java/android/service/intelligence/FillController.java +++ b/core/java/android/service/intelligence/FillController.java @@ -15,12 +15,12 @@ */ package android.service.intelligence; -import static android.service.intelligence.IntelligenceService.DEBUG; +import static android.service.intelligence.SmartSuggestionsService.DEBUG; import android.annotation.NonNull; import android.annotation.SystemApi; import android.os.RemoteException; -import android.service.intelligence.IntelligenceService.AutofillProxy; +import android.service.intelligence.SmartSuggestionsService.AutofillProxy; import android.util.Log; import android.util.Pair; import android.view.autofill.AutofillId; diff --git a/core/java/android/service/intelligence/FillRequest.java b/core/java/android/service/intelligence/FillRequest.java index 95e922487906..f68db9df6fe3 100644 --- a/core/java/android/service/intelligence/FillRequest.java +++ b/core/java/android/service/intelligence/FillRequest.java @@ -18,7 +18,7 @@ package android.service.intelligence; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; -import android.service.intelligence.IntelligenceService.AutofillProxy; +import android.service.intelligence.SmartSuggestionsService.AutofillProxy; import android.view.autofill.AutofillId; /** diff --git a/core/java/android/service/intelligence/FillWindow.java b/core/java/android/service/intelligence/FillWindow.java index 4ea07bfc86cf..309f6a1b6f1b 100644 --- a/core/java/android/service/intelligence/FillWindow.java +++ b/core/java/android/service/intelligence/FillWindow.java @@ -15,7 +15,7 @@ */ package android.service.intelligence; -import static android.service.intelligence.IntelligenceService.DEBUG; +import static android.service.intelligence.SmartSuggestionsService.DEBUG; import android.annotation.LongDef; import android.annotation.NonNull; diff --git a/core/java/android/service/intelligence/IIntelligenceService.aidl b/core/java/android/service/intelligence/IIntelligenceService.aidl index e2260d7d3d76..d6b31079e34c 100644 --- a/core/java/android/service/intelligence/IIntelligenceService.aidl +++ b/core/java/android/service/intelligence/IIntelligenceService.aidl @@ -17,6 +17,7 @@ package android.service.intelligence; import android.os.IBinder; +import android.service.intelligence.ContentCaptureEventsRequest; import android.service.intelligence.InteractionSessionId; import android.service.intelligence.InteractionContext; import android.service.intelligence.SnapshotData; @@ -26,19 +27,19 @@ import android.view.intelligence.ContentCaptureEvent; import java.util.List; - /** * Interface from the system to an intelligence service. * * @hide */ + // TODO(b/111276913): rename / update javadoc (once the final name is defined) oneway interface IIntelligenceService { // Called when session is created (context not null) or destroyed (context null) void onSessionLifecycle(in InteractionContext context, in InteractionSessionId sessionId); - void onContentCaptureEvents(in InteractionSessionId sessionId, - in List<ContentCaptureEvent> events); + void onContentCaptureEventsRequest(in InteractionSessionId sessionId, + in ContentCaptureEventsRequest request); void onActivitySnapshot(in InteractionSessionId sessionId, in SnapshotData snapshotData); diff --git a/core/java/android/service/intelligence/InteractionContext.java b/core/java/android/service/intelligence/InteractionContext.java index 0cc377bb030b..7f4283db28d2 100644 --- a/core/java/android/service/intelligence/InteractionContext.java +++ b/core/java/android/service/intelligence/InteractionContext.java @@ -37,7 +37,7 @@ public final class InteractionContext implements Parcelable { /** * Flag used to indicate that the app explicitly disabled content capture for the activity * (using - * {@link android.view.intelligence.IntelligenceManager#setContentCaptureEnabled()}), + * {@link android.view.intelligence.ContentCaptureManager#setContentCaptureEnabled()}), * in which case the service will just receive activity-level events. */ public static final int FLAG_DISABLED_BY_APP = 0x1; diff --git a/core/java/android/service/intelligence/PresentationParams.java b/core/java/android/service/intelligence/PresentationParams.java index c59069bbb674..95303099793a 100644 --- a/core/java/android/service/intelligence/PresentationParams.java +++ b/core/java/android/service/intelligence/PresentationParams.java @@ -20,7 +20,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; import android.graphics.Rect; -import android.service.intelligence.IntelligenceService.AutofillProxy; +import android.service.intelligence.SmartSuggestionsService.AutofillProxy; import android.util.DebugUtils; import android.view.View; diff --git a/core/java/android/service/intelligence/IntelligenceService.java b/core/java/android/service/intelligence/SmartSuggestionsService.java index 040e25e977e4..90f04ca66db7 100644 --- a/core/java/android/service/intelligence/IntelligenceService.java +++ b/core/java/android/service/intelligence/SmartSuggestionsService.java @@ -19,8 +19,10 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import android.annotation.CallSuper; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.Service; +import android.content.ComponentName; import android.content.Intent; import android.graphics.Rect; import android.os.CancellationSignal; @@ -43,19 +45,18 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import java.util.Set; /** - * A service used to capture the content of the screen. - * - * <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. + * A service used to capture the content of the screen to provide contextual data in other areas of + * the system such as Autofill. * * @hide */ @SystemApi -public abstract class IntelligenceService extends Service { +public abstract class SmartSuggestionsService extends Service { - private static final String TAG = "IntelligenceService"; + private static final String TAG = "SmartSuggestionsService"; // TODO(b/111330312): STOPSHIP use dynamic value, or change to false static final boolean DEBUG = true; @@ -63,11 +64,11 @@ public abstract class IntelligenceService extends Service { /** * The {@link Intent} that must be declared as handled by the service. * To be supported, the service must also require the - * {@link android.Manifest.permission#BIND_INTELLIGENCE_SERVICE} permission so + * {@link android.Manifest.permission#BIND_SMART_SUGGESTIONS_SERVICE} permission so * that other applications can not abuse it. */ public static final String SERVICE_INTERFACE = - "android.service.intelligence.IntelligenceService"; + "android.service.intelligence.SmartSuggestionsService"; private Handler mHandler; @@ -80,21 +81,21 @@ public abstract class IntelligenceService extends Service { throws RemoteException { if (context != null) { mHandler.sendMessage( - obtainMessage(IntelligenceService::onCreateInteractionSession, - IntelligenceService.this, context, sessionId)); + obtainMessage(SmartSuggestionsService::onCreateInteractionSession, + SmartSuggestionsService.this, context, sessionId)); } else { mHandler.sendMessage( - obtainMessage(IntelligenceService::onDestroyInteractionSession, - IntelligenceService.this, sessionId)); + obtainMessage(SmartSuggestionsService::onDestroyInteractionSession, + SmartSuggestionsService.this, sessionId)); } } @Override - public void onContentCaptureEvents(InteractionSessionId sessionId, - List<ContentCaptureEvent> events) { + public void onContentCaptureEventsRequest(InteractionSessionId sessionId, + ContentCaptureEventsRequest request) { mHandler.sendMessage( - obtainMessage(IntelligenceService::onContentCaptureEvent, - IntelligenceService.this, sessionId, events)); + obtainMessage(SmartSuggestionsService::onContentCaptureEventsRequest, + SmartSuggestionsService.this, sessionId, request)); } @@ -102,22 +103,22 @@ public abstract class IntelligenceService extends Service { public void onActivitySnapshot(InteractionSessionId sessionId, SnapshotData snapshotData) { mHandler.sendMessage( - obtainMessage(IntelligenceService::onActivitySnapshot, - IntelligenceService.this, sessionId, snapshotData)); + obtainMessage(SmartSuggestionsService::onActivitySnapshot, + SmartSuggestionsService.this, sessionId, snapshotData)); } @Override public void onAutofillRequest(InteractionSessionId sessionId, IBinder client, int autofilSessionId, AutofillId focusedId) { - mHandler.sendMessage(obtainMessage(IntelligenceService::handleOnAutofillRequest, - IntelligenceService.this, sessionId, client, autofilSessionId, focusedId)); + mHandler.sendMessage(obtainMessage(SmartSuggestionsService::handleOnAutofillRequest, + SmartSuggestionsService.this, sessionId, client, autofilSessionId, focusedId)); } @Override public void onDestroyAutofillWindowsRequest(InteractionSessionId sessionId) { mHandler.sendMessage( - obtainMessage(IntelligenceService::handleOnDestroyAutofillWindowsRequest, - IntelligenceService.this, sessionId)); + obtainMessage(SmartSuggestionsService::handleOnDestroyAutofillWindowsRequest, + SmartSuggestionsService.this, sessionId)); } }; @@ -139,6 +140,69 @@ public abstract class IntelligenceService extends Service { } /** + * Explicitly limits content capture to the given packages and activities. + * + * <p>When the whitelist is set, it overrides the values passed to + * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)} + * and {@link #setPackageContentCaptureEnabled(String, boolean)}. + * + * <p>To reset the whitelist, call it passing {@code null} to both arguments. + * + * <p>Useful when the service wants to restrict content capture to a category of apps, like + * chat apps. For example, if the service wants to support view captures on all activities of + * app {@code ChatApp1} and just activities {@code act1} and {@code act2} of {@code ChatApp2}, + * it would call: {@code setContentCaptureWhitelist(Arrays.asList("ChatApp1"), + * Arrays.asList(new ComponentName("ChatApp2", "act1"), + * new ComponentName("ChatApp2", "act2")));} + */ + public final void setContentCaptureWhitelist(@Nullable List<String> packages, + @Nullable List<ComponentName> activities) { + //TODO(b/111276913): implement + } + + /** + * Defines whether content capture should be enabled for activities with such + * {@link android.content.ComponentName}. + * + * <p>Useful to blacklist a particular activity. + */ + public final void setActivityContentCaptureEnabled(@NonNull ComponentName activity, + boolean enabled) { + //TODO(b/111276913): implement + } + + /** + * Defines whether content capture should be enabled for activities of the app with such + * {@code packageName}. + * + * <p>Useful to blacklist any activity from a particular app. + */ + public final void setPackageContentCaptureEnabled(@NonNull String packageName, + boolean enabled) { + //TODO(b/111276913): implement + } + + /** + * Gets the activities where content capture was disabled by + * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}. + */ + @NonNull + public final Set<ComponentName> getContentCaptureDisabledActivities() { + //TODO(b/111276913): implement + return null; + } + + /** + * Gets the apps where content capture was disabled by + * {@link #setPackageContentCaptureEnabled(String, boolean)}. + */ + @NonNull + public final Set<String> getContentCaptureDisabledPackages() { + //TODO(b/111276913): implement + return null; + } + + /** * Creates a new interaction session. * * @param context interaction context @@ -152,12 +216,12 @@ public abstract class IntelligenceService extends Service { * session. * * @param sessionId the session's Id - * @param events the events + * @param request the events */ // TODO(b/111276913): rename to onContentCaptureEvents or something like that; also, pass a // Request object so it can be extended - public abstract void onContentCaptureEvent(@NonNull InteractionSessionId sessionId, - @NonNull List<ContentCaptureEvent> events); + public abstract void onContentCaptureEventsRequest(@NonNull InteractionSessionId sessionId, + @NonNull ContentCaptureEventsRequest request); private void handleOnAutofillRequest(@NonNull InteractionSessionId sessionId, @NonNull IBinder client, int autofillSessionId, @NonNull AutofillId focusedId) { @@ -242,8 +306,7 @@ public abstract class IntelligenceService extends Service { } /** - * Notifies the service of {@link IntelligenceSnapshotData snapshot data} associated with a - * session. + * Notifies the service of {@link SnapshotData snapshot data} associated with a session. * * @param sessionId the session's Id * @param snapshotData the data diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index c5d03741dbba..401e75c95a38 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -112,7 +112,7 @@ import android.view.autofill.AutofillValue; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; -import android.view.intelligence.IntelligenceManager; +import android.view.intelligence.ContentCaptureManager; import android.widget.Checkable; import android.widget.FrameLayout; import android.widget.ScrollBarDrawable; @@ -8138,7 +8138,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * is visible. * * <p>The populated structure is then passed to the service through - * {@link IntelligenceManager#notifyViewAppeared(ViewStructure)}. + * {@link ContentCaptureManager#notifyViewAppeared(ViewStructure)}. * * <p><b>Note: </b>the following methods of the {@code structure} will be ignored: * <ul> @@ -8915,7 +8915,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * Helper used to notify the {@link IntelligenceManager} when the view is removed or + * Helper used to notify the {@link ContentCaptureManager} when the view is removed or * added, based on whether it's laid out and visible, and without knowing if the parent removed * it from the view hierarchy. * @@ -8931,11 +8931,15 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * </ol> */ private void notifyAppearedOrDisappearedForContentCaptureIfNeeded(boolean appeared) { + // First check if context has client, so it saves a service lookup when it doesn't + if (!mContext.isContentCaptureSupported()) return; - final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class); - if (im == null || !im.isContentCaptureEnabled()) return; + // Then check if it's enabled in the context... + final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class); + if (cm == null || !cm.isContentCaptureEnabled()) return; - // NOTE: isImportantForContentCapture() is more expensive than im.isContentCaptureEnabled() + // ... and finally at the view level + // NOTE: isImportantForContentCapture() is more expensive than cm.isContentCaptureEnabled() if (!isImportantForContentCapture()) return; if (appeared) { @@ -8950,9 +8954,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return; } // All good: notify the manager... - final ViewStructure structure = im.newViewStructure(this); + final ViewStructure structure = cm.newViewStructure(this); onProvideContentCaptureStructure(structure, /* flags= */ 0); - im.notifyViewAppeared(structure); + cm.notifyViewAppeared(structure); // ...and set the flags mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED; mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED; @@ -8969,7 +8973,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return; } // All good: notify the manager... - im.notifyViewDisappeared(getAutofillId()); + cm.notifyViewDisappeared(getAutofillId()); // ...and set the flags mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED; mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED; diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.java b/core/java/android/view/intelligence/ContentCaptureEvent.java index befcb55b1f73..f63628105cba 100644 --- a/core/java/android/view/intelligence/ContentCaptureEvent.java +++ b/core/java/android/view/intelligence/ContentCaptureEvent.java @@ -163,7 +163,7 @@ public final class ContentCaptureEvent implements Parcelable { * Gets optional flags associated with the event. * * @return either {@code 0} or - * {@link android.view.intelligence.IntelligenceManager#FLAG_USER_INPUT}. + * {@link android.view.intelligence.ContentCaptureManager#FLAG_USER_INPUT}. */ public int getFlags() { return mFlags; diff --git a/core/java/android/view/intelligence/IntelligenceManager.java b/core/java/android/view/intelligence/ContentCaptureManager.java index 2f3b4ef56aa1..9023cd08159a 100644 --- a/core/java/android/view/intelligence/IntelligenceManager.java +++ b/core/java/android/view/intelligence/ContentCaptureManager.java @@ -23,7 +23,6 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import android.annotation.NonNull; import android.annotation.Nullable; -import android.annotation.SystemApi; import android.annotation.SystemService; import android.content.ComponentName; import android.content.Context; @@ -44,13 +43,8 @@ import com.android.internal.util.Preconditions; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.List; -import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; -/** - * TODO(b/111276913): add javadocs / implement - */ /* * NOTE: all methods in this class should return right away, or do the real work in a handler * thread. @@ -58,10 +52,13 @@ import java.util.concurrent.atomic.AtomicBoolean; * Hence, the only field that must be thread-safe is mEnabled, which is called at the beginning * of every method. */ -@SystemService(Context.INTELLIGENCE_MANAGER_SERVICE) -public final class IntelligenceManager { +/** + * TODO(b/111276913): add javadocs / implement + */ +@SystemService(Context.CONTENT_CAPTURE_MANAGER_SERVICE) +public final class ContentCaptureManager { - private static final String TAG = "IntelligenceManager"; + private static final String TAG = "ContentCaptureManager"; // TODO(b/111276913): define a way to dynamically set them(for example, using settings?) private static final boolean VERBOSE = false; @@ -140,7 +137,7 @@ public final class IntelligenceManager { private final Handler mHandler; /** @hide */ - public IntelligenceManager(@NonNull Context context, @Nullable IIntelligenceManager service) { + public ContentCaptureManager(@NonNull Context context, @Nullable IIntelligenceManager service) { mContext = Preconditions.checkNotNull(context, "context cannot be null"); if (VERBOSE) { Log.v(TAG, "Constructor for " + context.getPackageName()); @@ -156,7 +153,7 @@ public final class IntelligenceManager { public void onActivityCreated(@NonNull IBinder token, @NonNull ComponentName componentName) { if (!isContentCaptureEnabled()) return; - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleStartSession, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleStartSession, this, token, componentName)); } @@ -264,7 +261,7 @@ public final class IntelligenceManager { Log.v(TAG, "onActivityLifecycleEvent() for " + getActivityDebugName() + ": " + ContentCaptureEvent.getTypeAsString(type)); } - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this, new ContentCaptureEvent(type), /* forceFlush= */ true)); } @@ -279,7 +276,7 @@ public final class IntelligenceManager { + ", mId=" + mId); } - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleFinishSession, this)); + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleFinishSession, this)); } private void handleFinishSession() { @@ -328,7 +325,7 @@ public final class IntelligenceManager { throw new IllegalArgumentException("Invalid node class: " + node.getClass()); } - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this, new ContentCaptureEvent(TYPE_VIEW_APPEARED) .setViewNode(((ViewNode.ViewStructureImpl) node).mNode), /* forceFlush= */ false)); @@ -346,7 +343,7 @@ public final class IntelligenceManager { Preconditions.checkNotNull(id); if (!isContentCaptureEnabled()) return; - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this, new ContentCaptureEvent(TYPE_VIEW_DISAPPEARED).setAutofillId(id), /* forceFlush= */ false)); } @@ -365,7 +362,7 @@ public final class IntelligenceManager { if (!isContentCaptureEnabled()) return; - mHandler.sendMessage(obtainMessage(IntelligenceManager::handleSendEvent, this, + mHandler.sendMessage(obtainMessage(ContentCaptureManager::handleSendEvent, this, new ContentCaptureEvent(TYPE_VIEW_TEXT_CHANGED, flags).setAutofillId(id) .setText(text), /* forceFlush= */ false)); } @@ -396,11 +393,11 @@ public final class IntelligenceManager { } /** - * Returns the component name of the {@code android.service.intelligence.IntelligenceService} - * that is enabled for the current user. + * Returns the component name of the system service that is consuming the captured events for + * the current user. */ @Nullable - public ComponentName getIntelligenceServiceComponentName() { + public ComponentName getServiceComponentName() { //TODO(b/111276913): implement return null; } @@ -422,106 +419,6 @@ public final class IntelligenceManager { //TODO(b/111276913): implement } - /** - * Called by the the service {@link android.service.intelligence.IntelligenceService} - * to define whether content capture should be enabled for activities with such - * {@link android.content.ComponentName}. - * - * <p>Useful to blacklist a particular activity. - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - public void setActivityContentCaptureEnabled(@NonNull ComponentName activity, - boolean enabled) { - //TODO(b/111276913): implement - } - - /** - * Called by the the service {@link android.service.intelligence.IntelligenceService} - * to explicitly limit content capture to the given packages and activities. - * - * <p>When the whitelist is set, it overrides the values passed to - * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)} - * and {@link #setPackageContentCaptureEnabled(String, boolean)}. - * - * <p>To reset the whitelist, call it passing {@code null} to both arguments. - * - * <p>Useful when the service wants to restrict content capture to a category of apps, like - * chat apps. For example, if the service wants to support view captures on all activities of - * app {@code ChatApp1} and just activities {@code act1} and {@code act2} of {@code ChatApp2}, - * it would call: {@code setContentCaptureWhitelist(Arrays.asList("ChatApp1"), - * Arrays.asList(new ComponentName("ChatApp2", "act1"), - * new ComponentName("ChatApp2", "act2")));} - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - public void setContentCaptureWhitelist(@Nullable List<String> packages, - @Nullable List<ComponentName> activities) { - //TODO(b/111276913): implement - } - - /** - * Called by the the service {@link android.service.intelligence.IntelligenceService} - * to define whether content capture should be enabled for activities of the app with such - * {@code packageName}. - * - * <p>Useful to blacklist any activity from a particular app. - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - public void setPackageContentCaptureEnabled(@NonNull String packageName, boolean enabled) { - //TODO(b/111276913): implement - } - - /** - * Gets the activities where content capture was disabled by - * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}. - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - @NonNull - public Set<ComponentName> getContentCaptureDisabledActivities() { - //TODO(b/111276913): implement - return null; - } - - /** - * Gets the apps where content capture was disabled by - * {@link #setPackageContentCaptureEnabled(String, boolean)}. - * - * @throws UnsupportedOperationException if not called by the UID that owns the - * {@link android.service.intelligence.IntelligenceService} associated with the - * current user. - * - * @hide - */ - @SystemApi - @NonNull - public Set<String> getContentCaptureDisabledPackages() { - //TODO(b/111276913): implement - return null; - } - /** @hide */ public void dump(String prefix, PrintWriter pw) { pw.print(prefix); pw.println("IntelligenceManager"); @@ -547,7 +444,7 @@ public final class IntelligenceManager { } if (mEvents != null) { final int numberEvents = mEvents.size(); - pw.print(prefix2); pw.print("batched events: "); pw.print(numberEvents); + pw.print(prefix2); pw.print("buffered events: "); pw.print(numberEvents); pw.print('/'); pw.println(MAX_BUFFER_SIZE); if (VERBOSE && numberEvents > 0) { final String prefix3 = prefix2 + " "; diff --git a/core/java/android/view/intelligence/IIntelligenceManager.aidl b/core/java/android/view/intelligence/IIntelligenceManager.aidl index 7518ff53b638..882fb2674bf1 100644 --- a/core/java/android/view/intelligence/IIntelligenceManager.aidl +++ b/core/java/android/view/intelligence/IIntelligenceManager.aidl @@ -28,6 +28,7 @@ import java.util.List; /** * {@hide} */ +// TODO(b/111276913): rename once the final name is defined oneway interface IIntelligenceManager { /** * Starts a session, sending the "remote" sessionId to the receiver. diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 1deee8af3d75..085f8f1d678f 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -166,7 +166,7 @@ import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputMethodManager; -import android.view.intelligence.IntelligenceManager; +import android.view.intelligence.ContentCaptureManager; import android.view.textclassifier.TextClassification; import android.view.textclassifier.TextClassificationContext; import android.view.textclassifier.TextClassificationManager; @@ -10135,7 +10135,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * Notify managers (such as {@link AutofillManager} and {@link IntelligenceManager}) that are + * Notify managers (such as {@link AutofillManager} and {@link ContentCaptureManager}) that are * interested on text changes. */ private void notifyListeningManagersAfterTextChanged() { @@ -10155,10 +10155,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // ContentCapture if (isImportantForContentCapture() && isTextEditable()) { - final IntelligenceManager im = mContext.getSystemService(IntelligenceManager.class); - if (im != null && im.isContentCaptureEnabled()) { + final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class); + if (cm != null && cm.isContentCaptureEnabled()) { // TODO(b/111276913): pass flags when edited by user / add CTS test - im.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0); + cm.notifyViewTextChanged(getAutofillId(), getText(), /* flags= */ 0); } } } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index b4d5f67e945e..91b98694a623 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -3047,12 +3047,12 @@ <permission android:name="android.permission.BIND_TEXTCLASSIFIER_SERVICE" android:protectionLevel="signature" /> - <!-- Must be required by a android.service.intelligence.IntelligenceService, + <!-- Must be required by a android.service.intelligence.SmartSuggestionsService, to ensure that only the system can bind to it. @SystemApi @hide This is not a third-party API (intended for OEMs and system apps). <p>Protection level: signature --> - <permission android:name="android.permission.BIND_INTELLIGENCE_SERVICE" + <permission android:name="android.permission.BIND_SMART_SUGGESTIONS_SERVICE" android:protectionLevel="signature" /> <!-- Must be required by hotword enrollment application, diff --git a/services/core/java/com/android/server/AbstractPerUserSystemService.java b/services/core/java/com/android/server/AbstractPerUserSystemService.java index 71d261c7f5b5..001d85f1b798 100644 --- a/services/core/java/com/android/server/AbstractPerUserSystemService.java +++ b/services/core/java/com/android/server/AbstractPerUserSystemService.java @@ -108,7 +108,8 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst * <p>Typically called when the service {@link Settings} property or {@link UserManager} * restriction changed, which includes the initial creation of the service. * - * <p>Subclasses can extend this method to provide extra initialization. + * <p>Subclasses can extend this method to provide extra initialization, like clearing up + * previous state. * * @param disabled whether the service is disabled (due to {@link UserManager} restrictions). * diff --git a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java index 6fe632459eaa..d5be26ac3389 100644 --- a/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java +++ b/services/core/java/com/android/server/intelligence/IntelligenceManagerInternal.java @@ -27,12 +27,13 @@ import android.view.autofill.IAutoFillManagerClient; * * @hide Only for use within the system server. */ +//TODO(b/111276913): rename once the final name is defined public abstract class IntelligenceManagerInternal { /** * Checks whether the given {@code uid} owns the - * {@link android.service.intelligence.IntelligenceService} implementation associated with the - * given {@code userId}. + * {@link android.service.intelligence.SmartSuggestionsService} implementation associated with + * the given {@code userId}. */ public abstract boolean isIntelligenceServiceForUser(int uid, @UserIdInt int userId); diff --git a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java index 08fbf5549a87..108f91c7fe4c 100644 --- a/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java +++ b/services/intelligence/java/com/android/server/intelligence/ContentCaptureSession.java @@ -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") diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java index 9fd797d1e549..e0d47d2c8802 100644 --- a/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java +++ b/services/intelligence/java/com/android/server/intelligence/IntelligenceManagerService.java @@ -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); } diff --git a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java index 9ab7e58feb9b..84e06b04768c 100644 --- a/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java +++ b/services/intelligence/java/com/android/server/intelligence/IntelligencePerUserService.java @@ -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 diff --git a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java index 00c5b6a1d67b..5ebb99eeddcf 100644 --- a/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java +++ b/services/intelligence/java/com/android/server/intelligence/RemoteIntelligenceService.java @@ -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)); } } |