Fix cleanup of voice sessions.
They would leave active voice activities lingering around.
Change-Id: I5b6716ab303636ebdf2f13c3172552a73dae3bb1
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 9e10e3d..1b2b08f 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -319,6 +319,15 @@
return true;
}
+ case FINISH_VOICE_TASK_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IVoiceInteractionSession session = IVoiceInteractionSession.Stub.asInterface(
+ data.readStrongBinder());
+ finishVoiceTask(session);
+ reply.writeNoException();
+ return true;
+ }
+
case WILL_ACTIVITY_BE_VISIBLE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -2468,6 +2477,16 @@
reply.recycle();
return res;
}
+ public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(session.asBinder());
+ mRemote.transact(FINISH_VOICE_TASK_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
public boolean willActivityBeVisible(IBinder token) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 01977fe..931903b 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -90,6 +90,7 @@
throws RemoteException;
public void finishSubActivity(IBinder token, String resultWho, int requestCode) throws RemoteException;
public boolean finishActivityAffinity(IBinder token) throws RemoteException;
+ public void finishVoiceTask(IVoiceInteractionSession session) throws RemoteException;
public boolean willActivityBeVisible(IBinder token) throws RemoteException;
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter,
@@ -749,4 +750,5 @@
int GET_APP_TASKS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+220;
int START_LOCK_TASK_BY_CURRENT = IBinder.FIRST_CALL_TRANSACTION+221;
int STOP_LOCK_TASK_BY_CURRENT = IBinder.FIRST_CALL_TRANSACTION+222;
+ int FINISH_VOICE_TASK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+223;
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 12f406f..6474047 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3892,6 +3892,19 @@
}
@Override
+ public void finishVoiceTask(IVoiceInteractionSession session) {
+ synchronized(this) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ mStackSupervisor.finishVoiceTask(session);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ }
+
+ @Override
public boolean willActivityBeVisible(IBinder token) {
synchronized(this) {
ActivityStack stack = ActivityRecord.getStackLocked(token);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 5442f83..545423b 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2497,6 +2497,27 @@
}
}
+ final void finishVoiceTask(IVoiceInteractionSession session) {
+ IBinder sessionBinder = session.asBinder();
+ boolean didOne = false;
+ for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+ TaskRecord tr = mTaskHistory.get(taskNdx);
+ if (tr.voiceSession != null && tr.voiceSession.asBinder() == sessionBinder) {
+ for (int activityNdx = tr.mActivities.size() - 1; activityNdx >= 0; --activityNdx) {
+ ActivityRecord r = tr.mActivities.get(activityNdx);
+ if (!r.finishing) {
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, "finish-voice",
+ false);
+ didOne = true;
+ }
+ }
+ }
+ }
+ if (didOne) {
+ mService.updateOomAdjLocked();
+ }
+ }
+
final boolean finishActivityAffinityLocked(ActivityRecord r) {
ArrayList<ActivityRecord> activities = r.task.mActivities;
for (int index = activities.indexOf(r); index >= 0; --index) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 15bae9b..c4423de 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2256,6 +2256,17 @@
}
}
+ void finishVoiceTask(IVoiceInteractionSession session) {
+ for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
+ final ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
+ final int numStacks = stacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = stacks.get(stackNdx);
+ stack.finishVoiceTask(session);
+ }
+ }
+ }
+
void findTaskToMoveToFrontLocked(TaskRecord task, int flags, Bundle options) {
if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
mUserLeaving = true;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 62ff121..8d96fb3 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -150,6 +150,12 @@
Slog.w(TAG, "Voice interation session already dead");
}
}
+ if (mSession != null) {
+ try {
+ mAm.finishVoiceTask(mSession);
+ } catch (RemoteException e) {
+ }
+ }
mContext.unbindService(this);
try {
mIWindowManager.removeWindowToken(mToken);