Yet another (major) refactoring on Content Capture and Augmented Autofill.

Bunch of changes:

- Split public SmartSuggestionsService info ContentCaptureService and
  AugmentedAutofillService
- Renamed 'intelligence' packages to either 'contentcapture' or
  'autofil.augmented'
- Renamed internal packages and classes.
- Changed permissions, resource names, etc...
- Moved Augmented Autofill logic from IntelligeceManagerService (R.I.P.) to
  Autofill.
- Optimized IPCs by passing a String instead of the InteractionSessionId
  (that also solves the view -> service dependency).

Test: atest CtsContentCaptureServiceTestCases \
            CtsAutoFillServiceTestCases \
            FrameworksCoreTests:SettingsBackupTest
Test: manual verification with Augmented Autofill Service

Bug: 119638877
Bug: 117944706

Change-Id: I787fc2a0dbd9ad53e4d5edb0d2a9242346e4652d
diff --git a/core/java/android/service/contentcapture/ContentCaptureService.java b/core/java/android/service/contentcapture/ContentCaptureService.java
new file mode 100644
index 0000000..3dfeede
--- /dev/null
+++ b/core/java/android/service/contentcapture/ContentCaptureService.java
@@ -0,0 +1,241 @@
+/*
+ * 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.contentcapture;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+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.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.contentcapture.ContentCaptureEvent;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 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 ContentCaptureService extends Service {
+
+    private static final String TAG = ContentCaptureService.class.getSimpleName();
+
+    // TODO(b/111330312): STOPSHIP use dynamic value, or change to false
+    static final boolean DEBUG = true;
+    static final boolean VERBOSE = false;
+
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     *
+     * <p>To be supported, the service must also require the
+     * {@link android.Manifest.permission#BIND_CONTENT_CAPTURE_SERVICE} permission so
+     * that other applications can not abuse it.
+     */
+    public static final String SERVICE_INTERFACE =
+            "android.service.contentcapture.ContentCaptureService";
+
+    private Handler mHandler;
+
+    private final IContentCaptureService mInterface = new IContentCaptureService.Stub() {
+
+        @Override
+        public void onSessionLifecycle(InteractionContext context, String sessionId)
+                throws RemoteException {
+            if (context != null) {
+                mHandler.sendMessage(
+                        obtainMessage(ContentCaptureService::handleOnCreateInteractionSession,
+                                ContentCaptureService.this, context, sessionId));
+            } else {
+                mHandler.sendMessage(
+                        obtainMessage(ContentCaptureService::handleOnDestroyInteractionSession,
+                                ContentCaptureService.this, sessionId));
+            }
+        }
+
+        @Override
+        public void onContentCaptureEventsRequest(String sessionId,
+                ContentCaptureEventsRequest request) {
+            mHandler.sendMessage(
+                    obtainMessage(ContentCaptureService::handleOnContentCaptureEventsRequest,
+                            ContentCaptureService.this, sessionId, request));
+
+        }
+
+        @Override
+        public void onActivitySnapshot(String sessionId, SnapshotData snapshotData) {
+            mHandler.sendMessage(
+                    obtainMessage(ContentCaptureService::handleOnActivitySnapshot,
+                            ContentCaptureService.this, sessionId, snapshotData));
+        }
+    };
+
+    @CallSuper
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mHandler = new Handler(Looper.getMainLooper(), null, true);
+    }
+
+    /** @hide */
+    @Override
+    public final IBinder onBind(Intent intent) {
+        if (SERVICE_INTERFACE.equals(intent.getAction())) {
+            return mInterface.asBinder();
+        }
+        Log.w(TAG, "Tried to bind to wrong intent (should be " + SERVICE_INTERFACE + ": " + intent);
+        return null;
+    }
+
+    /**
+     * 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
+     * @param sessionId the session's Id
+     */
+    public void onCreateInteractionSession(@NonNull InteractionContext context,
+            @NonNull InteractionSessionId sessionId) {
+        if (VERBOSE) {
+            Log.v(TAG, "onCreateInteractionSession(id=" + sessionId + ", ctx=" + context + ")");
+        }
+    }
+
+    /**
+     * Notifies the service of {@link ContentCaptureEvent events} associated with a content capture
+     * session.
+     *
+     * @param sessionId the session's Id
+     * @param request the events
+     */
+    public abstract void onContentCaptureEventsRequest(@NonNull InteractionSessionId sessionId,
+            @NonNull ContentCaptureEventsRequest request);
+
+    /**
+     * Notifies the service of {@link SnapshotData snapshot data} associated with a session.
+     *
+     * @param sessionId the session's Id
+     * @param snapshotData the data
+     */
+    public void onActivitySnapshot(@NonNull InteractionSessionId sessionId,
+            @NonNull SnapshotData snapshotData) {}
+
+    /**
+     * Destroys the interaction session.
+     *
+     * @param sessionId the id of the session to destroy
+     */
+    public void onDestroyInteractionSession(@NonNull InteractionSessionId sessionId) {
+        if (VERBOSE) {
+            Log.v(TAG, "onDestroyInteractionSession(id=" + sessionId + ")");
+        }
+    }
+
+    //TODO(b/111276913): consider caching the InteractionSessionId for the lifetime of the session,
+    // so we don't need to create a temporary InteractionSessionId for each event.
+
+    private void handleOnCreateInteractionSession(@NonNull InteractionContext context,
+            @NonNull String sessionId) {
+        onCreateInteractionSession(context, new InteractionSessionId(sessionId));
+    }
+
+    private void handleOnContentCaptureEventsRequest(@NonNull String sessionId,
+            @NonNull ContentCaptureEventsRequest request) {
+        onContentCaptureEventsRequest(new InteractionSessionId(sessionId), request);
+    }
+
+    private void handleOnActivitySnapshot(@NonNull String sessionId,
+            @NonNull SnapshotData snapshotData) {
+        onActivitySnapshot(new InteractionSessionId(sessionId), snapshotData);
+    }
+
+    private void handleOnDestroyInteractionSession(@NonNull String sessionId) {
+        onDestroyInteractionSession(new InteractionSessionId(sessionId));
+    }
+}