Prevent showing voice session when it is already queued to be hidden.

- It is possible for the session to be requested to be hidden before it
  gets the message to be shown and completes showing. This leads to an
  inconsistency where the voice interaction service implementation will be
  in a different state than the system for the session. Instead, we can
  cancel any pending show messages, and also clean up the pending show
  callback list immediately when the session is hidden.
- Also fixing up some error message codes when starting the assistant
  activity.

Bug: 38379130
Test: android.server.cts.ActivityManagerAssistantStackTests
Test: CtsVoiceInteractionTestCases
Test: CtsAlarmClockTestCases
Change-Id: I0d0e9c024367a47bda82d6a29ca89e18b7d69527
This commit is contained in:
Winson Chung
2017-06-01 15:35:48 -07:00
parent 4e73123c52
commit fc3ec4c5e6
5 changed files with 26 additions and 2 deletions

View File

@@ -300,6 +300,19 @@ public class ActivityManager {
*/
public static final int START_INTENT_NOT_RESOLVED = FIRST_START_FATAL_ERROR_CODE + 9;
/**
* Result for IActivityManager.startAssistantActivity: active session is currently hidden.
* @hide
*/
public static final int START_ASSISTANT_HIDDEN_SESSION = FIRST_START_FATAL_ERROR_CODE + 10;
/**
* Result for IActivityManager.startAssistantActivity: active session does not match
* the requesting token.
* @hide
*/
public static final int START_ASSISTANT_NOT_ACTIVE_SESSION = FIRST_START_FATAL_ERROR_CODE + 11;
/**
* Result for IActivityManaqer.startActivity: the activity was started
* successfully as normal.

View File

@@ -1953,6 +1953,12 @@ public class Instrumentation {
case ActivityManager.START_VOICE_HIDDEN_SESSION:
throw new IllegalStateException(
"Cannot start voice activity on a hidden session");
case ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION:
throw new IllegalStateException(
"Session calling startAssistantActivity does not match active session");
case ActivityManager.START_ASSISTANT_HIDDEN_SESSION:
throw new IllegalStateException(
"Cannot start assistant activity on a hidden session");
case ActivityManager.START_CANCELED:
throw new AndroidRuntimeException("Activity could not be started for "
+ intent);

View File

@@ -235,6 +235,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall
@Override
public void hide() {
// Remove any pending messages to show the session
mHandlerCaller.removeMessages(MSG_SHOW);
mHandlerCaller.sendMessage(mHandlerCaller.obtainMessage(MSG_HIDE));
}

View File

@@ -16,6 +16,8 @@
package com.android.server.voiceinteraction;
import static android.app.ActivityManager.START_ASSISTANT_HIDDEN_SESSION;
import static android.app.ActivityManager.START_ASSISTANT_NOT_ACTIVE_SESSION;
import static android.app.ActivityManager.START_VOICE_HIDDEN_SESSION;
import static android.app.ActivityManager.START_VOICE_NOT_ACTIVE_SESSION;
@@ -212,11 +214,11 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
try {
if (mActiveSession == null || token != mActiveSession.mToken) {
Slog.w(TAG, "startAssistantActivity does not match active session");
return START_VOICE_NOT_ACTIVE_SESSION;
return START_ASSISTANT_NOT_ACTIVE_SESSION;
}
if (!mActiveSession.mShown) {
Slog.w(TAG, "startAssistantActivity not allowed on hidden session");
return START_VOICE_HIDDEN_SESSION;
return START_ASSISTANT_HIDDEN_SESSION;
}
intent = new Intent(intent);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

View File

@@ -453,6 +453,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mShowFlags = 0;
mHaveAssistData = false;
mAssistData.clear();
mPendingShowCallbacks.clear();
if (mSession != null) {
try {
mSession.hide();