summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2015-03-16 17:15:53 -0700
committerDianne Hackborn <hackbod@google.com>2015-03-17 16:45:51 -0700
commit27eac1d58fe0b7ca3a2e27f5ed64eff232745f45 (patch)
treec1f0dc2a368ab1c7db1be81dc02b020eea0d1628
parent7438f814f16ff1ced53d93a2fe9e3973490f3843 (diff)
downloadframeworks_base-27eac1d58fe0b7ca3a2e27f5ed64eff232745f45.zip
frameworks_base-27eac1d58fe0b7ca3a2e27f5ed64eff232745f45.tar.gz
frameworks_base-27eac1d58fe0b7ca3a2e27f5ed64eff232745f45.tar.bz2
Add ability to get a screenshot for assist.
New flag you pass in to startSession() to say you want it, new callback on VoiceInteractionSession to receive it. Change-Id: I61fdcfdee41a60d46036a2ef16681a9b4181115a
-rw-r--r--Android.mk1
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--core/java/android/service/voice/IVoiceInteractionSession.aidl2
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java8
-rw-r--r--core/java/android/service/voice/VoiceInteractionSession.java21
-rw-r--r--core/java/android/view/IWindowManager.aidl9
-rw-r--r--core/java/com/android/internal/app/IAssistScreenshotReceiver.aidl24
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java75
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java100
-rw-r--r--tests/VoiceInteraction/res/layout/voice_interaction_session.xml9
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java1
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java2
-rw-r--r--tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java17
15 files changed, 212 insertions, 65 deletions
diff --git a/Android.mk b/Android.mk
index 84cad4e..30318d6 100644
--- a/Android.mk
+++ b/Android.mk
@@ -263,6 +263,7 @@ LOCAL_SRC_FILES += \
core/java/android/speech/tts/ITextToSpeechService.aidl \
core/java/com/android/internal/app/IAppOpsCallback.aidl \
core/java/com/android/internal/app/IAppOpsService.aidl \
+ core/java/com/android/internal/app/IAssistScreenshotReceiver.aidl \
core/java/com/android/internal/app/IBatteryStats.aidl \
core/java/com/android/internal/app/IProcessStats.aidl \
core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl \
diff --git a/api/current.txt b/api/current.txt
index e72e5c8..ac9af57 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -27886,6 +27886,7 @@ package android.service.voice {
field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService";
field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction";
field public static final int START_WITH_ASSIST = 1; // 0x1
+ field public static final int START_WITH_SCREENSHOT = 2; // 0x2
}
public abstract class VoiceInteractionSession implements android.view.KeyEvent.Callback {
@@ -27909,6 +27910,7 @@ package android.service.voice {
method public void onDestroy();
method public boolean[] onGetSupportedCommands(android.service.voice.VoiceInteractionSession.Caller, java.lang.String[]);
method public void onHandleAssist(android.os.Bundle);
+ method public void onHandleScreenshot(android.graphics.Bitmap);
method public void onHide();
method public boolean onKeyDown(int, android.view.KeyEvent);
method public boolean onKeyLongPress(int, android.view.KeyEvent);
diff --git a/api/system-current.txt b/api/system-current.txt
index 5139b4b..552df4d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -29770,6 +29770,7 @@ package android.service.voice {
field public static final java.lang.String SERVICE_INTERFACE = "android.service.voice.VoiceInteractionService";
field public static final java.lang.String SERVICE_META_DATA = "android.voice_interaction";
field public static final int START_WITH_ASSIST = 1; // 0x1
+ field public static final int START_WITH_SCREENSHOT = 2; // 0x2
}
public abstract class VoiceInteractionSession implements android.view.KeyEvent.Callback {
@@ -29793,6 +29794,7 @@ package android.service.voice {
method public void onDestroy();
method public boolean[] onGetSupportedCommands(android.service.voice.VoiceInteractionSession.Caller, java.lang.String[]);
method public void onHandleAssist(android.os.Bundle);
+ method public void onHandleScreenshot(android.graphics.Bitmap);
method public void onHide();
method public boolean onKeyDown(int, android.view.KeyEvent);
method public boolean onKeyLongPress(int, android.view.KeyEvent);
diff --git a/core/java/android/service/voice/IVoiceInteractionSession.aidl b/core/java/android/service/voice/IVoiceInteractionSession.aidl
index 797457a..4f4b2d5 100644
--- a/core/java/android/service/voice/IVoiceInteractionSession.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionSession.aidl
@@ -17,6 +17,7 @@
package android.service.voice;
import android.content.Intent;
+import android.graphics.Bitmap;
import android.os.Bundle;
/**
@@ -26,6 +27,7 @@ oneway interface IVoiceInteractionSession {
void show(in Bundle sessionArgs, int flags);
void hide();
void handleAssist(in Bundle assistData);
+ void handleScreenshot(in Bitmap screenshot);
void taskStarted(in Intent intent, int taskId);
void taskFinished(in Intent intent, int taskId);
void closeSystemDialogs();
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 0c01b25..419b92b 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -71,11 +71,17 @@ public class VoiceInteractionService extends Service {
public static final String SERVICE_META_DATA = "android.voice_interaction";
/**
- * Flag for use with {@link #showSession: request that the session be started with
+ * Flag for use with {@link #showSession}: request that the session be started with
* assist data from the currently focused activity.
*/
public static final int START_WITH_ASSIST = 1<<0;
+ /**
+ * Flag for use with {@link #showSession}: request that the session be started with
+ * a screen shot of the currently focused activity.
+ */
+ public static final int START_WITH_SCREENSHOT = 1<<1;
+
IVoiceInteractionService mInterface = new IVoiceInteractionService.Stub() {
@Override public void ready() {
mHandler.sendEmptyMessage(MSG_READY);
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 11eaa06..7a5bb90 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -22,6 +22,7 @@ import android.app.VoiceInteractor;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
+import android.graphics.Bitmap;
import android.graphics.Rect;
import android.graphics.Region;
import android.inputmethodservice.SoftInputWindow;
@@ -179,6 +180,12 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback {
}
@Override
+ public void handleScreenshot(Bitmap screenshot) {
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_HANDLE_SCREENSHOT,
+ screenshot));
+ }
+
+ @Override
public void taskStarted(Intent intent, int taskId) {
mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIO(MSG_TASK_STARTED,
taskId, intent));
@@ -323,8 +330,9 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback {
static final int MSG_CLOSE_SYSTEM_DIALOGS = 102;
static final int MSG_DESTROY = 103;
static final int MSG_HANDLE_ASSIST = 104;
- static final int MSG_SHOW = 105;
- static final int MSG_HIDE = 106;
+ static final int MSG_HANDLE_SCREENSHOT = 105;
+ static final int MSG_SHOW = 106;
+ static final int MSG_HIDE = 107;
class MyCallbacks implements HandlerCaller.Callback, SoftInputWindow.Callback {
@Override
@@ -396,9 +404,13 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback {
doDestroy();
break;
case MSG_HANDLE_ASSIST:
- if (DEBUG) Log.d(TAG, "onHandleAssist: " + (Bundle)msg.obj);
+ if (DEBUG) Log.d(TAG, "onHandleAssist: " + msg.obj);
onHandleAssist((Bundle) msg.obj);
break;
+ case MSG_HANDLE_SCREENSHOT:
+ if (DEBUG) Log.d(TAG, "onHandleScreenshot: " + msg.obj);
+ onHandleScreenshot((Bitmap) msg.obj);
+ break;
case MSG_SHOW:
if (DEBUG) Log.d(TAG, "doShow: args=" + msg.obj
+ " flags=" + msg.arg1);
@@ -768,6 +780,9 @@ public abstract class VoiceInteractionSession implements KeyEvent.Callback {
public void onHandleAssist(Bundle assistBundle) {
}
+ public void onHandleScreenshot(Bitmap screenshot) {
+ }
+
public boolean onKeyDown(int keyCode, KeyEvent event) {
return false;
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 8ac8bc5..d6625c8 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -16,6 +16,7 @@
package android.view;
+import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -220,10 +221,14 @@ interface IWindowManager
boolean isRotationFrozen();
/**
+ * Used only for assist -- request a screenshot of the current application.
+ */
+ boolean requestAssistScreenshot(IAssistScreenshotReceiver receiver);
+
+ /**
* Create a screenshot of the applications currently displayed.
*/
- Bitmap screenshotApplications(IBinder appToken, int displayId, int maxWidth,
- int maxHeight, boolean force565);
+ Bitmap screenshotApplications(IBinder appToken, int displayId, int maxWidth, int maxHeight);
/**
* Called by the status bar to notify Views of changes to System UI visiblity.
diff --git a/core/java/com/android/internal/app/IAssistScreenshotReceiver.aidl b/core/java/com/android/internal/app/IAssistScreenshotReceiver.aidl
new file mode 100644
index 0000000..a987a16
--- /dev/null
+++ b/core/java/com/android/internal/app/IAssistScreenshotReceiver.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.app;
+
+import android.graphics.Bitmap;
+
+/** @hide */
+oneway interface IAssistScreenshotReceiver {
+ void send(in Bitmap screenshot);
+}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 4bb265d..b102a07 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -132,8 +132,6 @@ final class ActivityStack {
// convertToTranslucent().
static final long TRANSLUCENT_CONVERSION_TIMEOUT = 2000;
- static final boolean SCREENSHOT_FORCE_565 = ActivityManager.isLowRamDeviceStatic();
-
enum ActivityState {
INITIALIZING,
RESUMED,
@@ -790,7 +788,7 @@ final class ActivityStack {
if (w > 0) {
if (DEBUG_SCREENSHOTS) Slog.d(TAG, "\tTaking screenshot");
return mWindowManager.screenshotApplications(who.appToken, Display.DEFAULT_DISPLAY,
- w, h, SCREENSHOT_FORCE_565);
+ w, h);
}
Slog.e(TAG, "Invalid thumbnail dimensions: " + w + "x" + h);
return null;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 99bad07..9a97a2d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -29,6 +29,7 @@ import android.view.IWindowId;
import android.view.IWindowSessionCallback;
import android.view.WindowContentFrameStats;
+import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.view.IInputContext;
@@ -38,6 +39,7 @@ import com.android.internal.view.WindowManagerPolicyThread;
import com.android.server.AttributeCache;
import com.android.server.DisplayThread;
import com.android.server.EventLogTags;
+import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.UiThread;
import com.android.server.Watchdog;
@@ -5997,26 +5999,57 @@ public class WindowManagerService extends IWindowManager.Stub
* Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
* In portrait mode, it grabs the upper region of the screen based on the vertical dimension
* of the target image.
+ */
+ @Override
+ public boolean requestAssistScreenshot(final IAssistScreenshotReceiver receiver) {
+ if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,
+ "requestAssistScreenshot()")) {
+ throw new SecurityException("Requires READ_FRAME_BUFFER permission");
+ }
+
+ FgThread.getHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ Bitmap bm = screenshotApplicationsInner(null, Display.DEFAULT_DISPLAY, -1, -1,
+ true);
+ try {
+ receiver.send(bm);
+ } catch (RemoteException e) {
+ }
+ }
+ });
+
+ return true;
+ }
+
+ /**
+ * Takes a snapshot of the screen. In landscape mode this grabs the whole screen.
+ * In portrait mode, it grabs the upper region of the screen based on the vertical dimension
+ * of the target image.
*
* @param displayId the Display to take a screenshot of.
* @param width the width of the target bitmap
* @param height the height of the target bitmap
- * @param force565 if true the returned bitmap will be RGB_565, otherwise it
- * will be the same config as the surface
*/
@Override
- public Bitmap screenshotApplications(IBinder appToken, int displayId, int width,
- int height, boolean force565) {
+ public Bitmap screenshotApplications(IBinder appToken, int displayId, int width, int height) {
if (!checkCallingPermission(Manifest.permission.READ_FRAME_BUFFER,
"screenshotApplications()")) {
throw new SecurityException("Requires READ_FRAME_BUFFER permission");
}
+ return screenshotApplicationsInner(appToken, displayId, width, height, false);
+ }
- final DisplayContent displayContent = getDisplayContentLocked(displayId);
- if (displayContent == null) {
- if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
- + ": returning null. No Display for displayId=" + displayId);
- return null;
+ Bitmap screenshotApplicationsInner(IBinder appToken, int displayId, int width, int height,
+ boolean includeFullDisplay) {
+ final DisplayContent displayContent;
+ synchronized(mWindowMap) {
+ displayContent = getDisplayContentLocked(displayId);
+ if (displayContent == null) {
+ if (DEBUG_SCREENSHOT) Slog.i(TAG, "Screenshot of " + appToken
+ + ": returning null. No Display for displayId=" + displayId);
+ return null;
+ }
}
final DisplayInfo displayInfo = displayContent.getDisplayInfo();
int dw = displayInfo.logicalWidth;
@@ -6033,9 +6066,6 @@ public class WindowManagerService extends IWindowManager.Stub
final Rect frame = new Rect();
final Rect stackBounds = new Rect();
- float scale = 0;
- int rot = Surface.ROTATION_0;
-
boolean screenshotReady;
int minLayer;
if (appToken == null) {
@@ -6116,7 +6146,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
// Don't include wallpaper in bounds calculation
- if (!ws.mIsWallpaper) {
+ if (!includeFullDisplay && !ws.mIsWallpaper) {
final Rect wf = ws.mFrame;
final Rect cr = ws.mContentInsets;
int left = wf.left + cr.left;
@@ -6170,8 +6200,21 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
- // Constrain frame to the screen size.
- frame.intersect(0, 0, dw, dh);
+ if (!includeFullDisplay) {
+ // Constrain frame to the screen size.
+ frame.intersect(0, 0, dw, dh);
+ } else {
+ // Caller just wants entire display.
+ frame.set(0, 0, dw, dh);
+ }
+
+
+ if (width < 0) {
+ width = frame.width();
+ }
+ if (height < 0) {
+ height = frame.height();
+ }
// Tell surface flinger what part of the image to crop. Take the top
// right part of the application, and crop the larger dimension to fit.
@@ -6185,7 +6228,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
// The screenshot API does not apply the current screen rotation.
- rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
+ int rot = getDefaultDisplayContentLocked().getDisplay().getRotation();
if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
rot = (rot == Surface.ROTATION_90) ? Surface.ROTATION_270 : Surface.ROTATION_90;
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 30d97b9..7a379c2 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -26,6 +26,7 @@ import android.content.ContentProvider;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
+import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -39,6 +40,7 @@ import android.service.voice.VoiceInteractionService;
import android.util.Slog;
import android.view.IWindowManager;
import android.view.WindowManager;
+import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.os.IResultReceiver;
@@ -70,6 +72,8 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
IVoiceInteractor mInteractor;
boolean mHaveAssistData;
Bundle mAssistData;
+ boolean mHaveScreenshot;
+ Bitmap mScreenshot;
public interface Callback {
public void sessionConnectionGone(VoiceInteractionSessionConnection connection);
@@ -91,7 +95,20 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
if (mShown) {
mHaveAssistData = true;
mAssistData = resultData;
- deliverAssistData();
+ deliverSessionDataLocked();
+ }
+ }
+ }
+ };
+
+ final IAssistScreenshotReceiver mScreenshotReceiver = new IAssistScreenshotReceiver.Stub() {
+ @Override
+ public void send(Bitmap screenshot) throws RemoteException {
+ synchronized (mLock) {
+ if (mShown) {
+ mHaveScreenshot = true;
+ mScreenshot = screenshot;
+ deliverSessionDataLocked();
}
}
}
@@ -144,6 +161,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mShown = true;
mShowArgs = args;
mShowFlags = flags;
+ mHaveAssistData = false;
if ((flags&VoiceInteractionService.START_WITH_ASSIST) != 0) {
try {
mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
@@ -151,9 +169,17 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
} catch (RemoteException e) {
}
} else {
- mHaveAssistData = false;
mAssistData = null;
}
+ mHaveScreenshot = false;
+ if ((flags&VoiceInteractionService.START_WITH_SCREENSHOT) != 0) {
+ try {
+ mIWindowManager.requestAssistScreenshot(mScreenshotReceiver);
+ } catch (RemoteException e) {
+ }
+ } else {
+ mScreenshot = null;
+ }
if (mSession != null) {
try {
mSession.show(mShowArgs, mShowFlags);
@@ -161,7 +187,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mShowFlags = 0;
} catch (RemoteException e) {
}
- deliverAssistData();
+ deliverSessionDataLocked();
}
return true;
}
@@ -210,39 +236,50 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
}
}
- void deliverAssistData() {
- if (mSession == null || !mHaveAssistData) {
+ void deliverSessionDataLocked() {
+ if (mSession == null) {
return;
}
- if (mAssistData != null) {
- int uid = mAssistData.getInt(Intent.EXTRA_ASSIST_UID, -1);
- if (uid >= 0) {
- Bundle assistContext = mAssistData.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
- if (assistContext != null) {
- AssistContent content = AssistContent.getAssistContent(assistContext);
- if (content != null) {
- Intent intent = content.getIntent();
- if (intent != null) {
- ClipData data = intent.getClipData();
- if (data != null && Intent.isAccessUriMode(intent.getFlags())) {
- grantClipDataPermissions(data, intent.getFlags(), uid,
- mCallingUid, mSessionComponentName.getPackageName());
+ if (mHaveAssistData) {
+ if (mAssistData != null) {
+ int uid = mAssistData.getInt(Intent.EXTRA_ASSIST_UID, -1);
+ if (uid >= 0) {
+ Bundle assistContext = mAssistData.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
+ if (assistContext != null) {
+ AssistContent content = AssistContent.getAssistContent(assistContext);
+ if (content != null) {
+ Intent intent = content.getIntent();
+ if (intent != null) {
+ ClipData data = intent.getClipData();
+ if (data != null && Intent.isAccessUriMode(intent.getFlags())) {
+ grantClipDataPermissions(data, intent.getFlags(), uid,
+ mCallingUid, mSessionComponentName.getPackageName());
+ }
+ }
+ ClipData data = content.getClipData();
+ if (data != null) {
+ grantClipDataPermissions(data,
+ Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ uid, mCallingUid, mSessionComponentName.getPackageName());
}
- }
- ClipData data = content.getClipData();
- if (data != null) {
- grantClipDataPermissions(data, Intent.FLAG_GRANT_READ_URI_PERMISSION,
- uid, mCallingUid, mSessionComponentName.getPackageName());
}
}
}
}
- }
- try {
- mSession.handleAssist(mAssistData);
+ try {
+ mSession.handleAssist(mAssistData);
+ } catch (RemoteException e) {
+ }
mAssistData = null;
mHaveAssistData = false;
- } catch (RemoteException e) {
+ }
+ if (mHaveScreenshot) {
+ try {
+ mSession.handleScreenshot(mScreenshot);
+ } catch (RemoteException e) {
+ }
+ mScreenshot = null;
+ mHaveScreenshot = false;
}
}
@@ -288,14 +325,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mShowFlags = 0;
} catch (RemoteException e) {
}
- if (mHaveAssistData) {
- try {
- session.handleAssist(mAssistData);
- mAssistData = null;
- mHaveAssistData = false;
- } catch (RemoteException e) {
- }
- }
+ deliverSessionDataLocked();
}
return true;
}
diff --git a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
index 1057176..d44afb0 100644
--- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
+++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
@@ -26,7 +26,7 @@
android:layout_height="match_parent"
android:fitsSystemWindows="true">
- <FrameLayout android:id="@+id/top_content"
+ <LinearLayout android:id="@+id/top_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
@@ -34,15 +34,16 @@
android:background="#ffffffff"
android:elevation="8dp"
>
-
<Button android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top|right"
android:text="@string/start"
/>
-
- </FrameLayout>
+ <ImageView android:id="@+id/screenshot"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ </LinearLayout>
<LinearLayout android:id="@+id/bottom_content"
android:layout_width="match_parent"
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
index bae19a6..2ad23ed 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
@@ -55,6 +55,7 @@ public class AssistVisualizer extends View {
buildTextRects(window, 0, 0);
}
}
+ invalidate();
}
public void clearAssistData() {
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index 722b0de..15196b4 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -79,7 +79,7 @@ public class MainInteractionService extends VoiceInteractionService {
Bundle args = new Bundle();
args.putParcelable("intent", new Intent(this, TestInteractionActivity.class));
args.putBundle("assist", intent.getExtras());
- startSession(args, START_WITH_ASSIST);
+ startSession(args, START_WITH_ASSIST|START_WITH_SCREENSHOT);
} else {
Log.w(TAG, "Not starting -- not current voice interaction service");
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index ad339be..bc18ca9 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -21,11 +21,13 @@ import android.app.AssistStructure;
import android.app.VoiceInteractor;
import android.content.Context;
import android.content.Intent;
+import android.graphics.Bitmap;
import android.os.Bundle;
import android.service.voice.VoiceInteractionSession;
import android.util.Log;
import android.view.View;
import android.widget.Button;
+import android.widget.ImageView;
import android.widget.TextView;
public class MainInteractionSession extends VoiceInteractionSession
@@ -39,6 +41,7 @@ public class MainInteractionSession extends VoiceInteractionSession
View mBottomContent;
TextView mText;
Button mStartButton;
+ ImageView mScreenshot;
Button mConfirmButton;
Button mCompleteButton;
Button mAbortButton;
@@ -76,6 +79,7 @@ public class MainInteractionSession extends VoiceInteractionSession
if (mAssistVisualizer != null) {
mAssistVisualizer.clearAssistData();
}
+ onHandleScreenshot(null);
updateState();
}
@@ -101,6 +105,7 @@ public class MainInteractionSession extends VoiceInteractionSession
mText = (TextView)mContentView.findViewById(R.id.text);
mStartButton = (Button)mContentView.findViewById(R.id.start);
mStartButton.setOnClickListener(this);
+ mScreenshot = (ImageView)mContentView.findViewById(R.id.screenshot);
mConfirmButton = (Button)mContentView.findViewById(R.id.confirm);
mConfirmButton.setOnClickListener(this);
mCompleteButton = (Button)mContentView.findViewById(R.id.complete);
@@ -119,6 +124,18 @@ 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);
+ } else {
+ mScreenshot.setImageDrawable(null);
+ }
+ }
+
void parseAssistData(Bundle assistBundle) {
if (assistBundle != null) {
Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT);