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

Commit 07848e30 authored by Felipe Leme's avatar Felipe Leme
Browse files

Improved implementation of VoiceInteractionManagerService.setDisabled()

This method is called by CarService when the system goes into suspend
state and the initial implementation completely disabled the service
(and unbound system server from it), which had 2 drawbacks:
- It adds extra work when the system resumes as it has to rebind.
- It can cause memory leaks if the service implementation doesn't
  handle it well.

This CL changes how the API is implemented: rather than disabling the
service, it just ignores new sessions.

To test it:

1. Disable

$ adb shell cmd voiceinteraction disable true

2. Start a session

$ adb shell cmd voiceinteraction show

3. Check logcat

I VoiceInteractionManager: showSessionForActiveService(): ignored while temporarily disabled

Bug: 190051449
Test: manual verification (see above)

Change-Id: Idbc4881b92d9254fb07ea5af1370ea600fc10b80
parent 1a49d4f7
Loading
Loading
Loading
Loading
+33 −24
Original line number Diff line number Diff line
@@ -562,11 +562,10 @@ public class VoiceInteractionManagerService extends SystemService {
        }

        void switchImplementationIfNeededLocked(boolean force) {
            if (!mCurUserSupported || mTemporarilyDisabled) {
            if (!mCurUserSupported) {
                if (DEBUG_USER) {
                    Slog.d(TAG, "switchImplementationIfNeeded(): skipping: force= " + force
                            + "mCurUserSupported=" + mCurUserSupported
                            + "mTemporarilyDisabled=" + mTemporarilyDisabled);
                            + "mCurUserSupported=" + mCurUserSupported);
                }
                if (mImpl != null) {
                    mImpl.shutdownLocked();
@@ -1048,13 +1047,16 @@ public class VoiceInteractionManagerService extends SystemService {
                    if (DEBUG) Slog.d(TAG, "setDisabled(): already " + disabled);
                    return;
                }
                Slog.i(TAG, "setDisabled(): changing to " + disabled);
                final long caller = Binder.clearCallingIdentity();
                try {
                mTemporarilyDisabled = disabled;
                    switchImplementationIfNeeded(/* force= */ false);
                } finally {
                    Binder.restoreCallingIdentity(caller);
                if (mTemporarilyDisabled) {
                    Slog.i(TAG, "setDisabled(): temporarily disabling and hiding current session");
                    try {
                        hideCurrentSession();
                    } catch (RemoteException e) {
                        Log.w(TAG, "Failed to call hideCurrentSession", e);
                    }
                } else {
                    Slog.i(TAG, "setDisabled(): re-enabling");
                }
            }
        }
@@ -1508,12 +1510,20 @@ public class VoiceInteractionManagerService extends SystemService {
        public boolean showSessionForActiveService(Bundle args, int sourceFlags,
                IVoiceInteractionSessionShowCallback showCallback, IBinder activityToken) {
            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
            if (DEBUG_USER) Slog.d(TAG, "showSessionForActiveService()");

            synchronized (this) {
                if (mImpl == null) {
                    Slog.w(TAG, "showSessionForActiveService without running voice interaction"
                            + "service");
                    return false;
                }
                if (mTemporarilyDisabled) {
                    Slog.i(TAG, "showSessionForActiveService(): ignored while temporarily "
                            + "disabled");
                    return false;
                }

                final long caller = Binder.clearCallingIdentity();
                try {
                    return mImpl.showSessionLocked(args,
@@ -1530,7 +1540,7 @@ public class VoiceInteractionManagerService extends SystemService {
        @Override
        public void hideCurrentSession() throws RemoteException {
            enforceCallingPermission(Manifest.permission.ACCESS_VOICE_INTERACTION_SERVICE);
            synchronized (this) {

            if (mImpl == null) {
                return;
            }
@@ -1547,7 +1557,6 @@ public class VoiceInteractionManagerService extends SystemService {
                Binder.restoreCallingIdentity(caller);
            }
        }
        }

        @Override
        public void launchVoiceAssistFromKeyguard() {
+1 −0
Original line number Diff line number Diff line
@@ -71,6 +71,7 @@ final class VoiceInteractionManagerServiceShellCommand extends ShellCommand {
            pw.println("");
            pw.println("  hide");
            pw.println("    Hides the current session");
            pw.println("");
            pw.println("  disable [true|false]");
            pw.println("    Temporarily disable (when true) service");
            pw.println("");