From e30e02f5d9a9141c9ee70c712d4f9d52c88ea969 Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Tue, 27 May 2014 18:24:45 -0700 Subject: Add system layer for voice interaction services. New window layer that voice interaction service windows go in to. Includes a new voice-specific content rectangle that voice activities are placed in to. Add specific animations for this layer, sliding down from the top (though this can be customized by the voice interaction service). Also add the concept of activities running for voice interaction services for purposes of adjusting the animation used for them, again sliding from the top, but not (yet?) customizable by the voice interaction service. Change-Id: Ic9e0e8c843c2e2972d6abb4087dce0019326155d --- .../java/com/android/server/am/ActivityStack.java | 6 +-- .../android/server/am/ActivityStackSupervisor.java | 2 +- .../java/com/android/server/wm/AppTransition.java | 48 ++++++++++++++++++---- .../java/com/android/server/wm/AppWindowToken.java | 8 +++- .../android/server/wm/WindowManagerService.java | 35 +++++++++++----- .../java/com/android/server/wm/WindowState.java | 5 +++ .../com/android/server/wm/WindowStateAnimator.java | 2 +- .../VoiceInteractionManagerServiceImpl.java | 2 +- 8 files changed, 81 insertions(+), 27 deletions(-) (limited to 'services') diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index a0440cb..8f60b03 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1860,7 +1860,7 @@ final class ActivityStack { mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, - r.userId, r.info.configChanges); + r.userId, r.info.configChanges, task.voiceSession != null); if (VALIDATE_TOKENS) { validateAppTokensLocked(); } @@ -1921,7 +1921,7 @@ final class ActivityStack { mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId, - r.info.configChanges); + r.info.configChanges, task.voiceSession != null); boolean doShow = true; if (newTask) { // Even though this activity is starting fresh, we still need @@ -1966,7 +1966,7 @@ final class ActivityStack { mWindowManager.addAppToken(task.mActivities.indexOf(r), r.appToken, r.task.taskId, mStackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, r.userId, - r.info.configChanges); + r.info.configChanges, task.voiceSession != null); ActivityOptions.abort(options); options = null; } diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index ae7fab3..6d20a32 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2290,7 +2290,7 @@ public final class ActivityStackSupervisor implements DisplayListener { mWindowManager.addAppToken(0, r.appToken, taskId, stackId, r.info.screenOrientation, r.fullscreen, (r.info.flags & ActivityInfo.FLAG_SHOW_ON_LOCK_SCREEN) != 0, - r.userId, r.info.configChanges); + r.userId, r.info.configChanges, task.voiceSession != null); } mWindowManager.addTask(taskId, stackId, false); } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index e2d2ac6..4f8b9d7 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -24,9 +24,7 @@ import android.graphics.Rect; import android.os.Debug; import android.os.Handler; import android.os.IRemoteCallback; -import android.os.SystemProperties; import android.util.Slog; -import android.view.View; import android.view.WindowManager; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; @@ -299,7 +297,7 @@ public class AppTransition implements Dump { return null; } - Animation loadAnimation(WindowManager.LayoutParams lp, int animAttr) { + Animation loadAnimationAttr(WindowManager.LayoutParams lp, int animAttr) { int anim = 0; Context context = mContext; if (animAttr >= 0) { @@ -315,7 +313,19 @@ public class AppTransition implements Dump { return null; } - private Animation loadAnimation(String packageName, int resId) { + Animation loadAnimationRes(WindowManager.LayoutParams lp, int resId) { + Context context = mContext; + if (resId >= 0) { + AttributeCache.Entry ent = getCachedAnimations(lp); + if (ent != null) { + context = ent.context; + } + return AnimationUtils.loadAnimation(context, resId); + } + return null; + } + + private Animation loadAnimationRes(String packageName, int resId) { int anim = 0; Context context = mContext; if (resId >= 0) { @@ -695,11 +705,31 @@ public class AppTransition implements Dump { Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter, - int appWidth, int appHeight, int orientation, - Rect containingFrame, Rect contentInsets, boolean isFullScreen) { + int appWidth, int appHeight, int orientation, Rect containingFrame, Rect contentInsets, + boolean isFullScreen, boolean isVoiceInteraction) { Animation a; - if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { - a = loadAnimation(mNextAppTransitionPackage, enter ? + if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_OPEN + || transit == TRANSIT_TASK_OPEN + || transit == TRANSIT_TASK_TO_FRONT)) { + a = loadAnimationRes(lp, enter + ? com.android.internal.R.anim.voice_activity_open_enter + : com.android.internal.R.anim.voice_activity_open_exit); + if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, + "applyAnimation voice:" + + " anim=" + a + " transit=" + transit + " isEntrance=" + enter + + " Callers=" + Debug.getCallers(3)); + } else if (isVoiceInteraction && (transit == TRANSIT_ACTIVITY_CLOSE + || transit == TRANSIT_TASK_CLOSE + || transit == TRANSIT_TASK_TO_BACK)) { + a = loadAnimationRes(lp, enter + ? com.android.internal.R.anim.voice_activity_close_enter + : com.android.internal.R.anim.voice_activity_close_exit); + if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, + "applyAnimation voice:" + + " anim=" + a + " transit=" + transit + " isEntrance=" + enter + + " Callers=" + Debug.getCallers(3)); + } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CUSTOM) { + a = loadAnimationRes(mNextAppTransitionPackage, enter ? mNextAppTransitionEnter : mNextAppTransitionExit); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" @@ -782,7 +812,7 @@ public class AppTransition implements Dump { : WindowAnimation_wallpaperIntraCloseExitAnimation; break; } - a = animAttr != 0 ? loadAnimation(lp, animAttr) : null; + a = animAttr != 0 ? loadAnimationAttr(lp, animAttr) : null; if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG, "applyAnimation:" + " anim=" + a diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index ca4ad8a..12c15e2 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -50,6 +50,8 @@ class AppWindowToken extends WindowToken { final WindowAnimator mAnimator; + final boolean voiceInteraction; + int groupId = -1; boolean appFullscreen; int requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED; @@ -107,11 +109,13 @@ class AppWindowToken extends WindowToken { boolean mDeferRemoval; - AppWindowToken(WindowManagerService _service, IApplicationToken _token) { + AppWindowToken(WindowManagerService _service, IApplicationToken _token, + boolean _voiceInteraction) { super(_service, _token.asBinder(), WindowManager.LayoutParams.TYPE_APPLICATION, true); appWindowToken = this; appToken = _token; + voiceInteraction = _voiceInteraction; mInputApplicationHandle = new InputApplicationHandle(this); mAnimator = service.mAnimator; mAppAnimator = new AppWindowAnimator(this); @@ -249,7 +253,7 @@ class AppWindowToken extends WindowToken { void dump(PrintWriter pw, String prefix) { super.dump(pw, prefix); if (appToken != null) { - pw.print(prefix); pw.println("app=true"); + pw.print(prefix); pw.print("app=true voiceInteraction="); pw.println(voiceInteraction); } if (allAppWindows.size() > 0) { pw.print(prefix); pw.print("allAppWindows="); pw.println(allAppWindows); diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index c23d1ea..68fface 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -2215,6 +2215,11 @@ public class WindowManagerService extends IWindowManager.Stub + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } + if (type == TYPE_VOICE_INTERACTION) { + Slog.w(TAG, "Attempted to add voice interaction window with unknown token " + + attrs.token + ". Aborting."); + return WindowManagerGlobal.ADD_BAD_APP_TOKEN; + } if (type == TYPE_WALLPAPER) { Slog.w(TAG, "Attempted to add wallpaper window with unknown token " + attrs.token + ". Aborting."); @@ -2250,6 +2255,12 @@ public class WindowManagerService extends IWindowManager.Stub + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } + } else if (type == TYPE_VOICE_INTERACTION) { + if (token.windowType != TYPE_VOICE_INTERACTION) { + Slog.w(TAG, "Attempted to add voice interaction window with bad token " + + attrs.token + ". Aborting."); + return WindowManagerGlobal.ADD_BAD_APP_TOKEN; + } } else if (type == TYPE_WALLPAPER) { if (token.windowType != TYPE_WALLPAPER) { Slog.w(TAG, "Attempted to add wallpaper window with bad token " @@ -3173,7 +3184,7 @@ public class WindowManagerService extends IWindowManager.Stub } private boolean applyAnimationLocked(AppWindowToken atoken, - WindowManager.LayoutParams lp, int transit, boolean enter) { + WindowManager.LayoutParams lp, int transit, boolean enter, boolean isVoiceInteraction) { // Only apply an animation if the display isn't frozen. If it is // frozen, there is no reason to animate and it can cause strange // artifacts when we unfreeze the display if some different animation @@ -3203,7 +3214,8 @@ public class WindowManagerService extends IWindowManager.Stub } Animation a = mAppTransition.loadAnimation(lp, transit, enter, width, height, - mCurConfiguration.orientation, containingFrame, contentInsets, isFullScreen); + mCurConfiguration.orientation, containingFrame, contentInsets, isFullScreen, + isVoiceInteraction); if (a != null) { if (DEBUG_ANIM) { RuntimeException e = null; @@ -3423,7 +3435,7 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void addAppToken(int addPos, IApplicationToken token, int taskId, int stackId, int requestedOrientation, boolean fullscreen, boolean showWhenLocked, int userId, - int configChanges) { + int configChanges, boolean voiceInteraction) { if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS, "addAppToken()")) { throw new SecurityException("Requires MANAGE_APP_TOKENS permission"); @@ -3449,7 +3461,7 @@ public class WindowManagerService extends IWindowManager.Stub Slog.w(TAG, "Attempted to add existing app token: " + token); return; } - atoken = new AppWindowToken(this, token); + atoken = new AppWindowToken(this, token, voiceInteraction); atoken.inputDispatchingTimeoutNanos = inputDispatchingTimeoutNanos; atoken.groupId = taskId; atoken.appFullscreen = fullscreen; @@ -4201,7 +4213,7 @@ public class WindowManagerService extends IWindowManager.Stub } boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp, - boolean visible, int transit, boolean performLayout) { + boolean visible, int transit, boolean performLayout, boolean isVoiceInteraction) { boolean delayed = false; if (wtoken.clientHidden == visible) { @@ -4222,7 +4234,7 @@ public class WindowManagerService extends IWindowManager.Stub if (wtoken.mAppAnimator.animation == AppWindowAnimator.sDummyAnimation) { wtoken.mAppAnimator.animation = null; } - if (applyAnimationLocked(wtoken, lp, transit, visible)) { + if (applyAnimationLocked(wtoken, lp, transit, visible, isVoiceInteraction)) { delayed = runningAppAnimation = true; } WindowState window = wtoken.findMainWindow(); @@ -4400,7 +4412,7 @@ public class WindowManagerService extends IWindowManager.Stub final long origId = Binder.clearCallingIdentity(); setTokenVisibilityLocked(wtoken, null, visible, AppTransition.TRANSIT_UNSET, - true); + true, wtoken.voiceInteraction); wtoken.updateReportedVisibilityLocked(); Binder.restoreCallingIdentity(origId); } @@ -4547,7 +4559,7 @@ public class WindowManagerService extends IWindowManager.Stub if (basewtoken != null && (wtoken=basewtoken.appWindowToken) != null) { if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Removing app token: " + wtoken); delayed = setTokenVisibilityLocked(wtoken, null, false, - AppTransition.TRANSIT_UNSET, true); + AppTransition.TRANSIT_UNSET, true, wtoken.voiceInteraction); wtoken.inPendingTransaction = false; mOpeningApps.remove(wtoken); wtoken.waitingToShow = false; @@ -8528,6 +8540,7 @@ public class WindowManagerService extends IWindowManager.Stub LayoutParams animLp = null; int bestAnimLayer = -1; boolean fullscreenAnim = false; + boolean voiceInteraction = false; if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "New wallpaper target=" + mWallpaperTarget @@ -8572,6 +8585,8 @@ public class WindowManagerService extends IWindowManager.Stub } } + voiceInteraction |= wtoken.voiceInteraction; + if (wtoken.appFullscreen) { WindowState ws = wtoken.findMainWindow(); if (ws != null) { @@ -8644,7 +8659,7 @@ public class WindowManagerService extends IWindowManager.Stub appAnimator.clearThumbnail(); wtoken.inPendingTransaction = false; appAnimator.animation = null; - setTokenVisibilityLocked(wtoken, animLp, true, transit, false); + setTokenVisibilityLocked(wtoken, animLp, true, transit, false, voiceInteraction); wtoken.updateReportedVisibilityLocked(); wtoken.waitingToShow = false; @@ -8676,7 +8691,7 @@ public class WindowManagerService extends IWindowManager.Stub wtoken.mAppAnimator.clearThumbnail(); wtoken.inPendingTransaction = false; wtoken.mAppAnimator.animation = null; - setTokenVisibilityLocked(wtoken, animLp, false, transit, false); + setTokenVisibilityLocked(wtoken, animLp, false, transit, false, voiceInteraction); wtoken.updateReportedVisibilityLocked(); wtoken.waitingToHide = false; // Force the allDrawn flag, because we want to start diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index c88382c..4a80e3e 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -714,6 +714,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mAppToken != null ? mAppToken.appToken : null; } + @Override + public boolean isVoiceInteraction() { + return mAppToken != null ? mAppToken.voiceInteraction : false; + } + boolean setInsetsChanged() { mOverscanInsetsChanged |= !mLastOverscanInsets.equals(mOverscanInsets); mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets); diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 1e79dcb..e257ebc 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -1658,7 +1658,7 @@ class WindowStateAnimator { break; } if (attr >= 0) { - a = mService.mAppTransition.loadAnimation(mWin.mAttrs, attr); + a = mService.mAppTransition.loadAnimationAttr(mWin.mAttrs, attr); } } if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG, diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java index 9b6daad..62ff121 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java @@ -113,7 +113,7 @@ class VoiceInteractionManagerServiceImpl { if (mBound) { try { mIWindowManager.addWindowToken(mToken, - WindowManager.LayoutParams.TYPE_INPUT_METHOD); + WindowManager.LayoutParams.TYPE_VOICE_INTERACTION); } catch (RemoteException e) { Slog.w(TAG, "Failed adding window token", e); } -- cgit v1.1