VoiceInteraction: Handle session delivery failure.

When the system connects to the VoiceInteractionSessionService, it
requests the service to create a new session. The service then delivers
this session to the system. Currently, a failure to deliver it is just
ignored, and the service continues to initialize the session. This
silently leaves the session in an invalid state where operations with it
always fail (since the system doesn't recognize the session).

There's currently a concurrency bug in the system server that causes the
session delivery to fail occasionally. Even with that fixed though, it's
good to handle unexpected errors here.

Fix: 178776751
Test: atest CtsVoiceInteractionTestCases --iterations
Change-Id: I3489db108158fa7c71179bee3d098ecd4ab6b2bd
This commit is contained in:
Ahaan Ugale
2021-01-23 21:20:45 -08:00
parent a20b10345d
commit 4d8bb5d015
2 changed files with 20 additions and 5 deletions

View File

@@ -18,8 +18,6 @@ package android.service.voice;
import android.os.Bundle;
import android.service.voice.IVoiceInteractionSession;
/**
* @hide
*/

View File

@@ -21,11 +21,14 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import com.android.internal.app.IVoiceInteractionManagerService;
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
@@ -38,6 +41,8 @@ import java.io.PrintWriter;
*/
public abstract class VoiceInteractionSessionService extends Service {
private static final String TAG = "VoiceInteractionSession";
static final int MSG_NEW_SESSION = 1;
IVoiceInteractionManagerService mSystemService;
@@ -120,10 +125,22 @@ public abstract class VoiceInteractionSessionService extends Service {
mSession = null;
}
mSession = onNewSession(args);
try {
mSystemService.deliverNewSession(token, mSession.mSession, mSession.mInteractor);
if (deliverSession(token)) {
mSession.doCreate(mSystemService, token);
} catch (RemoteException e) {
} else {
// TODO(b/178777121): Add an onError() method to let the application know what happened.
mSession.doDestroy();
mSession = null;
}
}
private boolean deliverSession(IBinder token) {
try {
return mSystemService.deliverNewSession(token, mSession.mSession, mSession.mInteractor);
} catch (DeadObjectException ignored) {
} catch (RemoteException e) {
Log.e(TAG, "Failed to deliver session: " + e);
}
return false;
}
}