Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7e7ca548 authored by Felix Oghina's avatar Felix Oghina Committed by Sandeep Bandaru
Browse files

Send AssistContent with current activity's intent to contentcapture.

- This change extends the current sending of ActivityEvent, to also send Intent data during activity-start.
- Internally, the call chain in ContentCapture local service is asynchronous http://shortn/_8GKsVIffiV

Context: go/aiai-intent-discovery

Bug: 344587973
Test: manual - Checks if the activity-start AssistInfo are received by
    ContentCaptureService in AiAi.
Test: added cts in topic.
Test: atest ActivityRecordTests

Change-Id: Ic61f1a6a401d742e1a364cb71b1814dc9a651a47
parent 4ce92c2d
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -34,12 +34,22 @@ public class AssistContent implements Parcelable {
    }

    /**
     * Create an AssistContent with extras initialized.
     *
     * @hide
     */
    public AssistContent(@android.annotation.NonNull Bundle extras) {
        mExtras = extras;
    }

    /**
     * Called by {@link android.app.ActivityThread} to set the default Intent based on
     * {@link android.app.Activity#getIntent Activity.getIntent}.
     *
     * <p>Automatically populates {@link #mUri} if that Intent is an {@link Intent#ACTION_VIEW}
     * of a web (http or https scheme) URI.</p>
     *
     * @hide
     */
    public void setDefaultIntent(Intent intent) {
        mIntent = intent;
+11 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
import android.app.assist.AssistContent;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
import android.content.Intent;
@@ -133,6 +134,16 @@ public abstract class ContentCaptureService extends Service {
     */
    public static final String SERVICE_META_DATA = "android.content_capture";


    /**
     * Extras key to flag that the passed in {@link AssistContent} is sent only during Activity
     * start.
     *
     * @hide
     */
    public static final String ASSIST_CONTENT_ACTIVITY_START_KEY = "activity_start_assist_content";


    private final LocalDataShareAdapterResourceManager mDataShareAdapterResourceManager =
            new LocalDataShareAdapterResourceManager();

+8 −0
Original line number Diff line number Diff line
@@ -365,6 +365,14 @@ public final class ContentCaptureManager {
    public static final String DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER =
            "enable_content_protection_receiver";

    /**
     * Whether AssistContent snapshot should be sent on activity start.
     *
     * @hide
     */
    public static final String DEVICE_CONFIG_ENABLE_ACTIVITY_START_ASSIST_CONTENT =
            "enable_activity_start_assist_content";

    /**
     * Sets the size of the in-memory ring buffer for the content protection flow.
     *
+49 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.contentcapture;

import static android.Manifest.permission.MANAGE_CONTENT_CAPTURE;
import static android.content.Context.CONTENT_CAPTURE_MANAGER_SERVICE;
import static android.service.contentcapture.ContentCaptureService.ASSIST_CONTENT_ACTIVITY_START_KEY;
import static android.service.contentcapture.ContentCaptureService.setClientState;
import static android.view.contentcapture.ContentCaptureHelper.toList;
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_ALLOWLIST_DELAY_MS;
@@ -28,6 +29,7 @@ import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PR
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_OPTIONAL_GROUPS_THRESHOLD;
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_REQUIRED_GROUPS_CONFIG;
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_PROPERTY_ENABLE_CONTENT_PROTECTION_RECEIVER;
import static android.view.contentcapture.ContentCaptureManager.DEVICE_CONFIG_ENABLE_ACTIVITY_START_ASSIST_CONTENT;
import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_FALSE;
import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_OK;
import static android.view.contentcapture.ContentCaptureManager.RESULT_CODE_SECURITY_EXCEPTION;
@@ -44,6 +46,7 @@ import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVIC
import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__DATA_SHARE_WRITE_FINISHED;
import static com.android.internal.util.FrameworkStatsLog.CONTENT_CAPTURE_SERVICE_EVENTS__EVENT__REJECT_DATA_SHARE_REQUEST;
import static com.android.internal.util.SyncResultReceiver.bundleFor;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;

import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -52,10 +55,12 @@ import android.app.ActivityManagerInternal;
import android.app.ActivityThread;
import android.app.admin.DevicePolicyCache;
import android.app.assist.ActivityId;
import android.app.assist.AssistContent;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityPresentationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
@@ -184,6 +189,9 @@ public class ContentCaptureManagerService extends
    @Nullable
    private boolean mDisabledByDeviceConfig;

    @GuardedBy("mLock")
    private boolean activityStartAssistDataEnabled;

    // Device-config settings that are cached and passed back to apps
    @GuardedBy("mLock")
    int mDevCfgLoggingLevel;
@@ -451,6 +459,8 @@ public class ContentCaptureManagerService extends
                case DEVICE_CONFIG_PROPERTY_CONTENT_PROTECTION_AUTO_DISCONNECT_TIMEOUT:
                    setFineTuneParamsFromDeviceConfig();
                    return;
                case DEVICE_CONFIG_ENABLE_ACTIVITY_START_ASSIST_CONTENT:
                    setActivityStartAssistDataEnabled();
                default:
                    Slog.i(TAG, "Ignoring change on " + key);
            }
@@ -639,6 +649,15 @@ public class ContentCaptureManagerService extends
        final String enabled = DeviceConfig.getProperty(DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                ContentCaptureManager.DEVICE_CONFIG_PROPERTY_SERVICE_EXPLICITLY_ENABLED);
        setDisabledByDeviceConfig(enabled);
        setActivityStartAssistDataEnabled();
    }

    private void setActivityStartAssistDataEnabled() {
        synchronized (mLock) {
            this.activityStartAssistDataEnabled = DeviceConfig.getBoolean(
                    DeviceConfig.NAMESPACE_CONTENT_CAPTURE,
                    DEVICE_CONFIG_ENABLE_ACTIVITY_START_ASSIST_CONTENT, false);
        }
    }

    private void setDisabledByDeviceConfig(@Nullable String explicitlyEnabled) {
@@ -908,6 +927,9 @@ public class ContentCaptureManagerService extends
        pw.print(prefix2);
        pw.print("contentProtectionAutoDisconnectTimeoutMs: ");
        pw.println(mDevCfgContentProtectionAutoDisconnectTimeoutMs);
        pw.print(prefix2);
        pw.print("activityStartAssistDataEnabled: ");
        pw.println(activityStartAssistDataEnabled);
        pw.print(prefix);
        pw.println("Global Options:");
        mGlobalContentCaptureOptions.dump(prefix2, pw);
@@ -1326,6 +1348,33 @@ public class ContentCaptureManagerService extends
            return false;
        }

        @Override
        @SuppressWarnings("GuardedBy")
        public boolean sendActivityStartAssistData(@UserIdInt int userId,
                @NonNull IBinder activityToken,
                @NonNull Intent intentData) {
            synchronized (mLock) {
                if (!activityStartAssistDataEnabled) {
                    return false;
                }
                Intent intent = new Intent(intentData);
                intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_WRITE_URI_PERMISSION
                        | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION));
                Bundle assistContentExtras = new Bundle();
                assistContentExtras.putBoolean(ASSIST_CONTENT_ACTIVITY_START_KEY, true);
                AssistContent assistContent = new AssistContent(assistContentExtras);
                assistContent.setDefaultIntent(intent);

                final Bundle activityAssistData = new Bundle();
                activityAssistData.putParcelable(ASSIST_KEY_CONTENT, assistContent);
                final ContentCapturePerUserService service = peekServiceForUserLocked(userId);
                if (service != null) {
                    return service.sendActivityAssistDataLocked(activityToken, activityAssistData);
                }
            }
            return false;
        }

        @Override
        public boolean sendActivityAssistData(@UserIdInt int userId, @NonNull IBinder activityToken,
                @NonNull Bundle data) {
+9 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.UserIdInt;
import android.app.assist.ActivityId;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.service.contentcapture.ActivityEvent.ActivityEventType;
@@ -39,6 +40,14 @@ public abstract class ContentCaptureManagerInternal {
     */
    public abstract boolean isContentCaptureServiceForUser(int uid, @UserIdInt int userId);

    /**
     * Notifies the intelligence service of new intent data associated with an activity start event.
     *
     * @return {@code false} if there was no service set for the given user
     */
    public abstract boolean sendActivityStartAssistData(@UserIdInt int userId,
            @NonNull IBinder activityToken, @NonNull Intent intentData);

    /**
     * Notifies the intelligence service of new assist data for the given activity.
     *
Loading