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

Commit 70c02611 authored by Felipe Leme's avatar Felipe Leme Committed by Android (Google) Code Review
Browse files

Merge "Refactored InteractionSessionId."

parents 15fe040f a7bdb148
Loading
Loading
Loading
Loading
+60 −21
Original line number Diff line number Diff line
@@ -16,43 +16,85 @@

package android.service.intelligence;

import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;

import java.io.PrintWriter;
import java.util.UUID;

// TODO(b/111276913): add javadocs / implement equals/hashcode/string
/** @hide */
@SystemApi
public final class InteractionSessionId implements Parcelable {

    private final int mGlobalId;
    private final @NonNull String mValue;

    // TODO(b/111276913): remove if not needed
    private final int mLocalId;
    /**
     * Creates a new instance.
     *
     * @hide
     */
    public InteractionSessionId() {
        this(UUID.randomUUID().toString());
    }

    /** @hide */
    public InteractionSessionId(int globalId, int localId) {
        mGlobalId = globalId;
        mLocalId = localId;
    /**
     * Creates a new instance.
     *
     * @param value The internal value.
     *
     * @hide
     */
    public InteractionSessionId(@NonNull String value) {
        mValue = value;
    }

    /** @hide */
    public int getGlobalId() {
        return mGlobalId;
    /**
     * @hide
     */
    public String getValue() {
        return mValue;
    }

    /** @hide */
    // TODO(b/111276913): dump to proto as well
    public void dump(PrintWriter pw) {
        pw.print("globalId="); pw.print(mGlobalId);
        pw.print("localId="); pw.print(mLocalId);
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((mValue == null) ? 0 : mValue.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        final InteractionSessionId other = (InteractionSessionId) obj;
        if (mValue == null) {
            if (other.mValue != null) return false;
        } else if (!mValue.equals(other.mValue)) {
            return false;
        }
        return true;
    }

    /**
     * @inheritdoc
     *
     * <p><b>NOTE: </b>this method is only useful for debugging purposes and is not guaranteed to
     * be stable, hence it should not be used to identify the session.
     */
    @Override
    public String toString() {
        return "SessionId[globalId=" + mGlobalId + ", localId=" + mLocalId + "]";
        return mValue;
    }

    /** @hide */
    // TODO(b/111276913): dump to proto as well
    public void dump(PrintWriter pw) {
        pw.print(mValue);
    }

    @Override
@@ -62,8 +104,7 @@ public final class InteractionSessionId implements Parcelable {

    @Override
    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeInt(mGlobalId);
        parcel.writeInt(mLocalId);
        parcel.writeString(mValue);
    }

    public static final Parcelable.Creator<InteractionSessionId> CREATOR =
@@ -71,9 +112,7 @@ public final class InteractionSessionId implements Parcelable {

        @Override
        public InteractionSessionId createFromParcel(Parcel parcel) {
            final int globalId = parcel.readInt();
            final int localId = parcel.readInt();
            return new InteractionSessionId(globalId, localId);
            return new InteractionSessionId(parcel.readString());
        }

        @Override
+5 −9
Original line number Diff line number Diff line
@@ -17,9 +17,8 @@
package android.view.intelligence;

import android.content.ComponentName;

import android.os.IBinder;

import android.service.intelligence.InteractionSessionId;
import android.view.intelligence.ContentCaptureEvent;

import com.android.internal.os.IResultReceiver;
@@ -34,19 +33,16 @@ oneway interface IIntelligenceManager {
      * Starts a session, sending the "remote" sessionId to the receiver.
      */
    void startSession(int userId, IBinder activityToken, in ComponentName componentName,
                      int localSessionId, int flags, in IResultReceiver result);
                      in InteractionSessionId sessionId, int flags, in IResultReceiver result);

    /**
      * Finishes a session.
      */
    // TODO(b/111276913): pass just (global) session id
    void finishSession(int userId, IBinder activityToken, in ComponentName componentName,
                       int localSessionId, int globalSessionId);
    void finishSession(int userId, in InteractionSessionId sessionId);

    /**
      * Sends a batch of events
      */
    // TODO(b/111276913): pass just (global) session id
    void sendEvents(int userId, IBinder activityToken, in ComponentName componentName,
                    int localSessionId, int globalSessionId, in List<ContentCaptureEvent> events);
    void sendEvents(int userId, in InteractionSessionId sessionId,
                    in List<ContentCaptureEvent> events);
}
+20 −35
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.service.intelligence.InteractionSessionId;
import android.util.Log;
import android.view.intelligence.ContentCaptureEvent.EventType;

@@ -55,9 +56,6 @@ public final class IntelligenceManager {
    public static final int FLAG_USER_INPUT = 0x1;


    /** @hide */
    public static final int NO_SESSION = 0;

    /**
     * Initial state, when there is no session.
     *
@@ -66,11 +64,11 @@ public final class IntelligenceManager {
    public static final int STATE_UNKNOWN = 0;

    /**
     * Service's startSession() was called, but remote session id was not returned yet.
     * Service's startSession() was called, but server didn't confirm it was created yet.
     *
     * @hide
     */
    public static final int STATE_WAITING_FOR_SESSION_ID = 1;
    public static final int STATE_WAITING_FOR_SERVER = 1;

    /**
     * Session is active.
@@ -79,8 +77,6 @@ public final class IntelligenceManager {
     */
    public static final int STATE_ACTIVE = 2;

    private static int sNextSessionId;

    private final Context mContext;

    @Nullable
@@ -88,14 +84,9 @@ public final class IntelligenceManager {

    private final Object mLock = new Object();

    // TODO(b/111276913): localSessionId might be an overkill, perhaps just the global id is enough.
    // Let's keep both for now, and revisit once we decide whether the session id will be persisted
    // when the activity's process is killed
    @GuardedBy("mLock")
    private int mLocalSessionId = NO_SESSION;

    @Nullable
    @GuardedBy("mLock")
    private int mRemoteSessionId = NO_SESSION;
    private InteractionSessionId mId;

    @GuardedBy("mLock")
    private int mState = STATE_UNKNOWN;
@@ -124,27 +115,25 @@ public final class IntelligenceManager {
                        + getStateAsStringLocked());
                return;
            }
            mState = STATE_WAITING_FOR_SESSION_ID;
            mLocalSessionId = ++sNextSessionId;
            mRemoteSessionId = NO_SESSION;
            mState = STATE_WAITING_FOR_SERVER;
            mId = new InteractionSessionId();
            mApplicationToken = token;
            mComponentName = componentName;

            if (VERBOSE) {
                Log.v(TAG, "onActivityStarted(): token=" + token + ", act=" + componentName
                        + ", localSessionId=" + mLocalSessionId);
                        + ", id=" + mId);
            }
            final int flags = 0; // TODO(b/111276913): get proper flags

            try {
                mService.startSession(mContext.getUserId(), mApplicationToken, componentName,
                        mLocalSessionId, flags, new IResultReceiver.Stub() {
                        mId, flags, new IResultReceiver.Stub() {
                            @Override
                            public void send(int resultCode, Bundle resultData)
                                    throws RemoteException {
                                synchronized (mLock) {
                                    if (resultCode > 0) {
                                        mRemoteSessionId = resultCode;
                                        mState = STATE_ACTIVE;
                                    } else {
                                        // TODO(b/111276913): handle other cases like disabled by
@@ -153,7 +142,7 @@ public final class IntelligenceManager {
                                    }
                                    if (VERBOSE) {
                                        Log.v(TAG, "onActivityStarted() result: code=" + resultCode
                                                + ", remoteSession=" + mRemoteSessionId
                                                + ", id=" + mId
                                                + ", state=" + getStateAsStringLocked());
                                    }
                                }
@@ -189,8 +178,7 @@ public final class IntelligenceManager {
            }

            try {
                mService.sendEvents(mContext.getUserId(), mApplicationToken, mComponentName,
                        mLocalSessionId, mRemoteSessionId, events);
                mService.sendEvents(mContext.getUserId(), mId, events);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
@@ -207,15 +195,13 @@ public final class IntelligenceManager {

            if (VERBOSE) {
                Log.v(TAG, "onActivityDestroyed(): state=" + getStateAsStringLocked()
                        + ", localSessionId=" + mLocalSessionId
                        + ", mRemoteSessionId=" + mRemoteSessionId);
                        + ", mId=" + mId);
            }

            try {
                mService.finishSession(mContext.getUserId(), mApplicationToken, mComponentName,
                        mLocalSessionId, mRemoteSessionId);
                mService.finishSession(mContext.getUserId(), mId);
                mState = STATE_UNKNOWN;
                mLocalSessionId = mRemoteSessionId = NO_SESSION;
                mId = null;
                mApplicationToken = null;
                mComponentName = null;
            } catch (RemoteException e) {
@@ -334,12 +320,11 @@ public final class IntelligenceManager {
            pw.print(prefix2); pw.print("mService: "); pw.println(mService);
            pw.print(prefix2); pw.print("user: "); pw.println(mContext.getUserId());
            pw.print(prefix2); pw.print("enabled: "); pw.println(isContentCaptureEnabled());
            pw.print(prefix2); pw.print("mLocalSessionId: "); pw.println(mLocalSessionId);
            pw.print(prefix2); pw.print("mRemoteSessionId: "); pw.println(mRemoteSessionId);
            pw.print(prefix2); pw.print("mState: "); pw.print(mState); pw.print(" (");
            pw.print(prefix2); pw.print("id: "); pw.println(mId);
            pw.print(prefix2); pw.print("state: "); pw.print(mState); pw.print(" (");
            pw.print(getStateAsStringLocked()); pw.println(")");
            pw.print(prefix2); pw.print("mAppToken: "); pw.println(mApplicationToken);
            pw.print(prefix2); pw.print("mComponentName: "); pw.println(mComponentName);
            pw.print(prefix2); pw.print("appToken: "); pw.println(mApplicationToken);
            pw.print(prefix2); pw.print("componentName: "); pw.println(mComponentName);
        }
    }

@@ -353,8 +338,8 @@ public final class IntelligenceManager {
        switch (state) {
            case STATE_UNKNOWN:
                return "UNKNOWN";
            case STATE_WAITING_FOR_SESSION_ID:
                return "WAITING_FOR_SESSION_ID";
            case STATE_WAITING_FOR_SERVER:
                return "WAITING_FOR_SERVER";
            case STATE_ACTIVE:
                return "ACTIVE";
            default:
+9 −10
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.Slog;
import android.view.intelligence.ContentCaptureEvent;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import com.android.server.AbstractRemoteService;
import com.android.server.intelligence.RemoteIntelligenceService.RemoteIntelligenceServiceCallbacks;

@@ -47,15 +48,15 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
    ContentCaptureSession(@NonNull Context context, int userId, @NonNull Object lock,
            @NonNull IBinder activityToken, @NonNull IntelligencePerUserService service,
            @NonNull ComponentName serviceComponentName, @NonNull ComponentName appComponentName,
            int taskId, int displayId, int localSessionId, int globalSessionId, int flags,
            int taskId, int displayId, @NonNull InteractionSessionId sessionId, int flags,
            boolean bindInstantServiceAllowed, boolean verbose) {
        mLock = lock;
        mActivityToken = activityToken;
        mService = service;
        mId = Preconditions.checkNotNull(sessionId);
        mRemoteService = new RemoteIntelligenceService(context,
                IntelligenceService.SERVICE_INTERFACE, serviceComponentName, userId, this,
                bindInstantServiceAllowed, verbose);
        mId = new InteractionSessionId(globalSessionId, localSessionId);
        mInterationContext = new InteractionContext(appComponentName, taskId, displayId, flags);
    }

@@ -88,7 +89,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
                mRemoteService.onSessionLifecycleRequest(/* context= */ null, mId);
            }
        } finally {
            mService.removeSessionLocked(mInterationContext.getActivityComponent());
            mService.removeSessionLocked(mId);
        }
    }

@@ -114,17 +115,15 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
        }
    }

    /**
     * Gets global id, unique per {@link IntelligencePerUserService}.
     */
    public int getGlobalSessionId() {
        return mId.getGlobalId();
    }

    @GuardedBy("mLock")
    public void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
        pw.print(prefix); pw.print("id: ");  mId.dump(pw); pw.println();
        pw.print(prefix); pw.print("context: ");  mInterationContext.dump(pw); pw.println();
        pw.print(prefix); pw.print("activity token: "); pw.println(mActivityToken);
    }

    @Override
    public String toString() {
        return "ContentCaptureSession[id=" + mId.getValue() + ", act=" + mActivityToken + "]";
    }
}
+13 −12
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.os.IBinder;
import android.os.UserManager;
import android.service.intelligence.InteractionSessionId;
import android.view.intelligence.ContentCaptureEvent;
import android.view.intelligence.IIntelligenceManager;

@@ -87,9 +88,11 @@ public final class IntelligenceManagerService

        @Override
        public void startSession(int userId, @NonNull IBinder activityToken,
                @NonNull ComponentName componentName, int localSessionId, int flags,
                @NonNull IResultReceiver result) {
                @NonNull ComponentName componentName, @NonNull InteractionSessionId sessionId,
                int flags, @NonNull IResultReceiver result) {
            Preconditions.checkNotNull(activityToken);
            Preconditions.checkNotNull(componentName);
            Preconditions.checkNotNull(sessionId);

            // TODO(b/111276913): refactor getTaskIdForActivity() to also return ComponentName,
            // so we don't pass it on startSession (same for Autofill)
@@ -101,31 +104,29 @@ public final class IntelligenceManagerService
            synchronized (mLock) {
                final IntelligencePerUserService service = getServiceForUserLocked(userId);
                service.startSessionLocked(activityToken, componentName, taskId, displayId,
                        localSessionId, flags, result);
                        sessionId, flags, result);
            }
        }

        @Override
        public void sendEvents(int userId, @NonNull IBinder activityToken,
                @NonNull ComponentName componentName, int localSessionId, int globalSessionId,
                List<ContentCaptureEvent> events) {
        public void sendEvents(int userId, @NonNull InteractionSessionId sessionId,
                @NonNull List<ContentCaptureEvent> events) {
            Preconditions.checkNotNull(sessionId);
            Preconditions.checkNotNull(events);

            synchronized (mLock) {
                final IntelligencePerUserService service = getServiceForUserLocked(userId);
                service.sendEventsLocked(componentName, events);
                service.sendEventsLocked(sessionId, events);
            }
        }

        @Override
        public void finishSession(int userId, @NonNull IBinder activityToken,
                @NonNull ComponentName componentName, int localSessionId, int globalSessionId) {
            Preconditions.checkNotNull(activityToken);
        public void finishSession(int userId, @NonNull InteractionSessionId sessionId) {
            Preconditions.checkNotNull(sessionId);

            synchronized (mLock) {
                final IntelligencePerUserService service = getServiceForUserLocked(userId);
                service.finishSessionLocked(activityToken, componentName, localSessionId,
                        globalSessionId);
                service.finishSessionLocked(sessionId);
            }
        }

Loading