Merge "Fix regression breaking SurfaceView in docked." into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index ed70474..1c4f85b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -7703,8 +7703,6 @@
method public void setExtras(android.os.PersistableBundle);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
- field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
- field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
diff --git a/api/system-current.txt b/api/system-current.txt
index 0896214..039b9ad 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -8001,8 +8001,6 @@
method public void setExtras(android.os.PersistableBundle);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
- field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
- field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
diff --git a/api/test-current.txt b/api/test-current.txt
index a190d95..3febda1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -7707,8 +7707,6 @@
method public void setExtras(android.os.PersistableBundle);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.content.ClipDescription> CREATOR;
- field public static final java.lang.String EXTRA_TARGET_COMPONENT_NAME = "android.content.extra.TARGET_COMPONENT_NAME";
- field public static final java.lang.String EXTRA_USER_SERIAL_NUMBER = "android.content.extra.USER_SERIAL_NUMBER";
field public static final java.lang.String MIMETYPE_TEXT_HTML = "text/html";
field public static final java.lang.String MIMETYPE_TEXT_INTENT = "text/vnd.android.intent";
field public static final java.lang.String MIMETYPE_TEXT_PLAIN = "text/plain";
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index bf823f8..56728ad 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -600,11 +600,16 @@
* Dispatch a gesture to the touch screen. Any gestures currently in progress, whether from
* the user, this service, or another service, will be cancelled.
* <p>
+ * The gesture will be dispatched as if it were performed directly on the screen by a user, so
+ * the events may be affected by features such as magnification and explore by touch.
+ * </p>
+ * <p>
* <strong>Note:</strong> In order to dispatch gestures, your service
* must declare the capability by setting the
* {@link android.R.styleable#AccessibilityService_canPerformGestures}
* property in its meta-data. For more information, see
* {@link #SERVICE_META_DATA}.
+ * </p>
*
* @param gesture The gesture to dispatch
* @param callback The object to call back when the status of the gesture is known. If
diff --git a/core/java/android/content/ClipDescription.java b/core/java/android/content/ClipDescription.java
index 1b024e2..461d1e0 100644
--- a/core/java/android/content/ClipDescription.java
+++ b/core/java/android/content/ClipDescription.java
@@ -71,6 +71,7 @@
* and {@link ComponentName#flattenToString()} to convert the extra value
* to/from {@link ComponentName}.
* </p>
+ * @hide
*/
public static final String EXTRA_TARGET_COMPONENT_NAME =
"android.content.extra.TARGET_COMPONENT_NAME";
@@ -81,6 +82,7 @@
* <p>
* Type: long
* </p>
+ * @hide
*/
public static final String EXTRA_USER_SERIAL_NUMBER =
"android.content.extra.USER_SERIAL_NUMBER";
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index df774b4..c972476 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -794,8 +794,7 @@
}
final long[] frameInfo = choreographer.mFrameInfo.mFrameInfo;
- int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length,
- mRootNode.mNativeRenderNode);
+ int syncResult = nSyncAndDrawFrame(mNativeProxy, frameInfo, frameInfo.length);
if ((syncResult & SYNC_LOST_SURFACE_REWARD_IF_FOUND) != 0) {
setEnabled(false);
attachInfo.mViewRootImpl.mSurface.release();
@@ -994,8 +993,7 @@
private static native void nSetLightCenter(long nativeProxy,
float lightX, float lightY, float lightZ);
private static native void nSetOpaque(long nativeProxy, boolean opaque);
- private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size,
- long rootRenderNode);
+ private static native int nSyncAndDrawFrame(long nativeProxy, long[] frameInfo, int size);
private static native void nDestroy(long nativeProxy, long rootRenderNode);
private static native void nRegisterAnimatingRenderNode(long rootRenderNode, long animatingNode);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b95d830..b0aa5c3 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -20424,21 +20424,21 @@
* the touch point.
* </p>
*
- * @param shadowSize A {@link android.graphics.Point} containing the width and height
+ * @param outShadowSize A {@link android.graphics.Point} containing the width and height
* of the shadow image. Your application must set {@link android.graphics.Point#x} to the
* desired width and must set {@link android.graphics.Point#y} to the desired height of the
* image.
*
- * @param shadowTouchPoint A {@link android.graphics.Point} for the position within the
+ * @param outShadowTouchPoint A {@link android.graphics.Point} for the position within the
* shadow image that should be underneath the touch point during the drag and drop
* operation. Your application must set {@link android.graphics.Point#x} to the
* X coordinate and {@link android.graphics.Point#y} to the Y coordinate of this position.
*/
- public void onProvideShadowMetrics(Point shadowSize, Point shadowTouchPoint) {
+ public void onProvideShadowMetrics(Point outShadowSize, Point outShadowTouchPoint) {
final View view = mView.get();
if (view != null) {
- shadowSize.set(view.getWidth(), view.getHeight());
- shadowTouchPoint.set(shadowSize.x / 2, shadowSize.y / 2);
+ outShadowSize.set(view.getWidth(), view.getHeight());
+ outShadowTouchPoint.set(outShadowSize.x / 2, outShadowSize.y / 2);
} else {
Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
}
diff --git a/core/java/com/android/internal/view/menu/StandardMenuPopup.java b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
index d8ed92d..339c2bf 100644
--- a/core/java/com/android/internal/view/menu/StandardMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/StandardMenuPopup.java
@@ -208,7 +208,7 @@
@Override
public void show() {
if (!tryShow()) {
- throw new IllegalStateException("MenuPopupHelper cannot be used without an anchor");
+ throw new IllegalStateException("StandardMenuPopup cannot be used without an anchor");
}
}
@@ -273,7 +273,7 @@
mOnDismissListener = null;
// Close this menu popup to make room for the submenu popup.
- dismiss();
+ mMenu.close(false /* closeAllMenus */);
// Show the new sub-menu popup at the same location as this popup.
if (subPopup.tryShow(mXOffset, mYOffset)) {
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index 27e2ee8..4459f32 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -128,9 +128,22 @@
static void android_view_RenderNode_setDisplayList(JNIEnv* env,
jobject clazz, jlong renderNodePtr, jlong displayListPtr) {
+ class RemovedObserver : public TreeObserver {
+ public:
+ virtual void onMaybeRemovedFromTree(RenderNode* node) override {
+ maybeRemovedNodes.insert(sp<RenderNode>(node));
+ }
+ std::set< sp<RenderNode> > maybeRemovedNodes;
+ };
+
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
DisplayList* newData = reinterpret_cast<DisplayList*>(displayListPtr);
- renderNode->setStagingDisplayList(newData);
+ RemovedObserver observer;
+ renderNode->setStagingDisplayList(newData, &observer);
+ for (auto& node : observer.maybeRemovedNodes) {
+ if (node->hasParents()) continue;
+ onRenderNodeRemoved(env, node.get());
+ }
}
// ----------------------------------------------------------------------------
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 14252dc..21e4d2f 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -525,7 +525,7 @@
UiFrameInfoBuilder(proxy->frameInfo())
.setVsync(vsync, vsync)
.addFlag(FrameInfoFlags::SurfaceCanvas);
- proxy->syncAndDrawFrame();
+ proxy->syncAndDrawFrame(nullptr);
}
static void destroy(JNIEnv* env, jclass clazz, jlong rendererPtr) {
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 8019326..3d65209 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -72,6 +72,31 @@
return env;
}
+// TODO: Clean this up, it's a bit odd to need to call over to
+// rendernode's jni layer. Probably means RootRenderNode should be pulled
+// into HWUI with appropriate callbacks for the various JNI hooks so
+// that RenderNode's JNI layer can handle its own thing
+void onRenderNodeRemoved(JNIEnv* env, RenderNode* node);
+
+class ScopedRemovedRenderNodeObserver : public TreeObserver {
+public:
+ ScopedRemovedRenderNodeObserver(JNIEnv* env) : mEnv(env) {}
+ ~ScopedRemovedRenderNodeObserver() {
+ for (auto& node : mMaybeRemovedNodes) {
+ if (node->hasParents()) continue;
+ onRenderNodeRemoved(mEnv, node.get());
+ }
+ }
+
+ virtual void onMaybeRemovedFromTree(RenderNode* node) override {
+ mMaybeRemovedNodes.insert(sp<RenderNode>(node));
+ }
+
+private:
+ JNIEnv* mEnv;
+ std::set< sp<RenderNode> > mMaybeRemovedNodes;
+};
+
class OnFinishedEvent {
public:
OnFinishedEvent(BaseRenderNodeAnimator* animator, AnimationListener* listener)
@@ -120,13 +145,7 @@
std::string mMessage;
};
-// TODO: Clean this up, it's a bit odd to need to call over to
-// rendernode's jni layer. Probably means RootRenderNode should be pulled
-// into HWUI with appropriate callbacks for the various JNI hooks so
-// that RenderNode's JNI layer can handle its own thing
-void onRenderNodeRemoved(JNIEnv* env, RenderNode* node);
-
-class RootRenderNode : public RenderNode, ErrorHandler, TreeObserver {
+class RootRenderNode : public RenderNode, ErrorHandler {
public:
RootRenderNode(JNIEnv* env) : RenderNode() {
mLooper = Looper::getForThread();
@@ -143,9 +162,6 @@
virtual void prepareTree(TreeInfo& info) override {
info.errorHandler = this;
- if (info.mode == TreeInfo::MODE_FULL) {
- info.observer = this;
- }
// TODO: This is hacky
info.windowInsetLeft = -stagingProperties().getLeft();
info.windowInsetTop = -stagingProperties().getTop();
@@ -155,7 +171,6 @@
info.windowInsetLeft = 0;
info.windowInsetTop = 0;
info.errorHandler = nullptr;
- info.observer = nullptr;
}
void sendMessage(const sp<MessageHandler>& handler) {
@@ -181,27 +196,10 @@
mPendingAnimatingRenderNodes.clear();
}
- virtual void onMaybeRemovedFromTree(RenderNode* node) override {
- mMaybeRemovedNodes.insert(sp<RenderNode>(node));
- }
-
- void processMaybeRemovedNodes(JNIEnv* env) {
- // We can safely access mMaybeRemovedNodes here because
- // we will only modify it in prepareTree calls that are
- // MODE_FULL
-
- for (auto& node : mMaybeRemovedNodes) {
- if (node->hasParents()) continue;
- onRenderNodeRemoved(env, node.get());
- }
- mMaybeRemovedNodes.clear();
- }
-
private:
sp<Looper> mLooper;
JavaVM* mVm;
std::vector< sp<RenderNode> > mPendingAnimatingRenderNodes;
- std::set< sp<RenderNode> > mMaybeRemovedNodes;
};
class AnimationContextBridge : public AnimationContext {
@@ -500,24 +498,23 @@
}
static int android_view_ThreadedRenderer_syncAndDrawFrame(JNIEnv* env, jobject clazz,
- jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize, jlong rootNodePtr) {
+ jlong proxyPtr, jlongArray frameInfo, jint frameInfoSize) {
LOG_ALWAYS_FATAL_IF(frameInfoSize != UI_THREAD_FRAME_INFO_SIZE,
"Mismatched size expectations, given %d expected %d",
frameInfoSize, UI_THREAD_FRAME_INFO_SIZE);
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
+ ScopedRemovedRenderNodeObserver observer(env);
env->GetLongArrayRegion(frameInfo, 0, frameInfoSize, proxy->frameInfo());
- int ret = proxy->syncAndDrawFrame();
- rootRenderNode->processMaybeRemovedNodes(env);
- return ret;
+ return proxy->syncAndDrawFrame(&observer);
}
static void android_view_ThreadedRenderer_destroy(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong rootNodePtr) {
+ ScopedRemovedRenderNodeObserver observer(env);
RootRenderNode* rootRenderNode = reinterpret_cast<RootRenderNode*>(rootNodePtr);
rootRenderNode->destroy();
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- proxy->destroy();
+ proxy->destroy(&observer);
}
static void android_view_ThreadedRenderer_registerAnimatingRenderNode(JNIEnv* env, jobject clazz,
@@ -542,9 +539,10 @@
static void android_view_ThreadedRenderer_buildLayer(JNIEnv* env, jobject clazz,
jlong proxyPtr, jlong nodePtr) {
+ ScopedRemovedRenderNodeObserver observer(env);
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
RenderNode* node = reinterpret_cast<RenderNode*>(nodePtr);
- proxy->buildLayer(node);
+ proxy->buildLayer(node, &observer);
}
static jboolean android_view_ThreadedRenderer_copyLayerInto(JNIEnv* env, jobject clazz,
@@ -579,8 +577,9 @@
static void android_view_ThreadedRenderer_destroyHardwareResources(JNIEnv* env, jobject clazz,
jlong proxyPtr) {
+ ScopedRemovedRenderNodeObserver observer(env);
RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
- proxy->destroyHardwareResources();
+ proxy->destroyHardwareResources(&observer);
}
static void android_view_ThreadedRenderer_trimMemory(JNIEnv* env, jobject clazz,
@@ -736,7 +735,7 @@
{ "nSetup", "(JIIFII)V", (void*) android_view_ThreadedRenderer_setup },
{ "nSetLightCenter", "(JFFF)V", (void*) android_view_ThreadedRenderer_setLightCenter },
{ "nSetOpaque", "(JZ)V", (void*) android_view_ThreadedRenderer_setOpaque },
- { "nSyncAndDrawFrame", "(J[JIJ)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
+ { "nSyncAndDrawFrame", "(J[JI)I", (void*) android_view_ThreadedRenderer_syncAndDrawFrame },
{ "nDestroy", "(JJ)V", (void*) android_view_ThreadedRenderer_destroy },
{ "nRegisterAnimatingRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_registerAnimatingRenderNode },
{ "nInvokeFunctor", "(JZ)V", (void*) android_view_ThreadedRenderer_invokeFunctor },
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 9578486..ea06fcd 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -81,14 +81,14 @@
#endif
}
-void RenderNode::setStagingDisplayList(DisplayList* displayList) {
+void RenderNode::setStagingDisplayList(DisplayList* displayList, TreeObserver* observer) {
mNeedsDisplayListSync = true;
delete mStagingDisplayList;
mStagingDisplayList = displayList;
// If mParentCount == 0 we are the sole reference to this RenderNode,
// so immediately free the old display list
if (!mParentCount && !mStagingDisplayList) {
- deleteDisplayList(nullptr);
+ deleteDisplayList(observer);
}
}
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index b0136cf..acdc3d8 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -117,7 +117,7 @@
void debugDumpLayers(const char* prefix);
- ANDROID_API void setStagingDisplayList(DisplayList* newData);
+ ANDROID_API void setStagingDisplayList(DisplayList* newData, TreeObserver* observer);
void computeOrdering();
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 63fa788..ab66b2a 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -76,15 +76,15 @@
}
CanvasContext::~CanvasContext() {
- destroy();
+ destroy(nullptr);
mRenderThread.renderState().unregisterCanvasContext(this);
}
-void CanvasContext::destroy() {
+void CanvasContext::destroy(TreeObserver* observer) {
stopDrawing();
setSurface(nullptr);
- freePrefetechedLayers();
- destroyHardwareResources();
+ freePrefetchedLayers(observer);
+ destroyHardwareResources(observer);
mAnimationContext->destroy();
#if !HWUI_NEW_OPS
if (mCanvas) {
@@ -222,7 +222,7 @@
mAnimationContext->runRemainingAnimations(info);
GL_CHECKPOINT(MODERATE);
- freePrefetechedLayers();
+ freePrefetchedLayers(info.observer);
GL_CHECKPOINT(MODERATE);
if (CC_UNLIKELY(!mNativeSurface.get())) {
@@ -569,25 +569,24 @@
}
void CanvasContext::markLayerInUse(RenderNode* node) {
- if (mPrefetechedLayers.erase(node)) {
+ if (mPrefetchedLayers.erase(node)) {
node->decStrong(nullptr);
}
}
-static void destroyPrefetechedNode(RenderNode* node) {
- ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...", node->getName());
- node->destroyHardwareResources(nullptr);
- node->decStrong(nullptr);
-}
-
-void CanvasContext::freePrefetechedLayers() {
- if (mPrefetechedLayers.size()) {
- std::for_each(mPrefetechedLayers.begin(), mPrefetechedLayers.end(), destroyPrefetechedNode);
- mPrefetechedLayers.clear();
+void CanvasContext::freePrefetchedLayers(TreeObserver* observer) {
+ if (mPrefetchedLayers.size()) {
+ for (auto& node : mPrefetchedLayers) {
+ ALOGW("Incorrectly called buildLayer on View: %s, destroying layer...",
+ node->getName());
+ node->destroyHardwareResources(observer);
+ node->decStrong(observer);
+ }
+ mPrefetchedLayers.clear();
}
}
-void CanvasContext::buildLayer(RenderNode* node) {
+void CanvasContext::buildLayer(RenderNode* node, TreeObserver* observer) {
ATRACE_CALL();
if (!mEglManager.hasEglContext()) return;
#if !HWUI_NEW_OPS
@@ -599,6 +598,7 @@
TreeInfo info(TreeInfo::MODE_FULL, *this);
info.damageAccumulator = &mDamageAccumulator;
+ info.observer = observer;
#if HWUI_NEW_OPS
info.layerUpdateQueue = &mLayerUpdateQueue;
#else
@@ -628,7 +628,7 @@
#endif
node->incStrong(nullptr);
- mPrefetechedLayers.insert(node);
+ mPrefetchedLayers.insert(node);
}
bool CanvasContext::copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap) {
@@ -636,12 +636,12 @@
return LayerRenderer::copyLayer(mRenderThread.renderState(), layer->backingLayer(), bitmap);
}
-void CanvasContext::destroyHardwareResources() {
+void CanvasContext::destroyHardwareResources(TreeObserver* observer) {
stopDrawing();
if (mEglManager.hasEglContext()) {
- freePrefetechedLayers();
+ freePrefetchedLayers(observer);
for (const sp<RenderNode>& node : mRenderNodes) {
- node->destroyHardwareResources(nullptr);
+ node->destroyHardwareResources(observer);
}
Caches& caches = Caches::getInstance();
// Make sure to release all the textures we were owning as there won't
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 6d0889e..9350114 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -92,17 +92,17 @@
void prepareTree(TreeInfo& info, int64_t* uiFrameInfo,
int64_t syncQueued, RenderNode* target);
void draw();
- void destroy();
+ void destroy(TreeObserver* observer);
// IFrameCallback, Choreographer-driven frame callback entry point
virtual void doFrame() override;
void prepareAndDraw(RenderNode* node);
- void buildLayer(RenderNode* node);
+ void buildLayer(RenderNode* node, TreeObserver* observer);
bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap* bitmap);
void markLayerInUse(RenderNode* node);
- void destroyHardwareResources();
+ void destroyHardwareResources(TreeObserver* observer);
static void trimMemory(RenderThread& thread, int level);
static void invokeFunctor(RenderThread& thread, Functor* functor);
@@ -174,7 +174,7 @@
void setSurface(Surface* window);
void requireSurface();
- void freePrefetechedLayers();
+ void freePrefetchedLayers(TreeObserver* observer);
void waitOnFences();
@@ -218,7 +218,7 @@
FrameInfoVisualizer mProfiler;
std::unique_ptr<FrameMetricsReporter> mFrameMetricsReporter;
- std::set<RenderNode*> mPrefetechedLayers;
+ std::set<RenderNode*> mPrefetchedLayers;
// Stores the bounds of the main content.
Rect mContentDrawBounds;
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index e8b9725..651aaa2 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -65,11 +65,12 @@
}
}
-int DrawFrameTask::drawFrame() {
+int DrawFrameTask::drawFrame(TreeObserver* observer) {
LOG_ALWAYS_FATAL_IF(!mContext, "Cannot drawFrame with no CanvasContext!");
mSyncResult = kSync_OK;
mSyncQueued = systemTime(CLOCK_MONOTONIC);
+ mObserver = observer;
postAndWait();
return mSyncResult;
@@ -88,6 +89,7 @@
bool canDrawThisFrame;
{
TreeInfo info(TreeInfo::MODE_FULL, *mContext);
+ info.observer = mObserver;
canUnblockUiThread = syncFrameState(info);
canDrawThisFrame = info.out.canDrawThisFrame;
}
diff --git a/libs/hwui/renderthread/DrawFrameTask.h b/libs/hwui/renderthread/DrawFrameTask.h
index cae251a9..9bba065 100644
--- a/libs/hwui/renderthread/DrawFrameTask.h
+++ b/libs/hwui/renderthread/DrawFrameTask.h
@@ -62,7 +62,7 @@
void pushLayerUpdate(DeferredLayerUpdater* layer);
void removeLayerUpdate(DeferredLayerUpdater* layer);
- int drawFrame();
+ int drawFrame(TreeObserver* observer);
int64_t* frameInfo() { return mFrameInfo; }
@@ -87,6 +87,7 @@
int mSyncResult;
int64_t mSyncQueued;
+ TreeObserver* mObserver;
int64_t mFrameInfo[UI_THREAD_FRAME_INFO_SIZE];
};
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 16dd108..2e99d0b 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -222,18 +222,19 @@
return mDrawFrameTask.frameInfo();
}
-int RenderProxy::syncAndDrawFrame() {
- return mDrawFrameTask.drawFrame();
+int RenderProxy::syncAndDrawFrame(TreeObserver* observer) {
+ return mDrawFrameTask.drawFrame(observer);
}
-CREATE_BRIDGE1(destroy, CanvasContext* context) {
- args->context->destroy();
+CREATE_BRIDGE2(destroy, CanvasContext* context, TreeObserver* observer) {
+ args->context->destroy(args->observer);
return nullptr;
}
-void RenderProxy::destroy() {
+void RenderProxy::destroy(TreeObserver* observer) {
SETUP_TASK(destroy);
args->context = mContext;
+ args->observer = observer;
// destroyCanvasAndSurface() needs a fence as when it returns the
// underlying BufferQueue is going to be released from under
// the render thread.
@@ -287,15 +288,16 @@
return layer;
}
-CREATE_BRIDGE2(buildLayer, CanvasContext* context, RenderNode* node) {
- args->context->buildLayer(args->node);
+CREATE_BRIDGE3(buildLayer, CanvasContext* context, RenderNode* node, TreeObserver* observer) {
+ args->context->buildLayer(args->node, args->observer);
return nullptr;
}
-void RenderProxy::buildLayer(RenderNode* node) {
+void RenderProxy::buildLayer(RenderNode* node, TreeObserver* observer) {
SETUP_TASK(buildLayer);
args->context = mContext;
args->node = node;
+ args->observer = observer;
postAndWait(task);
}
@@ -332,15 +334,16 @@
postAndWait(task);
}
-CREATE_BRIDGE1(destroyHardwareResources, CanvasContext* context) {
- args->context->destroyHardwareResources();
+CREATE_BRIDGE2(destroyHardwareResources, CanvasContext* context, TreeObserver* observer) {
+ args->context->destroyHardwareResources(args->observer);
return nullptr;
}
-void RenderProxy::destroyHardwareResources() {
+void RenderProxy::destroyHardwareResources(TreeObserver* observer) {
SETUP_TASK(destroyHardwareResources);
args->context = mContext;
- post(task);
+ args->observer = observer;
+ postAndWait(task);
}
CREATE_BRIDGE2(trimMemory, RenderThread* thread, int level) {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 8d65a82..97194fe 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -42,6 +42,7 @@
class DisplayList;
class Layer;
class Rect;
+class TreeObserver;
namespace renderthread {
@@ -75,21 +76,21 @@
ANDROID_API void setLightCenter(const Vector3& lightCenter);
ANDROID_API void setOpaque(bool opaque);
ANDROID_API int64_t* frameInfo();
- ANDROID_API int syncAndDrawFrame();
- ANDROID_API void destroy();
+ ANDROID_API int syncAndDrawFrame(TreeObserver* observer);
+ ANDROID_API void destroy(TreeObserver* observer);
ANDROID_API static void invokeFunctor(Functor* functor, bool waitForCompletion);
ANDROID_API void runWithGlContext(RenderTask* task);
ANDROID_API DeferredLayerUpdater* createTextureLayer();
- ANDROID_API void buildLayer(RenderNode* node);
+ ANDROID_API void buildLayer(RenderNode* node, TreeObserver* observer);
ANDROID_API bool copyLayerInto(DeferredLayerUpdater* layer, SkBitmap& bitmap);
ANDROID_API void pushLayerUpdate(DeferredLayerUpdater* layer);
ANDROID_API void cancelLayerUpdate(DeferredLayerUpdater* layer);
ANDROID_API void detachSurfaceTexture(DeferredLayerUpdater* layer);
- ANDROID_API void destroyHardwareResources();
+ ANDROID_API void destroyHardwareResources(TreeObserver* observer);
ANDROID_API static void trimMemory(int level);
ANDROID_API static void overrideProperty(const char* name, const char* value);
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 5492035..5f4ebc0 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -146,7 +146,7 @@
if (setup) {
TestCanvas canvas(props.getWidth(), props.getHeight());
setup(props, canvas);
- node->setStagingDisplayList(canvas.finishRecording());
+ node->setStagingDisplayList(canvas.finishRecording(), nullptr);
}
node->setPropertyFieldsDirty(0xFFFFFFFF);
return node;
@@ -157,7 +157,7 @@
TestCanvas canvas(node.stagingProperties().getWidth(),
node.stagingProperties().getHeight());
contentCallback(canvas);
- node.setStagingDisplayList(canvas.finishRecording());
+ node.setStagingDisplayList(canvas.finishRecording(), nullptr);
}
/**
diff --git a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
index 63c067b..f184411 100644
--- a/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/GlyphStressAnimation.cpp
@@ -59,6 +59,6 @@
0, 100 * (i + 2), kBidi_Force_LTR, paint, nullptr);
}
- container->setStagingDisplayList(canvas.finishRecording());
+ container->setStagingDisplayList(canvas.finishRecording(), nullptr);
}
};
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index ab368c05..8035dc4 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -76,7 +76,7 @@
// draw it to parent DisplayList
canvas.drawRenderNode(cards[ci].get());
}
- listView->setStagingDisplayList(canvas.finishRecording());
+ listView->setStagingDisplayList(canvas.finishRecording(), nullptr);
}
private:
SkBitmap createRandomCharIcon() {
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index 58c0876..cc0fdd5 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -95,7 +95,7 @@
testContext.waitForVsync();
nsecs_t vsync = systemTime(CLOCK_MONOTONIC);
UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
- proxy->syncAndDrawFrame();
+ proxy->syncAndDrawFrame(nullptr);
}
proxy->resetProfileInfo();
@@ -110,7 +110,7 @@
ATRACE_NAME("UI-Draw Frame");
UiFrameInfoBuilder(proxy->frameInfo()).setVsync(vsync, vsync);
scene->doFrame(i);
- proxy->syncAndDrawFrame();
+ proxy->syncAndDrawFrame(nullptr);
}
if (opts.reportFrametimeWeight) {
proxy->fence();
diff --git a/libs/hwui/utils/TestWindowContext.cpp b/libs/hwui/utils/TestWindowContext.cpp
index b0431ce..b3195c4 100644
--- a/libs/hwui/utils/TestWindowContext.cpp
+++ b/libs/hwui/utils/TestWindowContext.cpp
@@ -104,8 +104,8 @@
}
void finishDrawing() {
- mRootNode->setStagingDisplayList(mCanvas->finishRecording());
- mProxy->syncAndDrawFrame();
+ mRootNode->setStagingDisplayList(mCanvas->finishRecording(), nullptr);
+ mProxy->syncAndDrawFrame(nullptr);
// Surprisingly, calling mProxy->fence() here appears to make no difference to
// the timings we record.
}
diff --git a/media/java/android/media/tv/TvRecordingClient.java b/media/java/android/media/tv/TvRecordingClient.java
index a5ff29f..2613376 100644
--- a/media/java/android/media/tv/TvRecordingClient.java
+++ b/media/java/android/media/tv/TvRecordingClient.java
@@ -158,7 +158,7 @@
* <p>The application may supply the URI for a TV program for filling in program specific data
* fields in the {@link android.media.tv.TvContract.RecordedPrograms} table.
* A non-null {@code programHint} implies the started recording should be of that specific
- * program, whereas null {@code programHint} does not impose such a requirement and the
+ * program, whereas null {@code programUri} does not impose such a requirement and the
* recording can span across multiple TV programs. In either case, the application must call
* {@link TvRecordingClient#stopRecording()} to stop the recording.
*
diff --git a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
index 6eea81b..7dba545 100644
--- a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java
@@ -148,8 +148,9 @@
protected void onDraw(Canvas canvas) {
float totalDrawingWidth = getDrawingWidth();
float currentDrawPosition;
- if ((mGravity & Gravity.START) != 0) {
- if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
+ if ((mGravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.LEFT) {
+ if ((mGravity & Gravity.RELATIVE_LAYOUT_DIRECTION) != 0
+ && getLayoutDirection() == LAYOUT_DIRECTION_RTL) {
currentDrawPosition = getWidth() - getPaddingRight() - totalDrawingWidth;
} else {
currentDrawPosition = getPaddingLeft();
@@ -163,7 +164,7 @@
float yPosition =
(getHeight() - getPaddingBottom() - getPaddingTop()) / 2 + getPaddingTop();
canvas.clipRect(getPaddingLeft(), getPaddingTop(),
- getWidth()-getPaddingRight(), getHeight()-getPaddingBottom());
+ getWidth() - getPaddingRight(), getHeight() - getPaddingBottom());
float charLength = bounds.right - bounds.left;
for (int i = 0; i < length; i++) {
CharState charState = mTextChars.get(i);
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
index 6052ccd..7f0e27a 100755
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java
@@ -399,6 +399,9 @@
// Copy previous profile list into removedProfiles
removedProfiles.clear();
removedProfiles.addAll(profiles);
+ if (DEBUG) {
+ Log.d(TAG,"Current Profiles" + profiles.toString());
+ }
profiles.clear();
if (uuids == null) {
@@ -415,6 +418,13 @@
}
}
+ if ((mHfpClientProfile != null) &&
+ BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Handsfree_AG) &&
+ BluetoothUuid.isUuidPresent(localUuids, BluetoothUuid.Handsfree)) {
+ profiles.add(mHfpClientProfile);
+ removedProfiles.remove(mHfpClientProfile);
+ }
+
if (BluetoothUuid.containsAnyUuid(uuids, A2dpProfile.SINK_UUIDS) &&
mA2dpProfile != null) {
profiles.add(mA2dpProfile);
@@ -425,7 +435,7 @@
mA2dpSinkProfile != null) {
profiles.add(mA2dpSinkProfile);
removedProfiles.remove(mA2dpSinkProfile);
- }
+ }
if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.ObexObjectPush) &&
mOppProfile != null) {
@@ -461,5 +471,9 @@
profiles.remove(mPbapProfile);
removedProfiles.add(mPbapProfile);
}
+
+ if (DEBUG) {
+ Log.d(TAG,"New Profiles" + profiles.toString());
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index aba05aa..957c94b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -17,6 +17,7 @@
package com.android.systemui.recents;
import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
+import static android.view.View.MeasureSpec;
import android.app.ActivityManager;
import android.app.ActivityOptions;
@@ -36,7 +37,6 @@
import android.util.MutableBoolean;
import android.view.AppTransitionAnimationSpec;
import android.view.LayoutInflater;
-import android.view.View;
import android.view.ViewConfiguration;
import com.android.internal.logging.MetricsLogger;
@@ -608,23 +608,25 @@
mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
- int taskViewWidth = taskViewBounds.width();
- synchronized (mHeaderBarLock) {
- if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
- mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
- mHeaderBar.measure(
- View.MeasureSpec.makeMeasureSpec(taskViewWidth, View.MeasureSpec.EXACTLY),
- View.MeasureSpec.makeMeasureSpec(mTaskBarHeight, View.MeasureSpec.EXACTLY));
+ if (!taskViewBounds.isEmpty()) {
+ int taskViewWidth = taskViewBounds.width();
+ synchronized (mHeaderBarLock) {
+ if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
+ mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
+ mHeaderBar.measure(
+ MeasureSpec.makeMeasureSpec(taskViewWidth, MeasureSpec.EXACTLY),
+ MeasureSpec.makeMeasureSpec(mTaskBarHeight, MeasureSpec.EXACTLY));
+ }
+ mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
}
- mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
- }
- // Update the transition bitmap to match the new header bar height
- if (mThumbTransitionBitmapCache == null ||
- (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
- (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
- mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
- mTaskBarHeight, Bitmap.Config.ARGB_8888);
+ // Update the transition bitmap to match the new header bar height
+ if (mThumbTransitionBitmapCache == null ||
+ (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
+ (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
+ mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
+ mTaskBarHeight, Bitmap.Config.ARGB_8888);
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
index 9a9e33b..fd31872 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
@@ -32,8 +32,10 @@
import com.android.systemui.recents.RecentsImpl;
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent;
+import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.RecentsTaskLoader;
import com.android.systemui.recents.model.TaskStack;
+import com.android.systemui.recents.model.ThumbnailData;
import com.android.systemui.recents.tv.views.TaskCardView;
import com.android.systemui.statusbar.tv.TvStatusBar;
@@ -117,12 +119,15 @@
*/
private ActivityOptions getThumbnailTransitionActivityOptionsForTV(
ActivityManager.RunningTaskInfo topTask) {
- Bitmap thumbnail = mThumbTransitionBitmapCache;
Rect rect = TaskCardView.getStartingCardThumbnailRect(mContext);
- if (thumbnail != null) {
+ SystemServicesProxy ssp = Recents.getSystemServices();
+ ThumbnailData thumbnailData = ssp.getTaskThumbnail(topTask.id);
+ if (thumbnailData.thumbnail != null) {
+ Bitmap thumbnail = Bitmap.createScaledBitmap(thumbnailData.thumbnail, rect.width(),
+ rect.height(), false);
return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
- null, (int) rect.left, (int) rect.top,
- (int) rect.width(), (int) rect.height(), mHandler, null);
+ thumbnail, (int) rect.left, (int) rect.top, (int) rect.width(),
+ (int) rect.height(), mHandler, null);
}
// If both the screenshot and thumbnail fails, then just fall back to the default transition
return getUnknownTransitionActivityOptions();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java
index a69f8a2..fb1127e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvTransitionHelper.java
@@ -16,8 +16,10 @@
package com.android.systemui.recents.tv.views;
import android.annotation.Nullable;
+import android.app.Activity;
import android.app.ActivityOptions;
import android.content.Context;
+import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
@@ -120,8 +122,10 @@
}
try {
Rect taskRect = taskView.getFocusedThumbnailRect();
+ Bitmap thumbnail = Bitmap.createScaledBitmap(task.thumbnail, taskRect.width(),
+ taskRect.height(), false);
WindowManagerGlobal.getWindowManagerService()
- .overridePendingAppTransitionAspectScaledThumb(task.thumbnail, taskRect.left,
+ .overridePendingAppTransitionAspectScaledThumb(thumbnail, taskRect.left,
taskRect.top, taskRect.width(), taskRect.height(), callback, true);
} catch (RemoteException e) {
Log.w(TAG, "Failed to override transition: " + e);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
index 9e4abac..53fdf62 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java
@@ -18,7 +18,10 @@
import android.content.Context;
import android.graphics.Rect;
import android.os.Handler;
+import android.support.v7.widget.DefaultItemAnimator;
+import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowInsets;
@@ -32,15 +35,15 @@
import com.android.systemui.recents.events.EventBus;
import com.android.systemui.recents.events.activity.CancelEnterRecentsWindowAnimationEvent;
import com.android.systemui.recents.events.activity.DismissRecentsToHomeAnimationStarted;
+import com.android.systemui.recents.events.activity.ExitRecentsWindowFirstAnimationFrameEvent;
import com.android.systemui.recents.events.activity.LaunchTvTaskEvent;
import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent;
import com.android.systemui.recents.misc.SystemServicesProxy;
import com.android.systemui.recents.model.Task;
import com.android.systemui.recents.model.TaskStack;
import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder;
-
-import java.util.ArrayList;
-import java.util.List;
+import android.support.v7.widget.RecyclerView.OnScrollListener;
+import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
/**
* Top level layout of recents for TV. This will show the TaskStacks using a HorizontalGridView.
@@ -58,7 +61,7 @@
private Rect mSystemInsets = new Rect();
private RecentsTvTransitionHelper mTransitionHelper;
private Handler mHandler;
-
+ private OnScrollListener mScrollListener;
public RecentsTvView(Context context) {
this(context, null);
}
@@ -111,8 +114,7 @@
if (mTaskStackHorizontalView != null) {
Task task = mTaskStackHorizontalView.getFocusedTask();
if (task != null) {
- SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+ launchTaskFomRecents(task);
return true;
}
}
@@ -125,25 +127,53 @@
TaskStack stack = mTaskStackHorizontalView.getStack();
Task task = stack.getLaunchTarget();
if (task != null) {
- SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+ launchTaskFomRecents(task);
return true;
}
}
return false;
}
- /** Launches a given task. */
- public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
- if (mTaskStackHorizontalView != null) {
- // Iterate the stack views and try and find the given task.
- if (mTaskStackHorizontalView.getChildViewForTask(task) != null) {
- SystemServicesProxy ssp = Recents.getSystemServices();
- ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
- return true;
+ /**
+ * Launch the given task from recents with animation. If the task is not focused, this will
+ * attempt to scroll to focus the task before launching.
+ * @param task
+ */
+ private void launchTaskFomRecents(final Task task) {
+ if(task != mTaskStackHorizontalView.getFocusedTask()) {
+ if(mScrollListener != null) {
+ mTaskStackHorizontalView.removeOnScrollListener(mScrollListener);
}
+ mScrollListener = new OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+ super.onScrollStateChanged(recyclerView, newState);
+ if(newState == RecyclerView.SCROLL_STATE_IDLE) {
+ TaskCardView cardView = mTaskStackHorizontalView.getChildViewForTask(task);
+ if(cardView != null) {
+ mTransitionHelper.launchTaskFromRecents(mStack, task,
+ mTaskStackHorizontalView, cardView, null, INVALID_STACK_ID);
+ } else {
+ // This should not happen normally. If this happens then the data in
+ // the grid view was altered during the scroll. Log error and launch
+ // task with no animation.
+ Log.e(TAG, "Card view for task : " + task + ", returned null.");
+ SystemServicesProxy ssp = Recents.getSystemServices();
+ ssp.startActivityFromRecents(getContext(), task.key, task.title, null);
+ }
+ mTaskStackHorizontalView.removeOnScrollListener(mScrollListener);
+ }
+ }
+ };
+ mTaskStackHorizontalView.addOnScrollListener(mScrollListener);
+ mTaskStackHorizontalView.setSelectedPositionSmooth(
+ ((TaskStackHorizontalViewAdapter) mTaskStackHorizontalView.getAdapter())
+ .getPositionOfTask(task));
+ } else {
+ mTransitionHelper.launchTaskFromRecents(mStack, task, mTaskStackHorizontalView,
+ mTaskStackHorizontalView.getChildViewForTask(task), null,
+ INVALID_STACK_ID);
}
- return false;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
index e1f8699..99d478b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java
@@ -92,13 +92,6 @@
public Rect getFocusedThumbnailRect() {
Rect r = new Rect();
mThumbnailView.getGlobalVisibleRect(r);
- TypedValue out = new TypedValue();
- getContext().getResources().getValue(R.integer.selected_scale, out, true);
- float deltaScale = (out.getFloat() - 1.0f) / 2;
- r.set((int) (r.left - r.left * deltaScale),
- (int) (r.top - r.top * deltaScale),
- (int) (r.right + r.right * deltaScale),
- (int) (r.bottom + r.bottom * deltaScale));
return r;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
index 3788719..97712ea 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalViewAdapter.java
@@ -131,4 +131,9 @@
mTaskList.remove(position);
notifyItemRemoved(position);
}
+
+ public int getPositionOfTask(Task task) {
+ int position = mTaskList.indexOf(task);
+ return (position >= 0) ? position : 0;
+ }
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 3e7466f..613f890 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -363,12 +363,6 @@
private void enableFeatures() {
resetStreamState();
- if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) {
- mMotionEventInjector = new MotionEventInjector(mContext.getMainLooper());
- addFirstEventHandler(mMotionEventInjector);
- mAms.setMotionEventInjector(mMotionEventInjector);
- }
-
if ((mEnabledFeatures & FLAG_FEATURE_AUTOCLICK) != 0) {
mAutoclickController = new AutoclickController(mContext, mUserId);
addFirstEventHandler(mAutoclickController);
@@ -384,6 +378,12 @@
addFirstEventHandler(mMagnificationGestureHandler);
}
+ if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) {
+ mMotionEventInjector = new MotionEventInjector(mContext.getMainLooper());
+ addFirstEventHandler(mMotionEventInjector);
+ mAms.setMotionEventInjector(mMotionEventInjector);
+ }
+
if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) {
mKeyboardInterceptor = new KeyboardInterceptor(mAms);
addFirstEventHandler(mKeyboardInterceptor);
diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
index b2196bf..fb1ef37 100644
--- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java
@@ -156,10 +156,10 @@
final float offsetY = sentSpec.offsetY;
// Compute the new center and update spec as needed.
- final float centerX = (mMagnifiedBounds.width() / 2.0f
- + mMagnifiedBounds.left - offsetX) / scale;
- final float centerY = (mMagnifiedBounds.height() / 2.0f
- + mMagnifiedBounds.top - offsetY) / scale;
+ final float centerX = (mMagnifiedBounds.width() / 2.0f - offsetX) / scale
+ + mMagnifiedBounds.left;
+ final float centerY = (mMagnifiedBounds.height() / 2.0f - offsetY) / scale
+ + mMagnifiedBounds.top;
if (updateSpec) {
setScaleAndCenter(scale, centerX, centerY, false);
} else {
@@ -256,7 +256,7 @@
public float getCenterX() {
synchronized (mLock) {
return (mMagnifiedBounds.width() / 2.0f
- + mMagnifiedBounds.left - getOffsetX()) / getScale();
+ - getOffsetX()) / getScale() + mMagnifiedBounds.left;
}
}
@@ -279,7 +279,7 @@
public float getCenterY() {
synchronized (mLock) {
return (mMagnifiedBounds.height() / 2.0f
- + mMagnifiedBounds.top - getOffsetY()) / getScale();
+ - getOffsetY()) / getScale() + mMagnifiedBounds.top;
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 8a0a62a..810270d 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2884,7 +2884,6 @@
}
if (response == null) throw new IllegalArgumentException("response is null");
if (account == null) throw new IllegalArgumentException("account is null");
- if (authTokenType == null) throw new IllegalArgumentException("authTokenType is null");
int userId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {