Fix issue #20672970: Notifications are not dismissed on hot word detection
Add new VoiceInteractionSession.closeSystemDialogs() API that closes
everything except the session itself.
Change-Id: If45f1e120d8ca095b6c8055b6485acb5e710820e
diff --git a/api/current.txt b/api/current.txt
index 3ae5372..61a952c 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -28807,6 +28807,7 @@
public class VoiceInteractionSession implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback {
ctor public VoiceInteractionSession(android.content.Context);
ctor public VoiceInteractionSession(android.content.Context, android.os.Handler);
+ method public void closeSystemDialogs();
method public void finish();
method public android.content.Context getContext();
method public android.view.LayoutInflater getLayoutInflater();
diff --git a/api/system-current.txt b/api/system-current.txt
index 8a633df..7a4b137 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -30961,6 +30961,7 @@
public class VoiceInteractionSession implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback {
ctor public VoiceInteractionSession(android.content.Context);
ctor public VoiceInteractionSession(android.content.Context, android.os.Handler);
+ method public void closeSystemDialogs();
method public void finish();
method public android.content.Context getContext();
method public android.view.LayoutInflater getLayoutInflater();
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 7eb936a..a7e0e08 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -1001,6 +1001,21 @@
}
/**
+ * Request that all system dialogs (and status bar shade etc) be closed, allowing
+ * access to the session's UI. This will <em>not</em> cause the lock screen to be
+ * dismissed.
+ */
+ public void closeSystemDialogs() {
+ if (mToken == null) {
+ throw new IllegalStateException("Can't call before onCreate()");
+ }
+ try {
+ mSystemService.closeSystemDialogs(mToken);
+ } catch (RemoteException e) {
+ }
+ }
+
+ /**
* Convenience for inflating views.
*/
public LayoutInflater getLayoutInflater() {
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index a2bd700..8cd9bab 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -35,6 +35,7 @@
boolean hideSessionFromSession(IBinder token);
int startVoiceActivity(IBinder token, in Intent intent, String resolvedType);
void setKeepAwake(IBinder token, boolean keepAwake);
+ void closeSystemDialogs(IBinder token);
void finish(IBinder token);
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 959fd37..c7fbc76 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18,9 +18,7 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
-import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
-import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index cde87bd..61ae1c0 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -545,6 +545,24 @@
}
@Override
+ public void closeSystemDialogs(IBinder token) {
+ synchronized (this) {
+ if (mImpl == null) {
+ Slog.w(TAG, "closeSystemDialogs without running voice interaction service");
+ return;
+ }
+ final int callingPid = Binder.getCallingPid();
+ final int callingUid = Binder.getCallingUid();
+ final long caller = Binder.clearCallingIdentity();
+ try {
+ mImpl.closeSystemDialogsLocked(callingPid, callingUid, token);
+ } finally {
+ Binder.restoreCallingIdentity(caller);
+ }
+ }
+ }
+
+ @Override
public void finish(IBinder token) {
synchronized (this) {
if (mImpl == null) {
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index af0ddbe..e5faf4d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -48,6 +48,8 @@
class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConnection.Callback {
final static String TAG = "VoiceInteractionServiceManager";
+ final static String CLOSE_REASON_VOICE_INTERACTION = "voiceinteraction";
+
final boolean mValid;
final Context mContext;
@@ -68,11 +70,14 @@
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
- synchronized (mLock) {
- if (mActiveSession != null && mActiveSession.mSession != null) {
- try {
- mActiveSession.mSession.closeSystemDialogs();
- } catch (RemoteException e) {
+ String reason = intent.getStringExtra("reason");
+ if (!CLOSE_REASON_VOICE_INTERACTION.equals(reason)) {
+ synchronized (mLock) {
+ if (mActiveSession != null && mActiveSession.mSession != null) {
+ try {
+ mActiveSession.mSession.closeSystemDialogs();
+ } catch (RemoteException e) {
+ }
}
}
}
@@ -196,6 +201,18 @@
}
}
+ public void closeSystemDialogsLocked(int callingPid, int callingUid, IBinder token) {
+ try {
+ if (mActiveSession == null || token != mActiveSession.mToken) {
+ Slog.w(TAG, "closeSystemDialogs does not match active session");
+ return;
+ }
+ mAm.closeSystemDialogs(CLOSE_REASON_VOICE_INTERACTION);
+ } catch (RemoteException e) {
+ throw new IllegalStateException("Unexpected remote error", e);
+ }
+ }
+
public void finishLocked(IBinder token) {
if (mActiveSession == null || token != mActiveSession.mToken) {
Slog.w(TAG, "finish does not match active session");