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

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

Merge "Fixed Content Capture workflow when service is disabled."

parents cc9b7510 8e2e341b
Loading
Loading
Loading
Loading
+18 −11
Original line number Diff line number Diff line
@@ -86,6 +86,13 @@ public final class IntelligenceManager {
     */
    public static final int STATE_ACTIVE = 2;

    /**
     * Session is disabled.
     *
     * @hide
     */
    public static final int STATE_DISABLED = 3;

    private static final String BG_THREAD_NAME = "intel_svc_streamer_thread";

    /**
@@ -166,13 +173,7 @@ public final class IntelligenceManager {
                            public void send(int resultCode, Bundle resultData)
                                    throws RemoteException {
                                synchronized (mLock) {
                                    if (resultCode > 0) {
                                        mState = STATE_ACTIVE;
                                    } else {
                                        // TODO(b/111276913): handle other cases like disabled by
                                        // service
                                        resetStateLocked();
                                    }
                                    mState = resultCode;
                                    if (VERBOSE) {
                                        Log.v(TAG, "onActivityStarted() result: code=" + resultCode
                                                + ", id=" + mId
@@ -203,9 +204,13 @@ public final class IntelligenceManager {
                    // Typically happens on system apps that are started before the system service
                    // is ready (like com.android.settings/.FallbackHome)
                    //TODO(b/111276913): try to ignore session while system is not ready / boot
                    // not complete instead.
                    Log.w(TAG, "Closing session for " + getActivityDebugNameLocked()
                            + " after " + numberEvents + " delayed events");
                    // not complete instead. Similarly, the manager service should return right away
                    // when the user does not have a service set
                    if (VERBOSE) {
                        Log.v(TAG, "Closing session for " + getActivityDebugNameLocked()
                                + " after " + numberEvents + " delayed events and state "
                                + getStateAsString(mState));
                    }
                    // TODO(b/111276913): blacklist activity / use special flag to indicate that
                    // when it's launched again
                    resetStateLocked();
@@ -380,7 +385,7 @@ public final class IntelligenceManager {
        //TODO(b/111276913): properly implement by checking if it was explicitly disabled by
        // service, or if service is not set
        // (and probably renamign to isEnabledLocked()
        return mService != null;
        return mService != null && mState != STATE_DISABLED;
    }

    /**
@@ -509,6 +514,8 @@ public final class IntelligenceManager {
                return "WAITING_FOR_SERVER";
            case STATE_ACTIVE:
                return "ACTIVE";
            case STATE_DISABLED:
                return "DISABLED";
            default:
                return "INVALID:" + state;
        }
+9 −3
Original line number Diff line number Diff line
@@ -167,7 +167,7 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
    @GuardedBy("mLock")
    protected final int getServiceUidLocked() {
        if (mServiceInfo == null) {
            Slog.w(mTag, "getServiceUidLocked(): no mServiceInfo");
            if (mMaster.verbose) Slog.v(mTag, "getServiceUidLocked(): no mServiceInfo");
            return Process.INVALID_UID;
        }
        return mServiceInfo.applicationInfo.uid;
@@ -267,12 +267,18 @@ public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSyst
    @GuardedBy("mLock")
    protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
        pw.print(prefix); pw.print("User: "); pw.println(mUserId);
        pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled);
        pw.print(prefix); pw.print("Disabled by UserManager: "); pw.println(mDisabled);
        pw.print(prefix); pw.print("Setup complete: "); pw.println(mSetupComplete);
        if (mServiceInfo != null) {
            pw.print(prefix); pw.print("Service UID: ");
            pw.println(mServiceInfo.applicationInfo.uid);
        }
        pw.print(prefix); pw.print("Service name: "); pw.println(getComponentNameFromSettings());
        final String componentName = getComponentNameFromSettings();
        if (componentName != null) {
            pw.print(prefix); pw.print("Service name: ");
            pw.println(componentName);
        } else {
            pw.println("No service package set");
        }
    }
}
+20 −4
Original line number Diff line number Diff line
@@ -76,7 +76,7 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
    }

    /**
     * Cleans up the session and remove itself from the service.
     * Cleans up the session and removes it from the service.
     *
     * @param notifyRemoteService whether it should trigger a {@link
     * IntelligenceService#onDestroyInteractionSession(InteractionSessionId)}
@@ -85,14 +85,30 @@ final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks
    @GuardedBy("mLock")
    public void removeSelfLocked(boolean notifyRemoteService) {
        try {
            if (notifyRemoteService) {
                mRemoteService.onSessionLifecycleRequest(/* context= */ null, mId);
            }
            destroyLocked(notifyRemoteService);
        } finally {
            mService.removeSessionLocked(mId);
        }
    }

    /**
     * Cleans up the session, but not removes it from the service.
     *
     * @param notifyRemoteService whether it should trigger a {@link
     * IntelligenceService#onDestroyInteractionSession(InteractionSessionId)}
     * request.
     */
    @GuardedBy("mLock")
    public void destroyLocked(boolean notifyRemoteService) {
        if (mService.isVerbose()) {
            Slog.v(TAG, "destroyLocked(notifyRemoteService=" + notifyRemoteService + ")");
        }
        // TODO(b/111276913): must call client to set session as FINISHED_BY_SERVER
        if (notifyRemoteService) {
            mRemoteService.onSessionLifecycleRequest(/* context= */ null, mId);
        }
    }

    @Override // from RemoteScreenObservationServiceCallbacks
    public void onServiceDied(AbstractRemoteService service) {
        // TODO(b/111276913): implement (remove session from PerUserSession?)
+9 −0
Original line number Diff line number Diff line
@@ -78,6 +78,15 @@ public final class IntelligenceManagerService
        publishLocalService(IntelligenceManagerInternal.class, mLocalService);
    }

    @Override // from AbstractMasterSystemService
    protected IntelligencePerUserService removeCachedServiceLocked(int userId) {
        final IntelligencePerUserService service = super.removeCachedServiceLocked(userId);
        if (service != null) {
            service.destroyLocked();
        }
        return service;
    }

    private ActivityManagerInternal getAmInternal() {
        synchronized (mLock) {
            if (mAm == null) {
+38 −3
Original line number Diff line number Diff line
@@ -88,12 +88,18 @@ final class IntelligencePerUserService
            @NonNull ComponentName componentName, int taskId, int displayId,
            @NonNull InteractionSessionId sessionId, int flags,
            @NonNull IResultReceiver resultReceiver) {
        if (!isEnabledLocked()) {
            sendToClient(resultReceiver, IntelligenceManager.STATE_DISABLED);
            return;
        }
        final ComponentName serviceComponentName = getServiceComponentName();
        if (serviceComponentName == null) {
            // TODO(b/111276913): this happens when the system service is starting, we should
            // probably handle it in a more elegant way (like waiting for boot_complete or
            // something like that
            Slog.w(TAG, "startSession(" + activityToken + "): hold your horses");
            if (mMaster.debug) {
                Slog.d(TAG, "startSession(" + activityToken + "): hold your horses");
            }
            return;
        }

@@ -128,9 +134,15 @@ final class IntelligencePerUserService
    // TODO(b/111276913): log metrics
    @GuardedBy("mLock")
    public void finishSessionLocked(@NonNull InteractionSessionId sessionId) {
        if (!isEnabledLocked()) {
            return;
        }

        final ContentCaptureSession session = mSessions.get(sessionId);
        if (session == null) {
            Slog.w(TAG, "finishSession(): no session with id" + sessionId);
            if (mMaster.debug) {
                Slog.d(TAG, "finishSession(): no session with id" + sessionId);
            }
            return;
        }
        if (mMaster.verbose) {
@@ -139,12 +151,19 @@ final class IntelligencePerUserService
        session.removeSelfLocked(true);
    }

    // TODO(b/111276913): need to figure out why some events are sent before session is started;
    // probably because IntelligenceManager is not buffering them until it gets the session back
    @GuardedBy("mLock")
    public void sendEventsLocked(@NonNull InteractionSessionId sessionId,
            @NonNull List<ContentCaptureEvent> events) {
        if (!isEnabledLocked()) {
            return;
        }
        final ContentCaptureSession session = mSessions.get(sessionId);
        if (session == null) {
            Slog.w(TAG, "sendEvents(): no session for " + sessionId);
            if (mMaster.verbose) {
                Slog.v(TAG, "sendEvents(): no session for " + sessionId);
            }
            return;
        }
        if (mMaster.verbose) {
@@ -163,6 +182,22 @@ final class IntelligencePerUserService
        return uid == getServiceUidLocked();
    }

    /**
     * Destroys the service and all state associated with it.
     *
     * <p>Called when the service was disabled (for example, if the settings change).
     */
    @GuardedBy("mLock")
    public void destroyLocked() {
        if (mMaster.debug) Slog.d(TAG, "destroyLocked()");
        final int numSessions = mSessions.size();
        for (int i = 0; i < numSessions; i++) {
            final ContentCaptureSession session = mSessions.valueAt(i);
            session.destroyLocked(true);
        }
        mSessions.clear();
    }

    @Override
    protected void dumpLocked(String prefix, PrintWriter pw) {
        super.dumpLocked(prefix, pw);