Merge "Implement latest Material focus states spec"
diff --git a/api/current.txt b/api/current.txt
index d1b6ba0..3034650 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3696,6 +3696,7 @@
}
public class ActivityOptions {
+ method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int);
method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.view.View, java.lang.String);
@@ -3937,6 +3938,7 @@
public final class AssistData implements android.os.Parcelable {
method public int describeContents();
+ method public android.content.ComponentName getActivityComponent();
method public static android.app.AssistData getAssistData(android.os.Bundle);
method public void getWindowAt(int, android.app.AssistData.ViewNode);
method public int getWindowCount();
@@ -12069,7 +12071,10 @@
public class RippleDrawable extends android.graphics.drawable.LayerDrawable {
ctor public RippleDrawable(android.content.res.ColorStateList, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ method public int getRadius();
method public void setColor(android.content.res.ColorStateList);
+ method public void setRadius(int);
+ field public static final int RADIUS_AUTO = -1; // 0xffffffff
}
public class RotateDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
@@ -27530,6 +27535,7 @@
field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
+ field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
}
@@ -27644,9 +27650,10 @@
method public android.os.IBinder onBind(android.content.Intent);
method public void onReady();
method public void onShutdown();
- method public void startSession(android.os.Bundle);
+ method public void startSession(android.os.Bundle, int);
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
}
public abstract class VoiceInteractionSession implements android.view.KeyEvent.Callback {
@@ -27664,10 +27671,11 @@
method public void onCompleteVoice(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle);
method public void onComputeInsets(android.service.voice.VoiceInteractionSession.Insets);
method public abstract void onConfirm(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle);
- method public void onCreate(android.os.Bundle);
+ method public void onCreate(android.os.Bundle, int);
method public android.view.View onCreateContentView();
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 boolean onKeyDown(int, android.view.KeyEvent);
method public boolean onKeyLongPress(int, android.view.KeyEvent);
method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
@@ -37781,6 +37789,7 @@
ctor public CompoundButton(android.content.Context, android.util.AttributeSet);
ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int);
ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int, int);
+ method public android.graphics.drawable.Drawable getButtonDrawable();
method public android.content.res.ColorStateList getButtonTintList();
method public android.graphics.PorterDuff.Mode getButtonTintMode();
method public boolean isChecked();
diff --git a/api/system-current.txt b/api/system-current.txt
index fd6e2c8..567ff3e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3784,6 +3784,7 @@
}
public class ActivityOptions {
+ method public static android.app.ActivityOptions makeClipRevealAnimation(android.view.View, int, int, int, int);
method public static android.app.ActivityOptions makeCustomAnimation(android.content.Context, int, int);
method public static android.app.ActivityOptions makeScaleUpAnimation(android.view.View, int, int, int, int);
method public static android.app.ActivityOptions makeSceneTransitionAnimation(android.app.Activity, android.view.View, java.lang.String);
@@ -4027,6 +4028,7 @@
public final class AssistData implements android.os.Parcelable {
method public int describeContents();
+ method public android.content.ComponentName getActivityComponent();
method public static android.app.AssistData getAssistData(android.os.Bundle);
method public void getWindowAt(int, android.app.AssistData.ViewNode);
method public int getWindowCount();
@@ -12343,7 +12345,10 @@
public class RippleDrawable extends android.graphics.drawable.LayerDrawable {
ctor public RippleDrawable(android.content.res.ColorStateList, android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ method public int getRadius();
method public void setColor(android.content.res.ColorStateList);
+ method public void setRadius(int);
+ field public static final int RADIUS_AUTO = -1; // 0xffffffff
}
public class RotateDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Drawable.Callback {
@@ -29171,6 +29176,7 @@
field public static final int INTERRUPTION_FILTER_ALL = 1; // 0x1
field public static final int INTERRUPTION_FILTER_NONE = 3; // 0x3
field public static final int INTERRUPTION_FILTER_PRIORITY = 2; // 0x2
+ field public static final int INTERRUPTION_FILTER_UNKNOWN = 0; // 0x0
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationListenerService";
field public static final int TRIM_FULL = 0; // 0x0
field public static final int TRIM_LIGHT = 1; // 0x1
@@ -29331,9 +29337,10 @@
method public android.os.IBinder onBind(android.content.Intent);
method public void onReady();
method public void onShutdown();
- method public void startSession(android.os.Bundle);
+ method public void startSession(android.os.Bundle, int);
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
}
public abstract class VoiceInteractionSession implements android.view.KeyEvent.Callback {
@@ -29351,10 +29358,11 @@
method public void onCompleteVoice(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle);
method public void onComputeInsets(android.service.voice.VoiceInteractionSession.Insets);
method public abstract void onConfirm(android.service.voice.VoiceInteractionSession.Caller, android.service.voice.VoiceInteractionSession.Request, java.lang.CharSequence, android.os.Bundle);
- method public void onCreate(android.os.Bundle);
+ method public void onCreate(android.os.Bundle, int);
method public android.view.View onCreateContentView();
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 boolean onKeyDown(int, android.view.KeyEvent);
method public boolean onKeyLongPress(int, android.view.KeyEvent);
method public boolean onKeyMultiple(int, int, android.view.KeyEvent);
@@ -40238,6 +40246,7 @@
ctor public CompoundButton(android.content.Context, android.util.AttributeSet);
ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int);
ctor public CompoundButton(android.content.Context, android.util.AttributeSet, int, int);
+ method public android.graphics.drawable.Drawable getButtonDrawable();
method public android.content.res.ColorStateList getButtonTintList();
method public android.graphics.PorterDuff.Mode getButtonTintMode();
method public boolean isChecked();
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 47f57ea..fa10893 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -51,6 +51,7 @@
import android.util.Log;
import android.util.Singleton;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.os.IResultReceiver;
import java.util.ArrayList;
import java.util.List;
@@ -2114,6 +2115,15 @@
return true;
}
+ case REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int requestType = data.readInt();
+ IResultReceiver receiver = IResultReceiver.Stub.asInterface(data.readStrongBinder());
+ requestAssistContextExtras(requestType, receiver);
+ reply.writeNoException();
+ return true;
+ }
+
case REPORT_ASSIST_CONTEXT_EXTRAS_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -5146,6 +5156,19 @@
return res;
}
+ public void requestAssistContextExtras(int requestType, IResultReceiver receiver)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(requestType);
+ data.writeStrongBinder(receiver.asBinder());
+ mRemote.transact(REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
public void reportAssistContextExtras(IBinder token, Bundle extras)
throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/ActivityOptions.java b/core/java/android/app/ActivityOptions.java
index 39ae65c..8909b28 100644
--- a/core/java/android/app/ActivityOptions.java
+++ b/core/java/android/app/ActivityOptions.java
@@ -140,6 +140,8 @@
public static final int ANIM_THUMBNAIL_ASPECT_SCALE_DOWN = 9;
/** @hide */
public static final int ANIM_CUSTOM_IN_PLACE = 10;
+ /** @hide */
+ public static final int ANIM_CLIP_REVEAL = 11;
private String mPackageName;
private int mAnimationType = ANIM_NONE;
@@ -291,6 +293,33 @@
}
/**
+ * Create an ActivityOptions specifying an animation where the new
+ * activity is revealed from a small originating area of the screen to
+ * its final full representation.
+ *
+ * @param source The View that the new activity is animating from. This
+ * defines the coordinate space for <var>startX</var> and <var>startY</var>.
+ * @param startX The x starting location of the new activity, relative to <var>source</var>.
+ * @param startY The y starting location of the activity, relative to <var>source</var>.
+ * @param width The initial width of the new activity.
+ * @param height The initial height of the new activity.
+ * @return Returns a new ActivityOptions object that you can use to
+ * supply these options as the options Bundle when starting an activity.
+ */
+ public static ActivityOptions makeClipRevealAnimation(View source,
+ int startX, int startY, int width, int height) {
+ ActivityOptions opts = new ActivityOptions();
+ opts.mAnimationType = ANIM_CLIP_REVEAL;
+ int[] pts = new int[2];
+ source.getLocationOnScreen(pts);
+ opts.mStartX = pts[0] + startX;
+ opts.mStartY = pts[1] + startY;
+ opts.mWidth = width;
+ opts.mHeight = height;
+ return opts;
+ }
+
+ /**
* Create an ActivityOptions specifying an animation where a thumbnail
* is scaled from a given position to the new activity window that is
* being started.
@@ -582,6 +611,7 @@
break;
case ANIM_SCALE_UP:
+ case ANIM_CLIP_REVEAL:
mStartX = opts.getInt(KEY_ANIM_START_X, 0);
mStartY = opts.getInt(KEY_ANIM_START_Y, 0);
mWidth = opts.getInt(KEY_ANIM_WIDTH, 0);
@@ -809,6 +839,7 @@
b.putInt(KEY_ANIM_IN_PLACE_RES_ID, mCustomInPlaceResId);
break;
case ANIM_SCALE_UP:
+ case ANIM_CLIP_REVEAL:
b.putInt(KEY_ANIM_START_X, mStartX);
b.putInt(KEY_ANIM_START_Y, mStartY);
b.putInt(KEY_ANIM_WIDTH, mWidth);
diff --git a/core/java/android/app/AssistData.java b/core/java/android/app/AssistData.java
index 8d3d348..7b5eb6d 100644
--- a/core/java/android/app/AssistData.java
+++ b/core/java/android/app/AssistData.java
@@ -16,6 +16,7 @@
package android.app;
+import android.content.ComponentName;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Parcel;
@@ -44,6 +45,8 @@
*/
public static final String ASSIST_KEY = "android:assist";
+ final ComponentName mActivityComponent;
+
final ArrayList<ViewNodeImpl> mRootViews = new ArrayList<>();
ViewAssistDataImpl mTmpViewAssistDataImpl = new ViewAssistDataImpl();
@@ -400,6 +403,7 @@
}
AssistData(Activity activity) {
+ mActivityComponent = activity.getComponentName();
ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews(
activity.getActivityToken());
for (int i=0; i<views.size(); i++) {
@@ -414,6 +418,7 @@
}
AssistData(Parcel in) {
+ mActivityComponent = ComponentName.readFromParcel(in);
final int N = in.readInt();
for (int i=0; i<N; i++) {
mRootViews.add(new ViewNodeImpl(in));
@@ -421,7 +426,9 @@
//dump();
}
- void dump() {
+ /** @hide */
+ public void dump() {
+ Log.i(TAG, "Activity: " + mActivityComponent.flattenToShortString());
ViewNode node = new ViewNode();
final int N = getWindowCount();
for (int i=0; i<N; i++) {
@@ -445,7 +452,7 @@
}
String text = node.getText();
if (text != null) {
- Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-"
+ Log.i(TAG, prefix + " Text (sel " + node.getTextSelectionStart() + "-"
+ node.getTextSelectionEnd() + "): " + text);
}
String hint = node.getHint();
@@ -476,6 +483,10 @@
return assistBundle.getParcelable(ASSIST_KEY);
}
+ public ComponentName getActivityComponent() {
+ return mActivityComponent;
+ }
+
/**
* Return the number of window contents that have been collected in this assist data.
*/
@@ -498,6 +509,7 @@
public void writeToParcel(Parcel out, int flags) {
int start = out.dataPosition();
+ ComponentName.writeToParcel(mActivityComponent, out);
final int N = mRootViews.size();
out.writeInt(N);
for (int i=0; i<N; i++) {
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 467c99a..341a2d7 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -51,6 +51,7 @@
import android.os.StrictMode;
import android.service.voice.IVoiceInteractionSession;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.os.IResultReceiver;
import java.util.List;
@@ -419,6 +420,9 @@
public Bundle getAssistContextExtras(int requestType) throws RemoteException;
+ public void requestAssistContextExtras(int requestType, IResultReceiver receiver)
+ throws RemoteException;
+
public void reportAssistContextExtras(IBinder token, Bundle extras) throws RemoteException;
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle)
@@ -804,4 +808,5 @@
int CREATE_STACK_ON_DISPLAY = IBinder.FIRST_CALL_TRANSACTION+281;
int GET_FOCUSED_STACK_ID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+282;
int SET_TASK_RESIZEABLE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+283;
+ int REQUEST_ASSIST_CONTEXT_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+284;
}
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index fa5ac42..d410622 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -1039,10 +1039,10 @@
protected void dump(final FileDescriptor fd, PrintWriter pw, final String[] args) {
DumpUtils.dumpAsync(mHandler, new Dump() {
@Override
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, String prefix) {
dumpOnHandler(fd, pw, args);
}
- }, pw, 1000);
+ }, pw, "", 1000);
}
/** @hide */
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index 3d39b18..0860153 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -77,6 +77,14 @@
*/
public static final int INTERRUPTION_FILTER_NONE = 3;
+ /** {@link #getCurrentInterruptionFilter() Interruption filter} constant - returned when
+ * the value is unavailable for any reason. For example, before the notification listener
+ * is connected.
+ *
+ * {@see #onListenerConnected()}
+ */
+ public static final int INTERRUPTION_FILTER_UNKNOWN = 0;
+
/** {@link #getCurrentListenerHints() Listener hints} constant - the primary device UI
* should disable notification sound, vibrating and other visual or aural effects.
* This does not change the interruption filter, only the effects. **/
@@ -473,15 +481,16 @@
* <p>
* Listen for updates using {@link #onInterruptionFilterChanged(int)}.
*
- * @return One of the INTERRUPTION_FILTER_ constants, or 0 on errors.
+ * @return One of the INTERRUPTION_FILTER_ constants, or INTERRUPTION_FILTER_UNKNOWN when
+ * unavailable.
*/
public final int getCurrentInterruptionFilter() {
- if (!isBound()) return 0;
+ if (!isBound()) return INTERRUPTION_FILTER_UNKNOWN;
try {
return getNotificationInterface().getInterruptionFilterFromListener(mWrapper);
} catch (android.os.RemoteException ex) {
Log.v(TAG, "Unable to contact notification manager", ex);
- return 0;
+ return INTERRUPTION_FILTER_UNKNOWN;
}
}
diff --git a/core/java/android/service/voice/IVoiceInteractionSession.aidl b/core/java/android/service/voice/IVoiceInteractionSession.aidl
index 9f9c312..a8c0c4c 100644
--- a/core/java/android/service/voice/IVoiceInteractionSession.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionSession.aidl
@@ -17,11 +17,13 @@
package android.service.voice;
import android.content.Intent;
+import android.os.Bundle;
/**
* @hide
*/
oneway interface IVoiceInteractionSession {
+ void handleAssist(in Bundle assistData);
void taskStarted(in Intent intent, int taskId);
void taskFinished(in Intent intent, int taskId);
void closeSystemDialogs();
diff --git a/core/java/android/service/voice/IVoiceInteractionSessionService.aidl b/core/java/android/service/voice/IVoiceInteractionSessionService.aidl
index 2519442..7f8158f 100644
--- a/core/java/android/service/voice/IVoiceInteractionSessionService.aidl
+++ b/core/java/android/service/voice/IVoiceInteractionSessionService.aidl
@@ -24,5 +24,5 @@
* @hide
*/
oneway interface IVoiceInteractionSessionService {
- void newSession(IBinder token, in Bundle args);
+ void newSession(IBinder token, in Bundle args, int startFlags);
}
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index 65e6988..54a3a0a 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -70,6 +70,12 @@
*/
public static final String SERVICE_META_DATA = "android.voice_interaction";
+ /**
+ * Flag for use with {@link #startSession}: request that the session be started with
+ * assist data from the currently focused activity.
+ */
+ public static final int START_WITH_ASSIST = 1<<0;
+
IVoiceInteractionService mInterface = new IVoiceInteractionService.Stub() {
@Override public void ready() {
mHandler.sendEmptyMessage(MSG_READY);
@@ -136,16 +142,21 @@
* Initiate the execution of a new {@link android.service.voice.VoiceInteractionSession}.
* @param args Arbitrary arguments that will be propagated to the session.
*/
- public void startSession(Bundle args) {
+ public void startSession(Bundle args, int flags) {
if (mSystemService == null) {
throw new IllegalStateException("Not available until onReady() is called");
}
try {
- mSystemService.startSession(mInterface, args);
+ mSystemService.startSession(mInterface, args, flags);
} catch (RemoteException e) {
}
}
+ /** @hide */
+ public void startSession(Bundle args) {
+ startSession(args, 0);
+ }
+
@Override
public void onCreate() {
super.onCreate();
@@ -163,8 +174,8 @@
/**
* Called during service initialization to tell you when the system is ready
* to receive interaction from it. You should generally do initialization here
- * rather than in {@link #onCreate()}. Methods such as {@link #startSession(Bundle)} and
- * {@link #createAlwaysOnHotwordDetector(String, Locale, android.service.voice.AlwaysOnHotwordDetector.Callback)}
+ * rather than in {@link #onCreate}. Methods such as {@link #startSession} and
+ * {@link #createAlwaysOnHotwordDetector}
* will not be operational until this point.
*/
public void onReady() {
diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
index e6e9413..ebc7507 100644
--- a/core/java/android/service/voice/VoiceInteractionServiceInfo.java
+++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
@@ -99,6 +99,10 @@
mParseError = "No sessionService specified";
return;
}
+ if (mRecognitionService == null) {
+ mParseError = "No recognitionService specified";
+ return;
+ }
/* Not yet time
if (mRecognitionService == null) {
mParseError = "No recogitionService specified";
diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java
index 19d14bf..a3a2ca1 100644
--- a/core/java/android/service/voice/VoiceInteractionSession.java
+++ b/core/java/android/service/voice/VoiceInteractionSession.java
@@ -50,7 +50,6 @@
import java.lang.ref.WeakReference;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
/**
* An active voice interaction session, providing a facility for the implementation
@@ -91,7 +90,6 @@
final ArrayMap<IBinder, Request> mActiveRequests = new ArrayMap<IBinder, Request>();
final Insets mTmpInsets = new Insets();
- final int[] mTmpLocation = new int[2];
final WeakReference<VoiceInteractionSession> mWeakRef
= new WeakReference<VoiceInteractionSession>(this);
@@ -153,6 +151,12 @@
final IVoiceInteractionSession mSession = new IVoiceInteractionSession.Stub() {
@Override
+ public void handleAssist(Bundle assistBundle) {
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageO(MSG_HANDLE_ASSIST,
+ assistBundle));
+ }
+
+ @Override
public void taskStarted(Intent intent, int taskId) {
mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIO(MSG_TASK_STARTED,
taskId, intent));
@@ -279,6 +283,7 @@
static final int MSG_TASK_FINISHED = 101;
static final int MSG_CLOSE_SYSTEM_DIALOGS = 102;
static final int MSG_DESTROY = 103;
+ static final int MSG_HANDLE_ASSIST = 104;
class MyCallbacks implements HandlerCaller.Callback, SoftInputWindow.Callback {
@Override
@@ -341,6 +346,10 @@
if (DEBUG) Log.d(TAG, "doDestroy");
doDestroy();
break;
+ case MSG_HANDLE_ASSIST:
+ if (DEBUG) Log.d(TAG, "onHandleAssist: " + (Bundle)msg.obj);
+ onHandleAssist((Bundle) msg.obj);
+ break;
}
}
@@ -441,10 +450,11 @@
}
}
- void doCreate(IVoiceInteractionManagerService service, IBinder token, Bundle args) {
+ void doCreate(IVoiceInteractionManagerService service, IBinder token, Bundle args,
+ int startFlags) {
mSystemService = service;
mToken = token;
- onCreate(args);
+ onCreate(args, startFlags);
}
void doDestroy() {
@@ -585,12 +595,7 @@
}
}
- /**
- * Initiatize a new session.
- *
- * @param args The arguments that were supplied to
- * {@link VoiceInteractionService#startSession VoiceInteractionService.startSession}.
- */
+ /** @hide */
public void onCreate(Bundle args) {
mTheme = mTheme != 0 ? mTheme
: com.android.internal.R.style.Theme_DeviceDefault_VoiceInteractionSession;
@@ -598,14 +603,26 @@
Context.LAYOUT_INFLATER_SERVICE);
mWindow = new SoftInputWindow(mContext, "VoiceInteractionSession", mTheme,
mCallbacks, this, mDispatcherState,
- WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.TOP, true);
+ WindowManager.LayoutParams.TYPE_VOICE_INTERACTION, Gravity.BOTTOM, true);
mWindow.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
initViews();
- mWindow.getWindow().setLayout(MATCH_PARENT, WRAP_CONTENT);
+ mWindow.getWindow().setLayout(MATCH_PARENT, MATCH_PARENT);
mWindow.setToken(mToken);
}
/**
+ * Initiatize a new session.
+ *
+ * @param args The arguments that were supplied to
+ * {@link VoiceInteractionService#startSession VoiceInteractionService.startSession}.
+ * @param startFlags The start flags originally provided to
+ * {@link VoiceInteractionService#startSession VoiceInteractionService.startSession}.
+ */
+ public void onCreate(Bundle args, int startFlags) {
+ onCreate(args);
+ }
+
+ /**
* Last callback to the session as it is being finished.
*/
public void onDestroy() {
@@ -622,10 +639,13 @@
mContentFrame.removeAllViews();
mContentFrame.addView(view, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT));
+ ViewGroup.LayoutParams.MATCH_PARENT));
}
+ public void onHandleAssist(Bundle assistBundle) {
+ }
+
public boolean onKeyDown(int keyCode, KeyEvent event) {
return false;
}
@@ -657,19 +677,19 @@
/**
* Compute the interesting insets into your UI. The default implementation
- * uses the entire window frame as the insets. The default touchable
- * insets are {@link Insets#TOUCHABLE_INSETS_FRAME}.
+ * sets {@link Insets#contentInsets outInsets.contentInsets.top} to the height
+ * of the window, meaning it should not adjust content underneath. The default touchable
+ * insets are {@link Insets#TOUCHABLE_INSETS_FRAME}, meaning it consumes all touch
+ * events within its window frame.
*
* @param outInsets Fill in with the current UI insets.
*/
public void onComputeInsets(Insets outInsets) {
- int[] loc = mTmpLocation;
- View decor = getWindow().getWindow().getDecorView();
- decor.getLocationInWindow(loc);
- outInsets.contentInsets.top = 0;
outInsets.contentInsets.left = 0;
- outInsets.contentInsets.right = 0;
outInsets.contentInsets.bottom = 0;
+ outInsets.contentInsets.right = 0;
+ View decor = getWindow().getWindow().getDecorView();
+ outInsets.contentInsets.top = decor.getHeight();
outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_FRAME;
outInsets.touchableRegion.setEmpty();
}
diff --git a/core/java/android/service/voice/VoiceInteractionSessionService.java b/core/java/android/service/voice/VoiceInteractionSessionService.java
index e793849..008d55f 100644
--- a/core/java/android/service/voice/VoiceInteractionSessionService.java
+++ b/core/java/android/service/voice/VoiceInteractionSessionService.java
@@ -40,9 +40,9 @@
VoiceInteractionSession mSession;
IVoiceInteractionSessionService mInterface = new IVoiceInteractionSessionService.Stub() {
- public void newSession(IBinder token, Bundle args) {
- mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageOO(MSG_NEW_SESSION,
- token, args));
+ public void newSession(IBinder token, Bundle args, int startFlags) {
+ mHandlerCaller.sendMessage(mHandlerCaller.obtainMessageIOO(MSG_NEW_SESSION,
+ startFlags, token, args));
}
};
@@ -54,7 +54,7 @@
SomeArgs args = (SomeArgs)msg.obj;
switch (msg.what) {
case MSG_NEW_SESSION:
- doNewSession((IBinder)args.arg1, (Bundle)args.arg2);
+ doNewSession((IBinder)args.arg1, (Bundle)args.arg2, args.argi1);
break;
}
}
@@ -76,7 +76,7 @@
return mInterface.asBinder();
}
- void doNewSession(IBinder token, Bundle args) {
+ void doNewSession(IBinder token, Bundle args, int startFlags) {
if (mSession != null) {
mSession.doDestroy();
mSession = null;
@@ -84,7 +84,7 @@
mSession = onNewSession(args);
try {
mSystemService.deliverNewSession(token, mSession.mSession, mSession.mInteractor);
- mSession.doCreate(mSystemService, token, args);
+ mSession.doCreate(mSystemService, token, args, startFlags);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 743f6b7..8ac8bc5 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -91,6 +91,8 @@
IRemoteCallback startedCallback);
void overridePendingAppTransitionScaleUp(int startX, int startY, int startWidth,
int startHeight);
+ void overridePendingAppTransitionClipReveal(int startX, int startY,
+ int startWidth, int startHeight);
void overridePendingAppTransitionThumb(in Bitmap srcThumb, int startX, int startY,
IRemoteCallback startedCallback, boolean scaleUp);
void overridePendingAppTransitionAspectScaledThumb(in Bitmap srcThumb, int startX,
diff --git a/core/java/android/view/animation/ClipRectAnimation.java b/core/java/android/view/animation/ClipRectAnimation.java
index 2361501..e194927 100644
--- a/core/java/android/view/animation/ClipRectAnimation.java
+++ b/core/java/android/view/animation/ClipRectAnimation.java
@@ -26,8 +26,8 @@
* @hide
*/
public class ClipRectAnimation extends Animation {
- private Rect mFromRect = new Rect();
- private Rect mToRect = new Rect();
+ protected Rect mFromRect = new Rect();
+ protected Rect mToRect = new Rect();
/**
* Constructor to use when building a ClipRectAnimation from code
@@ -43,6 +43,15 @@
mToRect.set(toClip);
}
+ /**
+ * Constructor to use when building a ClipRectAnimation from code
+ */
+ public ClipRectAnimation(int fromL, int fromT, int fromR, int fromB,
+ int toL, int toT, int toR, int toB) {
+ mFromRect.set(fromL, fromT, fromR, fromB);
+ mToRect.set(toL, toT, toR, toB);
+ }
+
@Override
protected void applyTransformation(float it, Transformation tr) {
int l = mFromRect.left + (int) ((mToRect.left - mFromRect.left) * it);
diff --git a/core/java/android/view/animation/ClipRectLRAnimation.java b/core/java/android/view/animation/ClipRectLRAnimation.java
new file mode 100644
index 0000000..8993cd3
--- /dev/null
+++ b/core/java/android/view/animation/ClipRectLRAnimation.java
@@ -0,0 +1,49 @@
+/*
+ * 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 android.view.animation;
+
+import android.graphics.Rect;
+
+/**
+ * Special case of ClipRectAnimation that animates only the left/right
+ * dimensions of the clip, picking up the other dimensions from whatever is
+ * set on the transform already.
+ *
+ * @hide
+ */
+public class ClipRectLRAnimation extends ClipRectAnimation {
+
+ /**
+ * Constructor. Passes in 0 for Top/Bottom parameters of ClipRectAnimation
+ */
+ public ClipRectLRAnimation(int fromL, int fromR, int toL, int toR) {
+ super(fromL, 0, fromR, 0, toL, 0, toR, 0);
+ }
+
+ /**
+ * Calculates and sets clip rect on given transformation. It uses existing values
+ * on the Transformation for Top/Bottom clip parameters.
+ */
+ @Override
+ protected void applyTransformation(float it, Transformation tr) {
+ Rect oldClipRect = tr.getClipRect();
+ tr.setClipRect(mFromRect.left + (int) ((mToRect.left - mFromRect.left) * it),
+ oldClipRect.top,
+ mFromRect.right + (int) ((mToRect.right - mFromRect.right) * it),
+ oldClipRect.bottom);
+ }
+}
diff --git a/core/java/android/view/animation/ClipRectTBAnimation.java b/core/java/android/view/animation/ClipRectTBAnimation.java
new file mode 100644
index 0000000..06f86ce
--- /dev/null
+++ b/core/java/android/view/animation/ClipRectTBAnimation.java
@@ -0,0 +1,49 @@
+/*
+ * 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 android.view.animation;
+
+import android.graphics.Rect;
+
+/**
+ * Special case of ClipRectAnimation that animates only the top/bottom
+ * dimensions of the clip, picking up the other dimensions from whatever is
+ * set on the transform already.
+ *
+ * @hide
+ */
+public class ClipRectTBAnimation extends ClipRectAnimation {
+
+ /**
+ * Constructor. Passes in 0 for Left/Right parameters of ClipRectAnimation
+ */
+ public ClipRectTBAnimation(int fromT, int fromB, int toT, int toB) {
+ super(0, fromT, 0, fromB, 0, toT, 0, toB);
+ }
+
+ /**
+ * Calculates and sets clip rect on given transformation. It uses existing values
+ * on the Transformation for Left/Right clip parameters.
+ */
+ @Override
+ protected void applyTransformation(float it, Transformation tr) {
+ Rect oldClipRect = tr.getClipRect();
+ tr.setClipRect(oldClipRect.left, mFromRect.top + (int) ((mToRect.top - mFromRect.top) * it),
+ oldClipRect.right,
+ mFromRect.bottom + (int) ((mToRect.bottom - mFromRect.bottom) * it));
+ }
+
+}
diff --git a/core/java/android/view/animation/Transformation.java b/core/java/android/view/animation/Transformation.java
index 2f4fe73..30c12ed 100644
--- a/core/java/android/view/animation/Transformation.java
+++ b/core/java/android/view/animation/Transformation.java
@@ -122,7 +122,13 @@
mAlpha *= t.getAlpha();
mMatrix.preConcat(t.getMatrix());
if (t.mHasClipRect) {
- setClipRect(t.getClipRect());
+ Rect bounds = t.getClipRect();
+ if (mHasClipRect) {
+ setClipRect(mClipRect.left + bounds.left, mClipRect.top + bounds.top,
+ mClipRect.right + bounds.right, mClipRect.bottom + bounds.bottom);
+ } else {
+ setClipRect(bounds);
+ }
}
}
@@ -135,7 +141,13 @@
mAlpha *= t.getAlpha();
mMatrix.postConcat(t.getMatrix());
if (t.mHasClipRect) {
- setClipRect(t.getClipRect());
+ Rect bounds = t.getClipRect();
+ if (mHasClipRect) {
+ setClipRect(mClipRect.left + bounds.left, mClipRect.top + bounds.top,
+ mClipRect.right + bounds.right, mClipRect.bottom + bounds.bottom);
+ } else {
+ setClipRect(bounds);
+ }
}
}
diff --git a/core/java/android/view/animation/TranslateAnimation.java b/core/java/android/view/animation/TranslateAnimation.java
index d2ff754..216022b 100644
--- a/core/java/android/view/animation/TranslateAnimation.java
+++ b/core/java/android/view/animation/TranslateAnimation.java
@@ -24,7 +24,7 @@
* An animation that controls the position of an object. See the
* {@link android.view.animation full package} description for details and
* sample code.
- *
+ *
*/
public class TranslateAnimation extends Animation {
private int mFromXType = ABSOLUTE;
@@ -33,20 +33,28 @@
private int mFromYType = ABSOLUTE;
private int mToYType = ABSOLUTE;
- private float mFromXValue = 0.0f;
- private float mToXValue = 0.0f;
+ /** @hide */
+ protected float mFromXValue = 0.0f;
+ /** @hide */
+ protected float mToXValue = 0.0f;
- private float mFromYValue = 0.0f;
- private float mToYValue = 0.0f;
+ /** @hide */
+ protected float mFromYValue = 0.0f;
+ /** @hide */
+ protected float mToYValue = 0.0f;
- private float mFromXDelta;
- private float mToXDelta;
- private float mFromYDelta;
- private float mToYDelta;
+ /** @hide */
+ protected float mFromXDelta;
+ /** @hide */
+ protected float mToXDelta;
+ /** @hide */
+ protected float mFromYDelta;
+ /** @hide */
+ protected float mToYDelta;
/**
* Constructor used when a TranslateAnimation is loaded from a resource.
- *
+ *
* @param context Application context to use
* @param attrs Attribute set from which to read values
*/
@@ -81,7 +89,7 @@
/**
* Constructor to use when building a TranslateAnimation from code
- *
+ *
* @param fromXDelta Change in X coordinate to apply at the start of the
* animation
* @param toXDelta Change in X coordinate to apply at the end of the
diff --git a/core/java/android/view/animation/TranslateXAnimation.java b/core/java/android/view/animation/TranslateXAnimation.java
new file mode 100644
index 0000000..d75323f
--- /dev/null
+++ b/core/java/android/view/animation/TranslateXAnimation.java
@@ -0,0 +1,55 @@
+/*
+ * 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 android.view.animation;
+
+import android.graphics.Matrix;
+
+/**
+ * Special case of TranslateAnimation that translates only horizontally, picking up the
+ * vertical values from whatever is set on the Transformation already. When used in
+ * conjunction with a TranslateYAnimation, allows independent animation of x and y
+ * position.
+ * @hide
+ */
+public class TranslateXAnimation extends TranslateAnimation {
+ float[] mTmpValues = new float[9];
+
+ /**
+ * Constructor. Passes in 0 for the y parameters of TranslateAnimation
+ */
+ public TranslateXAnimation(float fromXDelta, float toXDelta) {
+ super(fromXDelta, toXDelta, 0, 0);
+ }
+
+ /**
+ * Constructor. Passes in 0 for the y parameters of TranslateAnimation
+ */
+ public TranslateXAnimation(int fromXType, float fromXValue, int toXType, float toXValue) {
+ super(fromXType, fromXValue, toXType, toXValue, ABSOLUTE, 0, ABSOLUTE, 0);
+ }
+
+ /**
+ * Calculates and sets x translation values on given transformation.
+ */
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ Matrix m = t.getMatrix();
+ m.getValues(mTmpValues);
+ float dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
+ t.getMatrix().setTranslate(dx, mTmpValues[Matrix.MTRANS_Y]);
+ }
+}
diff --git a/core/java/android/view/animation/TranslateYAnimation.java b/core/java/android/view/animation/TranslateYAnimation.java
new file mode 100644
index 0000000..714558d
--- /dev/null
+++ b/core/java/android/view/animation/TranslateYAnimation.java
@@ -0,0 +1,55 @@
+/*
+ * 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 android.view.animation;
+
+import android.graphics.Matrix;
+
+/**
+ * Special case of TranslateAnimation that translates only vertically, picking up the
+ * horizontal values from whatever is set on the Transformation already. When used in
+ * conjunction with a TranslateXAnimation, allows independent animation of x and y
+ * position.
+ * @hide
+ */
+public class TranslateYAnimation extends TranslateAnimation {
+ float[] mTmpValues = new float[9];
+
+ /**
+ * Constructor. Passes in 0 for the x parameters of TranslateAnimation
+ */
+ public TranslateYAnimation(float fromYDelta, float toYDelta) {
+ super(0, 0, fromYDelta, toYDelta);
+ }
+
+ /**
+ * Constructor. Passes in 0 for the x parameters of TranslateAnimation
+ */
+ public TranslateYAnimation(int fromYType, float fromYValue, int toYType, float toYValue) {
+ super(ABSOLUTE, 0, ABSOLUTE, 0, fromYType, fromYValue, toYType, toYValue);
+ }
+
+ /**
+ * Calculates and sets y translation values on given transformation.
+ */
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ Matrix m = t.getMatrix();
+ m.getValues(mTmpValues);
+ float dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
+ t.getMatrix().setTranslate(mTmpValues[Matrix.MTRANS_X], dy);
+ }
+}
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index fede493..f2afeeb 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -16,6 +16,7 @@
package android.widget;
+import android.annotation.DrawableRes;
import android.annotation.Nullable;
import android.graphics.PorterDuff;
import com.android.internal.R;
@@ -50,7 +51,6 @@
*/
public abstract class CompoundButton extends Button implements Checkable {
private boolean mChecked;
- private int mButtonResource;
private boolean mBroadcasting;
private Drawable mButtonDrawable;
@@ -197,54 +197,62 @@
}
/**
- * Set the button graphic to a given Drawable, identified by its resource
- * id.
+ * Sets a drawable as the compound button image given its resource
+ * identifier.
*
- * @param resid the resource id of the drawable to use as the button
- * graphic
+ * @param resId the resource identifier of the drawable
+ * @attr ref android.R.styleable#CompoundButton_button
*/
- public void setButtonDrawable(int resid) {
- if (resid != 0 && resid == mButtonResource) {
- return;
- }
-
- mButtonResource = resid;
-
- Drawable d = null;
- if (mButtonResource != 0) {
- d = getContext().getDrawable(mButtonResource);
+ public void setButtonDrawable(@DrawableRes int resId) {
+ final Drawable d;
+ if (resId != 0) {
+ d = getContext().getDrawable(resId);
+ } else {
+ d = null;
}
setButtonDrawable(d);
}
/**
- * Set the button graphic to a given Drawable
+ * Sets a drawable as the compound button image.
*
- * @param d The Drawable to use as the button graphic
+ * @param drawable the drawable to set
+ * @attr ref android.R.styleable#CompoundButton_button
*/
- public void setButtonDrawable(Drawable d) {
- if (mButtonDrawable != d) {
+ @Nullable
+ public void setButtonDrawable(@Nullable Drawable drawable) {
+ if (mButtonDrawable != drawable) {
if (mButtonDrawable != null) {
mButtonDrawable.setCallback(null);
unscheduleDrawable(mButtonDrawable);
}
- mButtonDrawable = d;
+ mButtonDrawable = drawable;
- if (d != null) {
- d.setCallback(this);
- d.setLayoutDirection(getLayoutDirection());
- if (d.isStateful()) {
- d.setState(getDrawableState());
+ if (drawable != null) {
+ drawable.setCallback(this);
+ drawable.setLayoutDirection(getLayoutDirection());
+ if (drawable.isStateful()) {
+ drawable.setState(getDrawableState());
}
- d.setVisible(getVisibility() == VISIBLE, false);
- setMinHeight(d.getIntrinsicHeight());
+ drawable.setVisible(getVisibility() == VISIBLE, false);
+ setMinHeight(drawable.getIntrinsicHeight());
applyButtonTint();
}
}
}
/**
+ * @return the drawable used as the compound button image
+ * @see #setButtonDrawable(Drawable)
+ * @see #setButtonDrawable(int)
+ */
+ @Nullable
+ public Drawable getButtonDrawable() {
+ return mButtonDrawable;
+ }
+
+ /**
* Applies a tint to the button drawable. Does not modify the current tint
* mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
* <p>
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index d5166f3..4752594 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -1352,6 +1352,9 @@
searchStartIndex);
// Note how dynamic layout's internal block indices get updated from Editor
blockIndices[i] = blockIndex;
+ if (mTextDisplayLists[blockIndex] != null) {
+ mTextDisplayLists[blockIndex].isDirty = true;
+ }
searchStartIndex = blockIndex + 1;
}
@@ -1388,6 +1391,7 @@
// brings this range of text back to the top left corner of the viewport
hardwareCanvas.translate(-left, -top);
layout.drawText(hardwareCanvas, blockBeginLine, blockEndLine);
+ mTextDisplayLists[blockIndex].isDirty = false;
// No need to untranslate, previous context is popped after
// drawDisplayList
} finally {
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 5a10524..6d90420 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -26,7 +26,7 @@
import android.service.voice.IVoiceInteractionSession;
interface IVoiceInteractionManagerService {
- void startSession(IVoiceInteractionService service, in Bundle sessionArgs);
+ void startSession(IVoiceInteractionService service, in Bundle sessionArgs, int flags);
boolean deliverNewSession(IBinder token, IVoiceInteractionSession session,
IVoiceInteractor interactor);
int startVoiceActivity(IBinder token, in Intent intent, String resolvedType);
diff --git a/core/java/com/android/internal/util/DumpUtils.java b/core/java/com/android/internal/util/DumpUtils.java
index 65b56ec..64e1d10 100644
--- a/core/java/com/android/internal/util/DumpUtils.java
+++ b/core/java/com/android/internal/util/DumpUtils.java
@@ -35,13 +35,14 @@
* trying to acquire, we use a short timeout to avoid deadlocks. The process
* is inelegant but this function is only used for debugging purposes.
*/
- public static void dumpAsync(Handler handler, final Dump dump, PrintWriter pw, long timeout) {
+ public static void dumpAsync(Handler handler, final Dump dump, PrintWriter pw,
+ final String prefix, long timeout) {
final StringWriter sw = new StringWriter();
if (handler.runWithScissors(new Runnable() {
@Override
public void run() {
PrintWriter lpw = new FastPrintWriter(sw);
- dump.dump(lpw);
+ dump.dump(lpw, prefix);
lpw.close();
}
}, timeout)) {
@@ -52,6 +53,6 @@
}
public interface Dump {
- void dump(PrintWriter pw);
+ void dump(PrintWriter pw, String prefix);
}
}
diff --git a/core/res/res/drawable/action_bar_item_background_material.xml b/core/res/res/drawable/action_bar_item_background_material.xml
new file mode 100644
index 0000000..8228e3f
--- /dev/null
+++ b/core/res/res/drawable/action_bar_item_background_material.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:color="?attr/colorControlHighlight"
+ android:radius="20dp" />
diff --git a/core/res/res/drawable/control_background_material.xml b/core/res/res/drawable/control_background_material.xml
index ae3181a..7b78349 100644
--- a/core/res/res/drawable/control_background_material.xml
+++ b/core/res/res/drawable/control_background_material.xml
@@ -15,4 +15,5 @@
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="@color/control_highlight_material" />
+ android:color="@color/control_highlight_material"
+ android:radius="20dp" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b90ac65..bc20378 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5291,6 +5291,9 @@
<declare-styleable name="RippleDrawable">
<!-- The color to use for ripple effects. This attribute is required. -->
<attr name="color" />
+ <!-- The radius of the ripple when fully expanded. By default, the
+ radius is computed based on the size of the ripple's container. -->
+ <attr name="radius" />
</declare-styleable>
<declare-styleable name="ScaleDrawable">
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index a4dcfbe..701afee 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -327,7 +327,7 @@
<item name="actionBarWidgetTheme">@null</item>
<item name="actionBarPopupTheme">?attr/popupTheme</item>
<item name="actionBarTheme">@style/ThemeOverlay.Material.ActionBar</item>
- <item name="actionBarItemBackground">?attr/selectableItemBackgroundBorderless</item>
+ <item name="actionBarItemBackground">@drawable/action_bar_item_background_material</item>
<item name="actionModeCutDrawable">@drawable/ic_menu_cut_material</item>
<item name="actionModeCopyDrawable">@drawable/ic_menu_copy_material</item>
@@ -681,7 +681,7 @@
<item name="actionModePopupWindowStyle">@style/Widget.Material.Light.PopupWindow.ActionMode</item>
<item name="actionBarWidgetTheme">@null</item>
<item name="actionBarTheme">@style/ThemeOverlay.Material.ActionBar</item>
- <item name="actionBarItemBackground">?attr/selectableItemBackgroundBorderless</item>
+ <item name="actionBarItemBackground">@drawable/action_bar_item_background_material</item>
<item name="actionModeCutDrawable">@drawable/ic_menu_cut_material</item>
<item name="actionModeCopyDrawable">@drawable/ic_menu_copy_material</item>
@@ -972,8 +972,12 @@
{@link android.service.voice.VoiceInteractionSession} class.
this inherits from Theme.Panel, but sets up appropriate animations
and a few custom attributes. -->
- <style name="Theme.Material.VoiceInteractionSession" parent="Theme.Material.Light.Panel">
- <item name="windowAnimationStyle">@style/Animation.VoiceInteractionSession</item>
+ <style name="Theme.Material.VoiceInteractionSession"
+ parent="Theme.Material.Light.NoActionBar.TranslucentDecor">
+ <item name="windowBackground">@color/transparent</item>
+ <item name="colorBackgroundCacheHint">@null</item>
+ <item name="windowIsTranslucent">true</item>
+ <item name="windowAnimationStyle">@style/Animation</item>
</style>
<!-- Theme for the search input bar. -->
diff --git a/graphics/java/android/graphics/drawable/Ripple.java b/graphics/java/android/graphics/drawable/Ripple.java
index bb1d3cb..138d73a 100644
--- a/graphics/java/android/graphics/drawable/Ripple.java
+++ b/graphics/java/android/graphics/drawable/Ripple.java
@@ -46,8 +46,7 @@
private static final long RIPPLE_ENTER_DELAY = 80;
// Hardware animators.
- private final ArrayList<RenderNodeAnimator> mRunningAnimations =
- new ArrayList<RenderNodeAnimator>();
+ private final ArrayList<RenderNodeAnimator> mRunningAnimations = new ArrayList<>();
private final RippleDrawable mOwner;
@@ -117,8 +116,8 @@
mStartingY = startingY;
}
- public void setup(int maxRadius, float density) {
- if (maxRadius != RippleDrawable.RADIUS_AUTO) {
+ public void setup(float maxRadius, float density) {
+ if (maxRadius >= 0) {
mHasMaxRadius = true;
mOuterRadius = maxRadius;
} else {
diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java
index fae4902..ef35289 100644
--- a/graphics/java/android/graphics/drawable/RippleBackground.java
+++ b/graphics/java/android/graphics/drawable/RippleBackground.java
@@ -49,8 +49,7 @@
private static final int ENTER_DURATION_FAST = 100;
// Hardware animators.
- private final ArrayList<RenderNodeAnimator> mRunningAnimations =
- new ArrayList<RenderNodeAnimator>();
+ private final ArrayList<RenderNodeAnimator> mRunningAnimations = new ArrayList<>();
private final RippleDrawable mOwner;
@@ -105,8 +104,8 @@
mBounds = bounds;
}
- public void setup(int maxRadius, float density) {
- if (maxRadius != RippleDrawable.RADIUS_AUTO) {
+ public void setup(float maxRadius, float density) {
+ if (maxRadius >= 0) {
mHasMaxRadius = true;
mOuterRadius = maxRadius;
} else {
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index ca9f714..556c59f 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -92,19 +92,17 @@
* @attr ref android.R.styleable#RippleDrawable_color
*/
public class RippleDrawable extends LayerDrawable {
+ /**
+ * Radius value that specifies the ripple radius should be computed based
+ * on the size of the ripple's container.
+ */
+ public static final int RADIUS_AUTO = -1;
+
private static final int MASK_UNKNOWN = -1;
private static final int MASK_NONE = 0;
private static final int MASK_CONTENT = 1;
private static final int MASK_EXPLICIT = 2;
- /**
- * Constant for automatically determining the maximum ripple radius.
- *
- * @see #setMaxRadius(int)
- * @hide
- */
- public static final int RADIUS_AUTO = -1;
-
/** The maximum number of ripples supported. */
private static final int MAX_RIPPLES = 10;
@@ -356,12 +354,36 @@
* Sets the ripple color.
*
* @param color Ripple color as a color state list.
+ *
+ * @attr ref android.R.styleable#RippleDrawable_color
*/
public void setColor(ColorStateList color) {
mState.mColor = color;
invalidateSelf();
}
+ /**
+ * Sets the radius in pixels of the fully expanded ripple.
+ *
+ * @param radius ripple radius in pixels, or {@link #RADIUS_AUTO} to
+ * compute the radius based on the container size
+ * @attr ref android.R.styleable#RippleDrawable_radius
+ */
+ public void setRadius(int radius) {
+ mState.mMaxRadius = radius;
+ invalidateSelf();
+ }
+
+ /**
+ * @return the radius in pixels of the fully expanded ripple if an explicit
+ * radius has been set, or {@link #RADIUS_AUTO} if the radius is
+ * computed based on the container size
+ * @attr ref android.R.styleable#RippleDrawable_radius
+ */
+ public int getRadius() {
+ return mState.mMaxRadius;
+ }
+
@Override
public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs, Theme theme)
throws XmlPullParserException, IOException {
@@ -428,6 +450,9 @@
mState.mColor = color;
}
+ mState.mMaxRadius = a.getDimensionPixelSize(
+ R.styleable.RippleDrawable_radius, mState.mMaxRadius);
+
verifyRequiredAttributes(a);
}
@@ -959,36 +984,6 @@
}
}
- /**
- * Sets the maximum ripple radius in pixels. The default value of
- * {@link #RADIUS_AUTO} defines the radius as the distance from the center
- * of the drawable bounds (or hotspot bounds, if specified) to a corner.
- *
- * @param maxRadius the maximum ripple radius in pixels or
- * {@link #RADIUS_AUTO} to automatically determine the maximum
- * radius based on the bounds
- * @see #getMaxRadius()
- * @see #setHotspotBounds(int, int, int, int)
- * @hide
- */
- public void setMaxRadius(int maxRadius) {
- if (maxRadius != RADIUS_AUTO && maxRadius < 0) {
- throw new IllegalArgumentException("maxRadius must be RADIUS_AUTO or >= 0");
- }
-
- mState.mMaxRadius = maxRadius;
- }
-
- /**
- * @return the maximum ripple radius in pixels, or {@link #RADIUS_AUTO} if
- * the radius is determined automatically
- * @see #setMaxRadius(int)
- * @hide
- */
- public int getMaxRadius() {
- return mState.mMaxRadius;
- }
-
private RippleDrawable(RippleState state, Resources res) {
mState = new RippleState(state, this, res);
mLayerState = mState;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c4718b8..511347e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -65,6 +65,7 @@
import com.android.internal.app.ProcessStats;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BatteryStatsImpl;
+import com.android.internal.os.IResultReceiver;
import com.android.internal.os.ProcessCpuTracker;
import com.android.internal.os.TransferPipe;
import com.android.internal.os.Zygote;
@@ -439,23 +440,28 @@
public final Bundle extras;
public final Intent intent;
public final String hint;
+ public final IResultReceiver receiver;
public final int userHandle;
public boolean haveResult = false;
public Bundle result = null;
public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
- String _hint, int _userHandle) {
+ String _hint, IResultReceiver _receiver, int _userHandle) {
activity = _activity;
extras = _extras;
intent = _intent;
hint = _hint;
+ receiver = _receiver;
userHandle = _userHandle;
}
@Override
public void run() {
Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
- synchronized (this) {
- haveResult = true;
- notifyAll();
+ synchronized (ActivityManagerService.this) {
+ synchronized (this) {
+ haveResult = true;
+ notifyAll();
+ }
+ pendingAssistExtrasTimedOutLocked(this);
}
}
}
@@ -9980,8 +9986,9 @@
return true;
}
+ @Override
public Bundle getAssistContextExtras(int requestType) {
- PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
+ PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
UserHandle.getCallingUserId());
if (pae == null) {
return null;
@@ -9993,19 +10000,22 @@
} catch (InterruptedException e) {
}
}
- if (pae.result != null) {
- pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
- }
}
synchronized (this) {
+ buildAssistBundleLocked(pae, pae.result);
mPendingAssistExtras.remove(pae);
mHandler.removeCallbacks(pae);
}
return pae.extras;
}
+ @Override
+ public void requestAssistContextExtras(int requestType, IResultReceiver receiver) {
+ enqueueAssistContext(requestType, null, null, receiver, UserHandle.getCallingUserId());
+ }
+
private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
- int userHandle) {
+ IResultReceiver receiver, int userHandle) {
enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
"getAssistContextExtras()");
PendingAssistExtras pae;
@@ -10025,7 +10035,7 @@
Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
return null;
}
- pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
+ pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
try {
activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
requestType);
@@ -10039,13 +10049,33 @@
}
}
+ void pendingAssistExtrasTimedOutLocked(PendingAssistExtras pae) {
+ mPendingAssistExtras.remove(pae);
+ if (pae.receiver != null) {
+ // Caller wants result sent back to them.
+ try {
+ pae.receiver.send(0, null);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+
+ private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
+ if (result != null) {
+ pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
+ }
+ if (pae.hint != null) {
+ pae.extras.putBoolean(pae.hint, true);
+ }
+ }
+
public void reportAssistContextExtras(IBinder token, Bundle extras) {
PendingAssistExtras pae = (PendingAssistExtras)token;
synchronized (pae) {
pae.result = extras;
pae.haveResult = true;
pae.notifyAll();
- if (pae.intent == null) {
+ if (pae.intent == null && pae.receiver == null) {
// Caller is just waiting for the result.
return;
}
@@ -10053,17 +10083,23 @@
// We are now ready to launch the assist activity.
synchronized (this) {
+ buildAssistBundleLocked(pae, extras);
boolean exists = mPendingAssistExtras.remove(pae);
mHandler.removeCallbacks(pae);
if (!exists) {
// Timed out.
return;
}
+ if (pae.receiver != null) {
+ // Caller wants result sent back to them.
+ try {
+ pae.receiver.send(0, pae.extras);
+ } catch (RemoteException e) {
+ }
+ return;
+ }
}
- pae.intent.replaceExtras(extras);
- if (pae.hint != null) {
- pae.intent.putExtra(pae.hint, true);
- }
+ pae.intent.replaceExtras(pae.extras);
pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
@@ -10076,7 +10112,7 @@
}
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
- return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
+ return enqueueAssistContext(requestType, intent, hint, null, userHandle) != null;
}
public void registerProcessObserver(IProcessObserver observer) {
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index b3f47e9..c0d2502 100755
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -712,6 +712,17 @@
pendingOptions.getCustomExitResId(),
pendingOptions.getOnAnimationStartListener());
break;
+ case ActivityOptions.ANIM_CLIP_REVEAL:
+ service.mWindowManager.overridePendingAppTransitionClipReveal(
+ pendingOptions.getStartX(), pendingOptions.getStartY(),
+ pendingOptions.getWidth(), pendingOptions.getHeight());
+ if (intent.getSourceBounds() == null) {
+ intent.setSourceBounds(new Rect(pendingOptions.getStartX(),
+ pendingOptions.getStartY(),
+ pendingOptions.getStartX()+pendingOptions.getWidth(),
+ pendingOptions.getStartY()+pendingOptions.getHeight()));
+ }
+ break;
case ActivityOptions.ANIM_SCALE_UP:
service.mWindowManager.overridePendingAppTransitionScaleUp(
pendingOptions.getStartX(), pendingOptions.getStartY(),
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 4301427..0cd6f9c 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1922,6 +1922,15 @@
entry.setValue(10);
}
}
+ // Persist volume for stream ring when it is changed here
+ final int device = getDeviceForStream(streamType);
+ sendMsg(mAudioHandler,
+ MSG_PERSIST_VOLUME,
+ SENDMSG_QUEUE,
+ device,
+ 0,
+ mStreamStates[streamType],
+ PERSIST_DELAY);
}
}
mStreamStates[streamType].mute(false);
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index 5b6f35b..af9f456 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -355,7 +355,7 @@
if (mWindow != null) {
final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.increaseIndent();
- DumpUtils.dumpAsync(mUiHandler, mWindow, ipw, 200);
+ DumpUtils.dumpAsync(mUiHandler, mWindow, ipw, "", 200);
}
}
diff --git a/services/core/java/com/android/server/display/OverlayDisplayWindow.java b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
index 9ca5fda..3f4eab9 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayWindow.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayWindow.java
@@ -153,7 +153,7 @@
}
@Override
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, String prefix) {
pw.println("mWindowVisible=" + mWindowVisible);
pw.println("mWindowX=" + mWindowX);
pw.println("mWindowY=" + mWindowY);
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index c939861..f163555 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -123,7 +123,7 @@
pw.println("mDisplayController:");
final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ");
ipw.increaseIndent();
- DumpUtils.dumpAsync(getHandler(), mDisplayController, ipw, 200);
+ DumpUtils.dumpAsync(getHandler(), mDisplayController, ipw, "", 200);
}
}
diff --git a/services/core/java/com/android/server/display/WifiDisplayController.java b/services/core/java/com/android/server/display/WifiDisplayController.java
index dbb59b2..31c1eea 100644
--- a/services/core/java/com/android/server/display/WifiDisplayController.java
+++ b/services/core/java/com/android/server/display/WifiDisplayController.java
@@ -209,7 +209,7 @@
}
@Override
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, String prefix) {
pw.println("mWifiDisplayOnSetting=" + mWifiDisplayOnSetting);
pw.println("mWifiP2pEnabled=" + mWifiP2pEnabled);
pw.println("mWfdEnabled=" + mWfdEnabled);
diff --git a/services/core/java/com/android/server/dreams/DreamManagerService.java b/services/core/java/com/android/server/dreams/DreamManagerService.java
index 4521c28..458928f 100644
--- a/services/core/java/com/android/server/dreams/DreamManagerService.java
+++ b/services/core/java/com/android/server/dreams/DreamManagerService.java
@@ -137,10 +137,10 @@
DumpUtils.dumpAsync(mHandler, new DumpUtils.Dump() {
@Override
- public void dump(PrintWriter pw) {
+ public void dump(PrintWriter pw, String prefix) {
mController.dump(pw);
}
- }, pw, 200);
+ }, pw, "", 200);
}
private boolean isDreamingInternal() {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index f93bd92..9b6b5fb 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -209,7 +209,7 @@
private final ArraySet<ManagedServiceInfo> mListenersDisablingEffects = new ArraySet<>();
private ComponentName mEffectsSuppressor;
private int mListenerHints; // right now, all hints are global
- private int mInterruptionFilter; // current ZEN mode as communicated to listeners
+ private int mInterruptionFilter = NotificationListenerService.INTERRUPTION_FILTER_UNKNOWN;
// for enabling and disabling notification pulse behavior
private boolean mScreenOn = true;
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5bb193a..ff274b6 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -3554,7 +3554,7 @@
pf.bottom = df.bottom = of.bottom = cf.bottom
= mOverscanScreenTop + mOverscanScreenHeight;
}
- } else if (attrs.type == TYPE_INPUT_METHOD) {
+ } else if (attrs.type == TYPE_INPUT_METHOD || attrs.type == TYPE_VOICE_INTERACTION) {
pf.left = df.left = of.left = cf.left = vf.left = mDockLeft;
pf.top = df.top = of.top = cf.top = vf.top = mDockTop;
pf.right = df.right = of.right = cf.right = vf.right = mDockRight;
@@ -3936,7 +3936,7 @@
}
private void offsetInputMethodWindowLw(WindowState win) {
- int top = win.getContentFrameLw().top;
+ int top = win.getDisplayFrameLw().top;
top += win.getGivenContentInsetsLw().top;
if (mContentBottom > top) {
mContentBottom = top;
@@ -3955,36 +3955,10 @@
}
private void offsetVoiceInputWindowLw(WindowState win) {
- final int gravity = win.getAttrs().gravity;
- switch (gravity&((Gravity.AXIS_PULL_BEFORE|Gravity.AXIS_PULL_AFTER)
- << Gravity.AXIS_X_SHIFT)) {
- case Gravity.AXIS_PULL_BEFORE<<Gravity.AXIS_X_SHIFT: {
- int right = win.getContentFrameLw().right - win.getGivenContentInsetsLw().right;
- if (mVoiceContentLeft < right) {
- mVoiceContentLeft = right;
- }
- } break;
- case Gravity.AXIS_PULL_AFTER<<Gravity.AXIS_X_SHIFT: {
- int left = win.getContentFrameLw().left - win.getGivenContentInsetsLw().left;
- if (mVoiceContentRight < left) {
- mVoiceContentRight = left;
- }
- } break;
- }
- switch (gravity&((Gravity.AXIS_PULL_BEFORE|Gravity.AXIS_PULL_AFTER)
- << Gravity.AXIS_Y_SHIFT)) {
- case Gravity.AXIS_PULL_BEFORE<<Gravity.AXIS_Y_SHIFT: {
- int bottom = win.getContentFrameLw().bottom - win.getGivenContentInsetsLw().bottom;
- if (mVoiceContentTop < bottom) {
- mVoiceContentTop = bottom;
- }
- } break;
- case Gravity.AXIS_PULL_AFTER<<Gravity.AXIS_Y_SHIFT: {
- int top = win.getContentFrameLw().top - win.getGivenContentInsetsLw().top;
- if (mVoiceContentBottom < top) {
- mVoiceContentBottom = top;
- }
- } break;
+ int top = win.getDisplayFrameLw().top;
+ top += win.getGivenContentInsetsLw().top;
+ if (mVoiceContentBottom > top) {
+ mVoiceContentBottom = top;
}
}
@@ -6385,9 +6359,8 @@
}
if (mStatusBar != null) {
pw.print(prefix); pw.print("mStatusBar=");
- pw.println(mStatusBar);
- pw.print(prefix); pw.print("isStatusBarKeyguard=");
- pw.print(isStatusBarKeyguard());
+ pw.print(mStatusBar); pw.print(" isStatusBarKeyguard=");
+ pw.println(isStatusBarKeyguard());
}
if (mNavigationBar != null) {
pw.print(prefix); pw.print("mNavigationBar=");
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index c0d54e1..2afeaab 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -17,12 +17,16 @@
package com.android.server.wm;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.os.Debug;
import android.os.Handler;
import android.os.IRemoteCallback;
+import android.os.UserHandle;
+import android.util.Log;
import android.util.Slog;
import android.view.WindowManager;
import android.view.animation.AlphaAnimation;
@@ -30,9 +34,14 @@
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.ClipRectAnimation;
+import android.view.animation.ClipRectLRAnimation;
+import android.view.animation.ClipRectTBAnimation;
import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
+import android.view.animation.TranslateXAnimation;
+import android.view.animation.TranslateYAnimation;
import com.android.internal.util.DumpUtils.Dump;
import com.android.server.AttributeCache;
import com.android.server.wm.WindowManagerService.H;
@@ -134,6 +143,7 @@
private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP = 5;
private static final int NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN = 6;
private static final int NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE = 7;
+ private static final int NEXT_TRANSIT_TYPE_CLIP_REVEAL = 8;
private int mNextAppTransitionType = NEXT_TRANSIT_TYPE_NONE;
// These are the possible states for the enter/exit activities during a thumbnail transition
@@ -169,19 +179,24 @@
private final Interpolator mDecelerateInterpolator;
private final Interpolator mThumbnailFadeInInterpolator;
private final Interpolator mThumbnailFadeOutInterpolator;
- private final Interpolator mThumbnailFastOutSlowInInterpolator;
+ private final Interpolator mLinearOutSlowInInterpolator;
+ private final Interpolator mFastOutSlowInInterpolator;
+ private final LinearInterpolator mLinearInterpolator;
private int mCurrentUserId = 0;
AppTransition(Context context, Handler h) {
mContext = context;
mH = h;
+ mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.linear_out_slow_in);
+ mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.fast_out_slow_in);
+ mLinearInterpolator = new LinearInterpolator();
mConfigShortAnimTime = context.getResources().getInteger(
com.android.internal.R.integer.config_shortAnimTime);
mDecelerateInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.decelerate_cubic);
- mThumbnailFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
- com.android.internal.R.interpolator.fast_out_slow_in);
mThumbnailFadeInInterpolator = new Interpolator() {
@Override
public float getInterpolation(float input) {
@@ -447,6 +462,83 @@
return a;
}
+ private Animation createClipRevealAnimationLocked(int transit, boolean enter,
+ int appWidth, int appHeight) {
+ final Animation anim;
+ if (enter) {
+ // Reveal will expand and move faster in horizontal direction
+
+ // Start from size of launch icon, expand to full width/height
+ Animation clipAnimLR = new ClipRectLRAnimation(
+ (appWidth - mNextAppTransitionStartWidth) / 2,
+ (appWidth + mNextAppTransitionStartWidth) / 2, 0, appWidth);
+ clipAnimLR.setInterpolator(mLinearOutSlowInInterpolator);
+ clipAnimLR.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+ Animation clipAnimTB = new ClipRectTBAnimation(
+ (appHeight - mNextAppTransitionStartHeight) / 2,
+ (appHeight + mNextAppTransitionStartHeight) / 2, 0, appHeight);
+ clipAnimTB.setInterpolator(mFastOutSlowInInterpolator);
+ clipAnimTB.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+
+ // Start from middle of launch icon area, move to 0, 0
+ int startMiddleX = mNextAppTransitionStartX +
+ (mNextAppTransitionStartWidth - appWidth) / 2;
+ int startMiddleY = mNextAppTransitionStartY +
+ (mNextAppTransitionStartHeight - appHeight) / 2;
+
+ TranslateXAnimation translateX = new TranslateXAnimation(
+ Animation.ABSOLUTE, startMiddleX, Animation.ABSOLUTE, 0);
+ translateX.setInterpolator(mLinearOutSlowInInterpolator);
+ translateX.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+ TranslateYAnimation translateY = new TranslateYAnimation(
+ Animation.ABSOLUTE, startMiddleY, Animation.ABSOLUTE, 0);
+ translateY.setInterpolator(mFastOutSlowInInterpolator);
+ translateY.setDuration(DEFAULT_APP_TRANSITION_DURATION);
+
+ // Quick fade-in from icon to app window
+ final int alphaDuration = 100;
+ AlphaAnimation alpha = new AlphaAnimation(0.1f, 1);
+ alpha.setDuration(alphaDuration);
+ alpha.setInterpolator(mLinearInterpolator);
+
+ AnimationSet set = new AnimationSet(false);
+ set.addAnimation(clipAnimLR);
+ set.addAnimation(clipAnimTB);
+ set.addAnimation(translateX);
+ set.addAnimation(translateY);
+ set.addAnimation(alpha);
+ set.initialize(appWidth, appHeight, appWidth, appHeight);
+ anim = set;
+ } else {
+ final long duration;
+ switch (transit) {
+ case TRANSIT_ACTIVITY_OPEN:
+ case TRANSIT_ACTIVITY_CLOSE:
+ duration = mConfigShortAnimTime;
+ break;
+ default:
+ duration = DEFAULT_APP_TRANSITION_DURATION;
+ break;
+ }
+ if (transit == TRANSIT_WALLPAPER_INTRA_OPEN ||
+ transit == TRANSIT_WALLPAPER_INTRA_CLOSE) {
+ // If we are on top of the wallpaper, we need an animation that
+ // correctly handles the wallpaper staying static behind all of
+ // the animated elements. To do this, will just have the existing
+ // element fade out.
+ anim = new AlphaAnimation(1, 0);
+ anim.setDetachWallpaper(true);
+ } else {
+ // For normal animations, the exiting element just holds in place.
+ anim = new AlphaAnimation(1, 1);
+ }
+ anim.setInterpolator(mDecelerateInterpolator);
+ anim.setDuration(duration);
+ anim.setFillAfter(true);
+ }
+ return anim;
+ }
+
/**
* Prepares the specified animation with a standard duration, interpolator, etc.
*/
@@ -522,14 +614,14 @@
Animation scale = new ScaleAnimation(1f, scaleW, 1f, scaleW,
mNextAppTransitionStartX + (thumbWidth / 2f),
mNextAppTransitionStartY + (thumbHeight / 2f));
- scale.setInterpolator(mThumbnailFastOutSlowInInterpolator);
+ scale.setInterpolator(mFastOutSlowInInterpolator);
scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Animation alpha = new AlphaAnimation(1, 0);
alpha.setInterpolator(mThumbnailFadeOutInterpolator);
alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
Animation translate = new TranslateAnimation(0, 0, 0, -unscaledStartY +
mNextAppTransitionInsets.top);
- translate.setInterpolator(mThumbnailFastOutSlowInInterpolator);
+ translate.setInterpolator(mFastOutSlowInInterpolator);
translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
// This AnimationSet uses the Interpolators assigned above.
@@ -543,14 +635,14 @@
Animation scale = new ScaleAnimation(scaleW, 1f, scaleW, 1f,
mNextAppTransitionStartX + (thumbWidth / 2f),
mNextAppTransitionStartY + (thumbHeight / 2f));
- scale.setInterpolator(mThumbnailFastOutSlowInInterpolator);
+ scale.setInterpolator(mFastOutSlowInInterpolator);
scale.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
Animation alpha = new AlphaAnimation(0f, 1f);
alpha.setInterpolator(mThumbnailFadeInInterpolator);
alpha.setDuration(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION);
Animation translate = new TranslateAnimation(0, 0, -unscaledStartY +
mNextAppTransitionInsets.top, 0);
- translate.setInterpolator(mThumbnailFastOutSlowInInterpolator);
+ translate.setInterpolator(mFastOutSlowInInterpolator);
translate.setDuration(THUMBNAIL_APP_TRANSITION_DURATION);
// This AnimationSet uses the Interpolators assigned above.
@@ -562,7 +654,7 @@
}
return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, 0,
- mThumbnailFastOutSlowInInterpolator);
+ mFastOutSlowInInterpolator);
}
/**
@@ -698,7 +790,7 @@
int duration = Math.max(THUMBNAIL_APP_TRANSITION_ALPHA_DURATION,
THUMBNAIL_APP_TRANSITION_DURATION);
return prepareThumbnailAnimationWithDuration(a, appWidth, appHeight, duration,
- mThumbnailFastOutSlowInInterpolator);
+ mFastOutSlowInInterpolator);
}
/**
@@ -845,6 +937,12 @@
"applyAnimation:"
+ " anim=" + a + " nextAppTransition=ANIM_CUSTOM_IN_PLACE"
+ " transit=" + transit + " Callers=" + Debug.getCallers(3));
+ } else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_CLIP_REVEAL) {
+ a = createClipRevealAnimationLocked(transit, enter, appWidth, appHeight);
+ if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
+ "applyAnimation:"
+ + " anim=" + a + " nextAppTransition=ANIM_CLIP_REVEAL"
+ + " Callers=" + Debug.getCallers(3));
} else if (mNextAppTransitionType == NEXT_TRANSIT_TYPE_SCALE_UP) {
a = createScaleUpAnimationLocked(transit, enter, appWidth, appHeight);
if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) Slog.v(TAG,
@@ -987,6 +1085,19 @@
}
}
+ void overridePendingAppTransitionClipReveal(int startX, int startY,
+ int startWidth, int startHeight) {
+ if (isTransitionSet()) {
+ mNextAppTransitionType = NEXT_TRANSIT_TYPE_CLIP_REVEAL;
+ mNextAppTransitionStartX = startX;
+ mNextAppTransitionStartY = startY;
+ mNextAppTransitionStartWidth = startWidth;
+ mNextAppTransitionStartHeight = startHeight;
+ postAnimationCallback();
+ mNextAppTransitionCallback = null;
+ }
+ }
+
void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
IRemoteCallback startedCallback, boolean scaleUp) {
if (isTransitionSet()) {
@@ -1130,32 +1241,34 @@
}
@Override
- public void dump(PrintWriter pw) {
- pw.print(" " + this);
- pw.print(" mAppTransitionState="); pw.println(appStateToString());
+ public void dump(PrintWriter pw, String prefix) {
+ pw.print(prefix); pw.println(this);
+ pw.print(prefix); pw.print("mAppTransitionState="); pw.println(appStateToString());
if (mNextAppTransitionType != NEXT_TRANSIT_TYPE_NONE) {
- pw.print(" mNextAppTransitionType="); pw.println(transitTypeToString());
+ pw.print(prefix); pw.print("mNextAppTransitionType=");
+ pw.println(transitTypeToString());
}
switch (mNextAppTransitionType) {
case NEXT_TRANSIT_TYPE_CUSTOM:
- pw.print(" mNextAppTransitionPackage=");
+ pw.print(prefix); pw.print("mNextAppTransitionPackage=");
pw.println(mNextAppTransitionPackage);
- pw.print(" mNextAppTransitionEnter=0x");
+ pw.print(prefix); pw.print("mNextAppTransitionEnter=0x");
pw.print(Integer.toHexString(mNextAppTransitionEnter));
pw.print(" mNextAppTransitionExit=0x");
pw.println(Integer.toHexString(mNextAppTransitionExit));
break;
case NEXT_TRANSIT_TYPE_CUSTOM_IN_PLACE:
- pw.print(" mNextAppTransitionPackage=");
+ pw.print(prefix); pw.print("mNextAppTransitionPackage=");
pw.println(mNextAppTransitionPackage);
- pw.print(" mNextAppTransitionInPlace=0x");
+ pw.print(prefix); pw.print("mNextAppTransitionInPlace=0x");
pw.print(Integer.toHexString(mNextAppTransitionInPlace));
break;
case NEXT_TRANSIT_TYPE_SCALE_UP:
- pw.print(" mNextAppTransitionStartX="); pw.print(mNextAppTransitionStartX);
+ pw.print(prefix); pw.print("mNextAppTransitionStartX=");
+ pw.print(mNextAppTransitionStartX);
pw.print(" mNextAppTransitionStartY=");
pw.println(mNextAppTransitionStartY);
- pw.print(" mNextAppTransitionStartWidth=");
+ pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
pw.print(mNextAppTransitionStartWidth);
pw.print(" mNextAppTransitionStartHeight=");
pw.println(mNextAppTransitionStartHeight);
@@ -1164,22 +1277,23 @@
case NEXT_TRANSIT_TYPE_THUMBNAIL_SCALE_DOWN:
case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP:
case NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_DOWN:
- pw.print(" mNextAppTransitionThumbnail=");
+ pw.print(prefix); pw.print("mNextAppTransitionThumbnail=");
pw.print(mNextAppTransitionThumbnail);
pw.print(" mNextAppTransitionStartX=");
pw.print(mNextAppTransitionStartX);
pw.print(" mNextAppTransitionStartY=");
pw.println(mNextAppTransitionStartY);
- pw.print(" mNextAppTransitionStartWidth=");
+ pw.print(prefix); pw.print("mNextAppTransitionStartWidth=");
pw.print(mNextAppTransitionStartWidth);
pw.print(" mNextAppTransitionStartHeight=");
pw.println(mNextAppTransitionStartHeight);
- pw.print(" mNextAppTransitionScaleUp="); pw.println(mNextAppTransitionScaleUp);
+ pw.print(prefix); pw.print("mNextAppTransitionScaleUp=");
+ pw.println(mNextAppTransitionScaleUp);
break;
}
if (mNextAppTransitionCallback != null) {
- pw.print(" mNextAppTransitionCallback=");
- pw.println(mNextAppTransitionCallback);
+ pw.print(prefix); pw.print("mNextAppTransitionCallback=");
+ pw.println(mNextAppTransitionCallback);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 02a4f4d..51f8f99 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4062,6 +4062,15 @@
}
@Override
+ public void overridePendingAppTransitionClipReveal(int startX, int startY,
+ int startWidth, int startHeight) {
+ synchronized(mWindowMap) {
+ mAppTransition.overridePendingAppTransitionClipReveal(startX, startY, startWidth,
+ startHeight);
+ }
+ }
+
+ @Override
public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX,
int startY, IRemoteCallback startedCallback, boolean scaleUp) {
synchronized(mWindowMap) {
@@ -11058,7 +11067,7 @@
pw.print(" mStartingIconInTransition="); pw.print(mStartingIconInTransition);
pw.print(" mSkipAppTransitionAnimation="); pw.println(mSkipAppTransitionAnimation);
pw.println(" mLayoutToAnim:");
- mAppTransition.dump(pw);
+ mAppTransition.dump(pw, " ");
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index c32ba67..fd990d7 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -129,12 +129,14 @@
}
public void initForUser(int userHandle) {
- if (DEBUG) Slog.i(TAG, "initForUser user=" + userHandle);
+ if (DEBUG) Slog.d(TAG, "**************** initForUser user=" + userHandle);
String curInteractorStr = Settings.Secure.getStringForUser(
mContext.getContentResolver(),
Settings.Secure.VOICE_INTERACTION_SERVICE, userHandle);
ComponentName curRecognizer = getCurRecognizer(userHandle);
VoiceInteractionServiceInfo curInteractorInfo = null;
+ if (DEBUG) Slog.d(TAG, "curInteractorStr=" + curInteractorStr
+ + " curRecognizer=" + curRecognizer);
if (curInteractorStr == null && curRecognizer != null
&& !ActivityManager.isLowRamDeviceStatic()) {
// If there is no interactor setting, that means we are upgrading
@@ -148,6 +150,8 @@
// Looks good! We'll apply this one. To make it happen, we clear the
// recognizer so that we don't think we have anything set and will
// re-apply the settings.
+ if (DEBUG) Slog.d(TAG, "No set interactor, found avail: "
+ + curInteractorInfo.getServiceInfo().name);
curRecognizer = null;
}
}
@@ -156,6 +160,7 @@
// enabled; if it is, turn it off.
if (ActivityManager.isLowRamDeviceStatic() && curInteractorStr != null) {
if (!TextUtils.isEmpty(curInteractorStr)) {
+ if (DEBUG) Slog.d(TAG, "Svelte device; disabling interactor");
setCurInteractor(null, userHandle);
curInteractorStr = "";
}
@@ -178,8 +183,11 @@
}
// If the apps for the currently set components still exist, then all is okay.
if (recognizerInfo != null && (curInteractor == null || interactorInfo != null)) {
+ if (DEBUG) Slog.d(TAG, "Current interactor/recognizer okay, done!");
return;
}
+ if (DEBUG) Slog.d(TAG, "Bad recognizer (" + recognizerInfo + ") or interactor ("
+ + interactorInfo + ")");
}
// Initializing settings, look for an interactor first (but only on non-svelte).
@@ -316,7 +324,7 @@
if (TextUtils.isEmpty(curInteractor)) {
return null;
}
- if (DEBUG) Slog.i(TAG, "getCurInteractor curInteractor=" + curInteractor
+ if (DEBUG) Slog.d(TAG, "getCurInteractor curInteractor=" + curInteractor
+ " user=" + userHandle);
return ComponentName.unflattenFromString(curInteractor);
}
@@ -325,7 +333,7 @@
Settings.Secure.putStringForUser(mContext.getContentResolver(),
Settings.Secure.VOICE_INTERACTION_SERVICE,
comp != null ? comp.flattenToShortString() : "", userHandle);
- if (DEBUG) Slog.i(TAG, "setCurInteractor comp=" + comp
+ if (DEBUG) Slog.d(TAG, "setCurInteractor comp=" + comp
+ " user=" + userHandle);
}
@@ -363,7 +371,7 @@
if (TextUtils.isEmpty(curRecognizer)) {
return null;
}
- if (DEBUG) Slog.i(TAG, "getCurRecognizer curRecognizer=" + curRecognizer
+ if (DEBUG) Slog.d(TAG, "getCurRecognizer curRecognizer=" + curRecognizer
+ " user=" + userHandle);
return ComponentName.unflattenFromString(curRecognizer);
}
@@ -372,12 +380,12 @@
Settings.Secure.putStringForUser(mContext.getContentResolver(),
Settings.Secure.VOICE_RECOGNITION_SERVICE,
comp != null ? comp.flattenToShortString() : "", userHandle);
- if (DEBUG) Slog.i(TAG, "setCurRecognizer comp=" + comp
+ if (DEBUG) Slog.d(TAG, "setCurRecognizer comp=" + comp
+ " user=" + userHandle);
}
@Override
- public void startSession(IVoiceInteractionService service, Bundle args) {
+ public void startSession(IVoiceInteractionService service, Bundle args, int flags) {
synchronized (this) {
if (mImpl == null || mImpl.mService == null
|| service.asBinder() != mImpl.mService.asBinder()) {
@@ -388,7 +396,7 @@
final int callingUid = Binder.getCallingUid();
final long caller = Binder.clearCallingIdentity();
try {
- mImpl.startSessionLocked(callingPid, callingUid, args);
+ mImpl.startSessionLocked(callingPid, callingUid, args, flags);
} finally {
Binder.restoreCallingIdentity(caller);
}
@@ -692,7 +700,7 @@
@Override
public void onSomePackagesChanged() {
int userHandle = getChangingUserId();
- if (DEBUG) Slog.i(TAG, "onSomePackagesChanged user=" + userHandle);
+ if (DEBUG) Slog.d(TAG, "onSomePackagesChanged user=" + userHandle);
ComponentName curInteractor = getCurInteractor(userHandle);
ComponentName curRecognizer = getCurRecognizer(userHandle);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index b36b611..e80f702 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -43,6 +43,7 @@
import android.view.WindowManager;
import com.android.internal.app.IVoiceInteractor;
+import com.android.internal.os.IResultReceiver;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -103,13 +104,33 @@
final class SessionConnection implements ServiceConnection {
final IBinder mToken = new Binder();
final Bundle mArgs;
+ final int mFlags;
boolean mBound;
IVoiceInteractionSessionService mService;
IVoiceInteractionSession mSession;
IVoiceInteractor mInteractor;
+ boolean mHaveAssistData;
+ Bundle mAssistData;
- SessionConnection(Bundle args) {
+ final IResultReceiver mAssistReceiver = new IResultReceiver.Stub() {
+ @Override
+ public void send(int resultCode, Bundle resultData) throws RemoteException {
+ synchronized (mLock) {
+ mHaveAssistData = true;
+ mAssistData = resultData;
+ if (mSession != null) {
+ try {
+ mSession.handleAssist(resultData);
+ } catch (RemoteException e) {
+ }
+ }
+ }
+ }
+ };
+
+ SessionConnection(Bundle args, int flags) {
mArgs = args;
+ mFlags = flags;
Intent serviceIntent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
serviceIntent.setComponent(mSessionComponentName);
mBound = mContext.bindServiceAsUser(serviceIntent, this,
@@ -121,6 +142,14 @@
} catch (RemoteException e) {
Slog.w(TAG, "Failed adding window token", e);
}
+ if ((flags&VoiceInteractionService.START_WITH_ASSIST) != 0) {
+ try {
+ mAm.requestAssistContextExtras(0, mAssistReceiver);
+ } catch (RemoteException e) {
+ }
+ } else {
+ mHaveAssistData = true;
+ }
} else {
Slog.w(TAG, "Failed binding to voice interaction session service " + mComponent);
}
@@ -132,7 +161,7 @@
mService = IVoiceInteractionSessionService.Stub.asInterface(service);
if (mActiveSession == this) {
try {
- mService.newSession(mToken, mArgs);
+ mService.newSession(mToken, mArgs, mFlags);
} catch (RemoteException e) {
Slog.w(TAG, "Failed adding window token", e);
}
@@ -176,12 +205,17 @@
public void dump(String prefix, PrintWriter pw) {
pw.print(prefix); pw.print("mToken="); pw.println(mToken);
pw.print(prefix); pw.print("mArgs="); pw.println(mArgs);
+ pw.print(prefix); pw.print("mFlags=0x"); pw.println(Integer.toHexString(mFlags));
pw.print(prefix); pw.print("mBound="); pw.println(mBound);
if (mBound) {
pw.print(prefix); pw.print("mService="); pw.println(mService);
pw.print(prefix); pw.print("mSession="); pw.println(mSession);
pw.print(prefix); pw.print("mInteractor="); pw.println(mInteractor);
}
+ pw.print(prefix); pw.print("mHaveAssistData="); pw.println(mHaveAssistData);
+ if (mHaveAssistData) {
+ pw.print(prefix); pw.print("mAssistData="); pw.println(mAssistData);
+ }
}
};
@@ -222,12 +256,12 @@
mContext.registerReceiver(mBroadcastReceiver, filter, null, handler);
}
- public void startSessionLocked(int callingPid, int callingUid, Bundle args) {
+ public void startSessionLocked(int callingPid, int callingUid, Bundle args, int flags) {
if (mActiveSession != null) {
mActiveSession.cancel();
mActiveSession = null;
}
- mActiveSession = new SessionConnection(args);
+ mActiveSession = new SessionConnection(args, flags);
}
public boolean deliverNewSessionLocked(int callingPid, int callingUid, IBinder token,
@@ -238,6 +272,12 @@
}
mActiveSession.mSession = session;
mActiveSession.mInteractor = interactor;
+ if (mActiveSession.mHaveAssistData) {
+ try {
+ session.handleAssist(mActiveSession.mAssistData);
+ } catch (RemoteException e) {
+ }
+ }
return true;
}
diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml
index 06d31a4..adf572c 100644
--- a/tests/VoiceInteraction/AndroidManifest.xml
+++ b/tests/VoiceInteraction/AndroidManifest.xml
@@ -12,11 +12,19 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
- <activity android:name="SettingsActivity"
- android:label="Voice Interaction Settings"
+ <activity android:name="AssistProxyActivity"
+ android:label="Test Assist Proxy"
+ android:theme="@android:style/Theme.NoDisplay"
android:excludeFromRecents="true"
android:noHistory="true">
<intent-filter>
+ <action android:name="android.intent.action.ASSIST" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ <activity android:name="SettingsActivity"
+ android:label="Voice Interaction Settings">
+ <intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
@@ -44,7 +52,7 @@
<meta-data android:name="android.speech" android:resource="@xml/recognition_service" />
</service>
<activity android:name="TestInteractionActivity" android:label="Voice Interaction Target"
- android:theme="@android:style/Theme.Material.Light.Voice">
+ android:theme="@android:style/Theme.Material.Light">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
diff --git a/tests/VoiceInteraction/res/layout/test_interaction.xml b/tests/VoiceInteraction/res/layout/test_interaction.xml
index d55736f..c4e280e 100644
--- a/tests/VoiceInteraction/res/layout/test_interaction.xml
+++ b/tests/VoiceInteraction/res/layout/test_interaction.xml
@@ -32,7 +32,6 @@
android:layout_weight="1"
android:layout_marginTop="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:textColor="#ffffffff"
/>
<Button android:id="@+id/complete"
diff --git a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
index 002f350..10571765 100644
--- a/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
+++ b/tests/VoiceInteraction/res/layout/voice_interaction_session.xml
@@ -15,24 +15,46 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="match_parent"
- android:fitsSystemWindows="true">
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
- <FrameLayout android:layout_width="fill_parent"
+ <com.android.test.voiceinteraction.AssistVisualizer android:id="@+id/assist_visualizer"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <FrameLayout android:layout_width="match_parent"
android:layout_height="match_parent"
- android:padding="8dp">
+ android:fitsSystemWindows="true">
- <LinearLayout android:id="@+id/content"
- android:layout_width="fill_parent"
- android:layout_height="match_parent"
+ <FrameLayout android:id="@+id/top_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top"
+ android:orientation="vertical"
+ 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>
+
+ <LinearLayout android:id="@+id/bottom_content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="bottom"
android:orientation="vertical"
android:background="#ffffffff"
android:elevation="8dp"
>
<TextView android:id="@+id/text"
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
@@ -40,11 +62,6 @@
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content"
android:orientation="horizontal">
- <Button android:id="@+id/start"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/start"
- />
<Button android:id="@+id/confirm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistProxyActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistProxyActivity.java
new file mode 100644
index 0000000..fc04ff5
--- /dev/null
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistProxyActivity.java
@@ -0,0 +1,34 @@
+/*
+ * 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.test.voiceinteraction;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+public class AssistProxyActivity extends Activity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ finish();
+ Intent intent = new Intent(this, MainInteractionService.class);
+ intent.setAction(Intent.ACTION_ASSIST);
+ intent.putExtras(getIntent());
+ startService(new Intent(this, MainInteractionService.class));
+ }
+}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
new file mode 100644
index 0000000..5d5ae2f
--- /dev/null
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/AssistVisualizer.java
@@ -0,0 +1,95 @@
+/*
+ * 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.test.voiceinteraction;
+
+import android.annotation.Nullable;
+import android.app.AssistData;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+
+import java.util.ArrayList;
+
+public class AssistVisualizer extends View {
+ static final String TAG = "AssistVisualizer";
+
+ AssistData mAssistData;
+ final Paint mFramePaint = new Paint();
+ final ArrayList<Rect> mTextRects = new ArrayList<>();
+ final int[] mTmpLocation = new int[2];
+
+ public AssistVisualizer(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ setWillNotDraw(false);
+ mFramePaint.setColor(0xffff0000);
+ mFramePaint.setStyle(Paint.Style.STROKE);
+ mFramePaint.setStrokeWidth(0);
+ }
+
+ public void setAssistData(AssistData ad) {
+ mAssistData = ad;
+ mTextRects.clear();
+ final int N = ad.getWindowCount();
+ if (N > 0) {
+ AssistData.ViewNode window = new AssistData.ViewNode();
+ for (int i=0; i<N; i++) {
+ ad.getWindowAt(i, window);
+ buildTextRects(window, 0, 0);
+ }
+ }
+ }
+
+ void buildTextRects(AssistData.ViewNode root, int parentLeft, int parentTop) {
+ if (root.getVisibility() != View.VISIBLE) {
+ return;
+ }
+ int left = parentLeft+root.getLeft();
+ int top = parentTop+root.getTop();
+ Log.d(TAG, "View " + root.getClassName() + ": " + left + ", " + top);
+ if (root.getText() != null) {
+ Rect r = new Rect(left, top, left+root.getWidth(), top+root.getHeight());
+ Log.d(TAG, "Text Rect " + r.toShortString() + ": " + root.getText());
+ mTextRects.add(r);
+ }
+ final int N = root.getChildCount();
+ if (N > 0) {
+ left -= root.getScrollX();
+ top -= root.getScrollY();
+ AssistData.ViewNode child = new AssistData.ViewNode();
+ for (int i=0; i<N; i++) {
+ root.getChildAt(i, child);
+ buildTextRects(child, left, top);
+ }
+ }
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ getLocationOnScreen(mTmpLocation);
+ final int N = mTextRects.size();
+ for (int i=0; i<N; i++) {
+ Rect r = mTextRects.get(i);
+ canvas.drawRect(r.left-mTmpLocation[0], r.top-mTmpLocation[1],
+ r.right-mTmpLocation[0], r.bottom-mTmpLocation[1], mFramePaint);
+ }
+ }
+}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index 4639114..2cab3ea 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -16,6 +16,7 @@
package com.android.test.voiceinteraction;
+import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.service.voice.AlwaysOnHotwordDetector;
@@ -74,9 +75,19 @@
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
- Bundle args = new Bundle();
- args.putParcelable("intent", new Intent(this, TestInteractionActivity.class));
- startSession(args);
+ if (isActiveService(this, new ComponentName(this, getClass()))) {
+ Bundle args = new Bundle();
+ args.putParcelable("intent", new Intent(this, TestInteractionActivity.class));
+ args.putBundle("assist", intent.getExtras());
+ Bundle assistContext = intent.getBundleExtra(Intent.EXTRA_ASSIST_CONTEXT);
+ int startFlags = 0;
+ if (assistContext == null) {
+ startFlags |= START_WITH_ASSIST;
+ }
+ startSession(args, startFlags);
+ } else {
+ Log.w(TAG, "Not starting -- not current voice interaction service");
+ }
stopSelf(startId);
return START_NOT_STICKY;
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
index d20906e..1aeb98a 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java
@@ -16,6 +16,7 @@
package com.android.test.voiceinteraction;
+import android.app.AssistData;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
@@ -31,12 +32,17 @@
Intent mStartIntent;
View mContentView;
+ AssistVisualizer mAssistVisualizer;
+ View mTopContent;
+ View mBottomContent;
TextView mText;
Button mStartButton;
Button mConfirmButton;
Button mCompleteButton;
Button mAbortButton;
+ AssistData mAssistData;
+
static final int STATE_IDLE = 0;
static final int STATE_LAUNCHING = 1;
static final int STATE_CONFIRM = 2;
@@ -52,15 +58,25 @@
}
@Override
- public void onCreate(Bundle args) {
+ public void onCreate(Bundle args, int startFlags) {
super.onCreate(args);
showWindow();
mStartIntent = args.getParcelable("intent");
+ Bundle assist = args.getBundle("assist");
+ if (assist != null) {
+ parseAssistData(assist);
+ }
}
@Override
public View onCreateContentView() {
mContentView = getLayoutInflater().inflate(R.layout.voice_interaction_session, null);
+ mAssistVisualizer = (AssistVisualizer)mContentView.findViewById(R.id.assist_visualizer);
+ if (mAssistData != null) {
+ mAssistVisualizer.setAssistData(mAssistData);
+ }
+ mTopContent = mContentView.findViewById(R.id.top_content);
+ mBottomContent = mContentView.findViewById(R.id.bottom_content);
mText = (TextView)mContentView.findViewById(R.id.text);
mStartButton = (Button)mContentView.findViewById(R.id.start);
mStartButton.setOnClickListener(this);
@@ -74,7 +90,34 @@
return mContentView;
}
+ @Override
+ public void onHandleAssist(Bundle assistBundle) {
+ if (assistBundle != null) {
+ parseAssistData(assistBundle);
+ } else {
+ Log.i(TAG, "onHandleAssist: NO ASSIST BUNDLE");
+ }
+ }
+
+ void parseAssistData(Bundle assistBundle) {
+ Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT);
+ if (assistContext != null) {
+ mAssistData = AssistData.getAssistData(assistContext);
+ mAssistData.dump();
+ if (mAssistVisualizer != null) {
+ mAssistVisualizer.setAssistData(mAssistData);
+ }
+ }
+ }
+
void updateState() {
+ if (mState == STATE_IDLE) {
+ mTopContent.setVisibility(View.VISIBLE);
+ mBottomContent.setVisibility(View.GONE);
+ } else {
+ mTopContent.setVisibility(View.GONE);
+ mBottomContent.setVisibility(View.VISIBLE);
+ }
mStartButton.setEnabled(mState == STATE_IDLE);
mConfirmButton.setEnabled(mState == STATE_CONFIRM || mState == STATE_COMMAND);
mAbortButton.setEnabled(mState == STATE_ABORT_VOICE);
@@ -109,6 +152,15 @@
}
@Override
+ public void onComputeInsets(Insets outInsets) {
+ super.onComputeInsets(outInsets);
+ if (mState != STATE_IDLE) {
+ outInsets.contentInsets.top = mBottomContent.getTop();
+ outInsets.touchableInsets = Insets.TOUCHABLE_INSETS_CONTENT;
+ }
+ }
+
+ @Override
public boolean[] onGetSupportedCommands(Caller caller, String[] commands) {
return new boolean[commands.length];
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
index 783c78e..8522cdc 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/TestInteractionActivity.java
@@ -57,11 +57,6 @@
mCompleteButton = (Button)findViewById(R.id.complete);
mCompleteButton.setOnClickListener(this);
- // Framework should take care of these.
- getWindow().setGravity(Gravity.TOP);
- getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
-
mInteractor = getVoiceInteractor();
VoiceInteractor.ConfirmationRequest req = new VoiceInteractor.ConfirmationRequest(
"This is a confirmation", null) {
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index d90271b..32305a0 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -215,6 +215,12 @@
}
@Override
+ public void overridePendingAppTransitionClipReveal(int startX, int startY,
+ int startWidth, int startHeight) throws RemoteException {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
public void overridePendingAppTransitionThumb(Bitmap srcThumb, int startX, int startY,
IRemoteCallback startedCallback, boolean scaleUp) throws RemoteException {
// TODO Auto-generated method stub