diff options
author | Dianne Hackborn <hackbod@google.com> | 2017-02-06 17:42:41 -0800 |
---|---|---|
committer | Dianne Hackborn <hackbod@google.com> | 2017-02-08 14:00:31 -0800 |
commit | 59da805846034a4939b014f469d7383285c75aab (patch) | |
tree | bb287efa2b69314fe4f86bf674a97979a7c20ab8 | |
parent | bf99f78a3827af8cbcb394c7dd42d83915c2b551 (diff) |
Add new VoiceInteractionSession.setUiEnabled method
This allows the session to turn off all of its UI. Use it
in onCreate() to prevent the session from ever creating any
of its UI. Switched the window creation and initialization to
happen lazily to support this.
Test: New test added to android.assist.cts.LifecycleTest
Bug: 30999386
Change-Id: I8eacb3697c8ac9908c50b9577abea2d20597b016
-rw-r--r-- | api/current.txt | 2 | ||||
-rw-r--r-- | api/system-current.txt | 2 | ||||
-rw-r--r-- | api/test-current.txt | 2 | ||||
-rw-r--r-- | core/java/android/service/voice/VoiceInteractionSession.java | 138 | ||||
-rw-r--r-- | tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java | 31 |
5 files changed, 124 insertions, 51 deletions
diff --git a/api/current.txt b/api/current.txt index de5486907589..d86748b3480c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -36758,6 +36758,7 @@ package android.service.voice { method public boolean onKeyUp(int, android.view.KeyEvent); method public void onLockscreenShown(); method public void onLowMemory(); + method public void onPrepareShow(android.os.Bundle, int); method public void onRequestAbortVoice(android.service.voice.VoiceInteractionSession.AbortVoiceRequest); method public void onRequestCommand(android.service.voice.VoiceInteractionSession.CommandRequest); method public void onRequestCompleteVoice(android.service.voice.VoiceInteractionSession.CompleteVoiceRequest); @@ -36771,6 +36772,7 @@ package android.service.voice { method public void setDisabledShowContext(int); method public void setKeepAwake(boolean); method public void setTheme(int); + method public void setUiEnabled(boolean); method public void show(android.os.Bundle, int); method public void startVoiceActivity(android.content.Intent); field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10 diff --git a/api/system-current.txt b/api/system-current.txt index bdf06db863fc..4b361d6f72fc 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -39856,6 +39856,7 @@ package android.service.voice { method public boolean onKeyUp(int, android.view.KeyEvent); method public void onLockscreenShown(); method public void onLowMemory(); + method public void onPrepareShow(android.os.Bundle, int); method public void onRequestAbortVoice(android.service.voice.VoiceInteractionSession.AbortVoiceRequest); method public void onRequestCommand(android.service.voice.VoiceInteractionSession.CommandRequest); method public void onRequestCompleteVoice(android.service.voice.VoiceInteractionSession.CompleteVoiceRequest); @@ -39869,6 +39870,7 @@ package android.service.voice { method public void setDisabledShowContext(int); method public void setKeepAwake(boolean); method public void setTheme(int); + method public void setUiEnabled(boolean); method public void show(android.os.Bundle, int); method public void startVoiceActivity(android.content.Intent); field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10 diff --git a/api/test-current.txt b/api/test-current.txt index 0f6502b6daed..3005e3222adf 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -36893,6 +36893,7 @@ package android.service.voice { method public boolean onKeyUp(int, android.view.KeyEvent); method public void onLockscreenShown(); method public void onLowMemory(); + method public void onPrepareShow(android.os.Bundle, int); method public void onRequestAbortVoice(android.service.voice.VoiceInteractionSession.AbortVoiceRequest); method public void onRequestCommand(android.service.voice.VoiceInteractionSession.CommandRequest); method public void onRequestCompleteVoice(android.service.voice.VoiceInteractionSession.CompleteVoiceRequest); @@ -36906,6 +36907,7 @@ package android.service.voice { method public void setDisabledShowContext(int); method public void setKeepAwake(boolean); method public void setTheme(int); + method public void setUiEnabled(boolean); method public void show(android.os.Bundle, int); method public void startVoiceActivity(android.content.Intent); field public static final int SHOW_SOURCE_ACTIVITY = 16; // 0x10 diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index e9bbc2de26cc..ca736e346761 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -135,6 +135,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall FrameLayout mContentFrame; SoftInputWindow mWindow; + boolean mUiEnabled = true; boolean mInitialized; boolean mWindowAdded; boolean mWindowVisible; @@ -1001,35 +1002,40 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall try { mInShowWindow = true; + onPrepareShow(args, flags); if (!mWindowVisible) { - if (!mWindowAdded) { - mWindowAdded = true; - View v = onCreateContentView(); - if (v != null) { - setContentView(v); - } - } + ensureWindowAdded(); } onShow(args, flags); if (!mWindowVisible) { mWindowVisible = true; - mWindow.show(); + if (mUiEnabled) { + mWindow.show(); + } } if (showCallback != null) { - mRootView.invalidate(); - mRootView.getViewTreeObserver().addOnPreDrawListener( - new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - mRootView.getViewTreeObserver().removeOnPreDrawListener(this); - try { - showCallback.onShown(); - } catch (RemoteException e) { - Log.w(TAG, "Error calling onShown", e); + if (mUiEnabled) { + mRootView.invalidate(); + mRootView.getViewTreeObserver().addOnPreDrawListener( + new ViewTreeObserver.OnPreDrawListener() { + @Override + public boolean onPreDraw() { + mRootView.getViewTreeObserver().removeOnPreDrawListener(this); + try { + showCallback.onShown(); + } catch (RemoteException e) { + Log.w(TAG, "Error calling onShown", e); + } + return true; } - return true; - } - }); + }); + } else { + try { + showCallback.onShown(); + } catch (RemoteException e) { + Log.w(TAG, "Error calling onShown", e); + } + } } } finally { mWindowWasVisible = true; @@ -1039,7 +1045,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall void doHide() { if (mWindowVisible) { - mWindow.hide(); + ensureWindowHidden(); mWindowVisible = false; onHide(); } @@ -1058,19 +1064,56 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } } - void initViews() { + void ensureWindowCreated() { + if (mInitialized) { + return; + } + + if (!mUiEnabled) { + throw new IllegalStateException("setUiEnabled is false"); + } + mInitialized = true; + mInflater = (LayoutInflater)mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme, + mCallbacks, this, mDispatcherState, + WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.BOTTOM, true); + mWindow.getWindow().addFlags( + WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED | + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | + WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); mThemeAttrs = mContext.obtainStyledAttributes(android.R.styleable.VoiceInteractionSession); mRootView = mInflater.inflate( com.android.internal.R.layout.voice_interaction_session, null); mRootView.setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); mWindow.setContentView(mRootView); mRootView.getViewTreeObserver().addOnComputeInternalInsetsListener(mInsetsComputer); mContentFrame = (FrameLayout)mRootView.findViewById(android.R.id.content); + + mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT); + mWindow.setToken(mToken); + } + + void ensureWindowAdded() { + if (mUiEnabled && !mWindowAdded) { + mWindowAdded = true; + ensureWindowCreated(); + View v = onCreateContentView(); + if (v != null) { + setContentView(v); + } + } + } + + void ensureWindowHidden() { + if (mWindow != null) { + mWindow.hide(); + } } /** @@ -1151,6 +1194,24 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } /** + * Control whether the UI layer for this session is enabled. It is enabled by default. + * If set to false, you will not be able to provide a UI through {@link #onCreateContentView()}. + */ + public void setUiEnabled(boolean enabled) { + if (mUiEnabled != enabled) { + mUiEnabled = enabled; + if (mWindowVisible) { + if (enabled) { + ensureWindowAdded(); + mWindow.show(); + } else { + ensureWindowHidden(); + } + } + } + } + + /** * You can call this to customize the theme used by your IME's window. * This must be set before {@link #onCreate}, so you * will typically call it in your constructor with the resource ID @@ -1242,6 +1303,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * Convenience for inflating views. */ public LayoutInflater getLayoutInflater() { + ensureWindowCreated(); return mInflater; } @@ -1249,6 +1311,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * Retrieve the window being used to show the session's UI. */ public Dialog getWindow() { + ensureWindowCreated(); return mWindow; } @@ -1278,18 +1341,17 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall private void doOnCreate() { mTheme = mTheme != 0 ? mTheme : com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession; - mInflater = (LayoutInflater)mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme, - mCallbacks, this, mDispatcherState, - WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.BOTTOM, true); - mWindow.getWindow().addFlags( - WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED | - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | - WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR); - initViews(); - mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT); - mWindow.setToken(mToken); + } + + /** + * Called prior to {@link #onShow} before any UI setup has occurred. Not generally useful. + * + * @param args The arguments that were supplied to + * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}. + * @param showFlags The show flags originally provided to + * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}. + */ + public void onPrepareShow(Bundle args, int showFlags) { } /** @@ -1327,6 +1389,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } public void setContentView(View view) { + ensureWindowCreated(); mContentFrame.removeAllViews(); mContentFrame.addView(view, new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, @@ -1623,7 +1686,8 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { writer.print(prefix); writer.print("mToken="); writer.println(mToken); writer.print(prefix); writer.print("mTheme=#"); writer.println(Integer.toHexString(mTheme)); - writer.print(prefix); writer.print("mInitialized="); writer.println(mInitialized); + writer.print(prefix); writer.print("mUiEnabled="); writer.println(mUiEnabled); + writer.print(" mInitialized="); writer.println(mInitialized); writer.print(prefix); writer.print("mWindowAdded="); writer.print(mWindowAdded); writer.print(" mWindowVisible="); writer.println(mWindowVisible); writer.print(prefix); writer.print("mWindowWasVisible="); writer.print(mWindowWasVisible); diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java index 5767f110f0a4..040173792406 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java @@ -172,12 +172,10 @@ public class MainInteractionSession extends VoiceInteractionSession @Override public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) { mAssistStructure = structure; - if (mAssistStructure != null) { - if (mAssistVisualizer != null) { + if (mAssistVisualizer != null) { + if (mAssistStructure != null) { mAssistVisualizer.setAssistStructure(mAssistStructure); - } - } else { - if (mAssistVisualizer != null) { + } else { mAssistVisualizer.clearAssistData(); } } @@ -207,19 +205,24 @@ public class MainInteractionSession extends VoiceInteractionSession @Override public void onHandleScreenshot(Bitmap screenshot) { - if (screenshot != null) { - mScreenshot.setImageBitmap(screenshot); - mScreenshot.setAdjustViewBounds(true); - mScreenshot.setMaxWidth(screenshot.getWidth() / 3); - mScreenshot.setMaxHeight(screenshot.getHeight() / 3); - mFullScreenshot.setImageBitmap(screenshot); - } else { - mScreenshot.setImageDrawable(null); - mFullScreenshot.setImageDrawable(null); + if (mScreenshot != null) { + if (screenshot != null) { + mScreenshot.setImageBitmap(screenshot); + mScreenshot.setAdjustViewBounds(true); + mScreenshot.setMaxWidth(screenshot.getWidth() / 3); + mScreenshot.setMaxHeight(screenshot.getHeight() / 3); + mFullScreenshot.setImageBitmap(screenshot); + } else { + mScreenshot.setImageDrawable(null); + mFullScreenshot.setImageDrawable(null); + } } } void updateState() { + if (mTopContent == null) { + return; + } if (mState == STATE_IDLE) { mTopContent.setVisibility(View.VISIBLE); mBottomContent.setVisibility(View.GONE); |