Merge "Scroll handle should have intrinsic width and height"
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index be26c24..55e23b1 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -20,6 +20,7 @@
 import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.HOME_STACK_ID;
+import static android.app.ActivityManager.INVALID_STACK_ID;
 import static android.view.View.MeasureSpec.AT_MOST;
 import static android.view.View.MeasureSpec.EXACTLY;
 import static android.view.View.MeasureSpec.getMode;
@@ -5250,7 +5251,7 @@
      * @return Returns the workspace stack id which contains this window.
      **/
     private int getWorkspaceId() {
-        int workspaceId = FULLSCREEN_WORKSPACE_STACK_ID;
+        int workspaceId = INVALID_STACK_ID;
         WindowControllerCallback callback = getWindowControllerCallback();
         if (callback != null) {
             try {
@@ -5259,6 +5260,9 @@
                 Log.e(TAG, "Failed to get the workspace ID of a PhoneWindow.");
             }
         }
+        if (workspaceId == INVALID_STACK_ID) {
+            return FULLSCREEN_WORKSPACE_STACK_ID;
+        }
         return workspaceId;
     }
 
diff --git a/core/tests/coretests/src/android/widget/TextViewTest.java b/core/tests/coretests/src/android/widget/TextViewTest.java
index e337937..49d9115 100644
--- a/core/tests/coretests/src/android/widget/TextViewTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewTest.java
@@ -18,7 +18,7 @@
 
 import android.app.Activity;
 import android.content.Intent;
-import android.test.AndroidTestCase;
+import android.test.ActivityInstrumentationTestCase2;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.text.GetChars;
 import android.text.Selection;
@@ -27,11 +27,15 @@
 /**
  * TextViewTest tests {@link TextView}.
  */
-public class TextViewTest extends AndroidTestCase {
+public class TextViewTest extends ActivityInstrumentationTestCase2<TextViewActivity> {
+
+    public TextViewTest() {
+        super(TextViewActivity.class);
+    }
 
     @SmallTest
     public void testArray() throws Exception {
-        TextView tv = new TextView(mContext);
+        TextView tv = new TextView(getActivity());
 
         char[] c = new char[] { 'H', 'e', 'l', 'l', 'o', ' ',
                                 'W', 'o', 'r', 'l', 'd', '!' };
@@ -61,17 +65,24 @@
 
     @SmallTest
     public void testProcessTextActivityResultNonEditable() {
-        TextView tv = new TextView(mContext);
+        final TextView tv = new TextView(getActivity());
         CharSequence originalText = "This is some text.";
         tv.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, tv.getText().toString());
         tv.setTextIsSelectable(true);
         Selection.setSelection((Spannable) tv.getText(), 0, tv.getText().length());
 
-        CharSequence newText = "Text is replaced.";
-        Intent data = new Intent();
-        data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText);
-        tv.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, data);
+        // We need to run this in the UI thread, as it will create a Toast.
+        getActivity().runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                CharSequence newText = "Text is replaced.";
+                Intent data = new Intent();
+                data.putExtra(Intent.EXTRA_PROCESS_TEXT, newText);
+                tv.onActivityResult(TextView.PROCESS_TEXT_REQUEST_CODE, Activity.RESULT_OK, data);
+            }
+        });
+        getInstrumentation().waitForIdleSync();
 
         // This is a TextView, which can't be modified. Hence no change should have been made.
         assertEquals(originalText, tv.getText().toString());
@@ -79,7 +90,7 @@
 
     @SmallTest
     public void testProcessTextActivityResultEditable() {
-        EditText tv = new EditText(mContext);
+        EditText tv = new EditText(getActivity());
         CharSequence originalText = "This is some text.";
         tv.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, tv.getText().toString());
@@ -96,7 +107,7 @@
 
     @SmallTest
     public void testProcessTextActivityResultCancel() {
-        EditText tv = new EditText(mContext);
+        EditText tv = new EditText(getActivity());
         CharSequence originalText = "This is some text.";
         tv.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, tv.getText().toString());
@@ -113,7 +124,7 @@
 
     @SmallTest
     public void testProcessTextActivityNoData() {
-        EditText tv = new EditText(mContext);
+        EditText tv = new EditText(getActivity());
         CharSequence originalText = "This is some text.";
         tv.setText(originalText, TextView.BufferType.SPANNABLE);
         assertEquals(originalText, tv.getText().toString());
diff --git a/libs/hwui/CanvasState.cpp b/libs/hwui/CanvasState.cpp
index 54fb5f2..e307ad9 100644
--- a/libs/hwui/CanvasState.cpp
+++ b/libs/hwui/CanvasState.cpp
@@ -155,17 +155,20 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 bool CanvasState::clipRect(float left, float top, float right, float bottom, SkRegion::Op op) {
-    mDirtyClip |= mSnapshot->clip(left, top, right, bottom, op);
+    mSnapshot->clip(left, top, right, bottom, op);
+    mDirtyClip = true;
     return !mSnapshot->clipIsEmpty();
 }
 
 bool CanvasState::clipPath(const SkPath* path, SkRegion::Op op) {
-    mDirtyClip |= mSnapshot->clipPath(*path, op);
+    mSnapshot->clipPath(*path, op);
+    mDirtyClip = true;
     return !mSnapshot->clipIsEmpty();
 }
 
 bool CanvasState::clipRegion(const SkRegion* region, SkRegion::Op op) {
-    mDirtyClip |= mSnapshot->clipRegionTransformed(*region, op);
+    mSnapshot->clipRegionTransformed(*region, op);
+    mDirtyClip = true;
     return !mSnapshot->clipIsEmpty();
 }
 
diff --git a/libs/hwui/ClipArea.cpp b/libs/hwui/ClipArea.cpp
index b1a6844..8e7efb4 100644
--- a/libs/hwui/ClipArea.cpp
+++ b/libs/hwui/ClipArea.cpp
@@ -32,9 +32,7 @@
 }
 
 static void handlePoint(Rect& transformedBounds, const Matrix4& transform, float x, float y) {
-    Vertex v;
-    v.x = x;
-    v.y = y;
+    Vertex v = {x, y};
     transform.mapPoint(v.x, v.y);
     transformedBounds.expandToCoverVertex(v.x, v.y);
 }
@@ -187,7 +185,7 @@
  */
 
 ClipArea::ClipArea()
-        : mMode(kModeRectangle) {
+        : mMode(Mode::Rectangle) {
 }
 
 /*
@@ -200,45 +198,46 @@
 }
 
 void ClipArea::setEmpty() {
-    mMode = kModeRectangle;
+    mMode = Mode::Rectangle;
     mClipRect.setEmpty();
     mClipRegion.setEmpty();
     mRectangleList.setEmpty();
 }
 
 void ClipArea::setClip(float left, float top, float right, float bottom) {
-    mMode = kModeRectangle;
+    mMode = Mode::Rectangle;
     mClipRect.set(left, top, right, bottom);
     mClipRegion.setEmpty();
 }
 
-bool ClipArea::clipRectWithTransform(float left, float top, float right,
+void ClipArea::clipRectWithTransform(float left, float top, float right,
         float bottom, const mat4* transform, SkRegion::Op op) {
     Rect r(left, top, right, bottom);
-    return clipRectWithTransform(r, transform, op);
+    clipRectWithTransform(r, transform, op);
 }
 
-bool ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform,
+void ClipArea::clipRectWithTransform(const Rect& r, const mat4* transform,
         SkRegion::Op op) {
     switch (mMode) {
-    case kModeRectangle:
-        return rectangleModeClipRectWithTransform(r, transform, op);
-    case kModeRectangleList:
-        return rectangleListModeClipRectWithTransform(r, transform, op);
-    case kModeRegion:
-        return regionModeClipRectWithTransform(r, transform, op);
+    case Mode::Rectangle:
+        rectangleModeClipRectWithTransform(r, transform, op);
+        break;
+    case Mode::RectangleList:
+        rectangleListModeClipRectWithTransform(r, transform, op);
+        break;
+    case Mode::Region:
+        regionModeClipRectWithTransform(r, transform, op);
+        break;
     }
-    return false;
 }
 
-bool ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
+void ClipArea::clipRegion(const SkRegion& region, SkRegion::Op op) {
     enterRegionMode();
     mClipRegion.op(region, op);
     onClipRegionUpdated();
-    return true;
 }
 
-bool ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform,
+void ClipArea::clipPathWithTransform(const SkPath& path, const mat4* transform,
         SkRegion::Op op) {
     SkMatrix skTransform;
     transform->copyTo(skTransform);
@@ -246,7 +245,7 @@
     path.transform(skTransform, &transformed);
     SkRegion region;
     regionFromPath(transformed, region);
-    return clipRegion(region, op);
+    clipRegion(region, op);
 }
 
 /*
@@ -257,19 +256,20 @@
     // Entering rectangle mode discards any
     // existing clipping information from the other modes.
     // The only way this occurs is by a clip setting operation.
-    mMode = kModeRectangle;
+    mMode = Mode::Rectangle;
 }
 
-bool ClipArea::rectangleModeClipRectWithTransform(const Rect& r,
+void ClipArea::rectangleModeClipRectWithTransform(const Rect& r,
         const mat4* transform, SkRegion::Op op) {
 
     if (op == SkRegion::kReplace_Op && transform->rectToRect()) {
         mClipRect = r;
         transform->mapRect(mClipRect);
-        return true;
+        return;
     } else if (op != SkRegion::kIntersect_Op) {
         enterRegionMode();
-        return regionModeClipRectWithTransform(r, transform, op);
+        regionModeClipRectWithTransform(r, transform, op);
+        return;
     }
 
     if (transform->rectToRect()) {
@@ -279,19 +279,18 @@
         if (!hasIntersection) {
             mClipRect.setEmpty();
         }
-        return true;
+        return;
     }
 
     enterRectangleListMode();
-    return rectangleListModeClipRectWithTransform(r, transform, op);
+    rectangleListModeClipRectWithTransform(r, transform, op);
 }
 
-bool ClipArea::rectangleModeClipRectWithTransform(float left, float top,
+void ClipArea::rectangleModeClipRectWithTransform(float left, float top,
         float right, float bottom, const mat4* transform, SkRegion::Op op) {
     Rect r(left, top, right, bottom);
-    bool result = rectangleModeClipRectWithTransform(r, transform, op);
+    rectangleModeClipRectWithTransform(r, transform, op);
     mClipRect = mRectangleList.calculateBounds();
-    return result;
 }
 
 /*
@@ -302,25 +301,24 @@
     // Is is only legal to enter rectangle list mode from
     // rectangle mode, since rectangle list mode cannot represent
     // all clip areas that can be represented by a region.
-    ALOG_ASSERT(mMode == kModeRectangle);
-    mMode = kModeRectangleList;
+    ALOG_ASSERT(mMode == Mode::Rectangle);
+    mMode = Mode::RectangleList;
     mRectangleList.set(mClipRect, Matrix4::identity());
 }
 
-bool ClipArea::rectangleListModeClipRectWithTransform(const Rect& r,
+void ClipArea::rectangleListModeClipRectWithTransform(const Rect& r,
         const mat4* transform, SkRegion::Op op) {
     if (op != SkRegion::kIntersect_Op
             || !mRectangleList.intersectWith(r, *transform)) {
         enterRegionMode();
-        return regionModeClipRectWithTransform(r, transform, op);
+        regionModeClipRectWithTransform(r, transform, op);
     }
-    return true;
 }
 
-bool ClipArea::rectangleListModeClipRectWithTransform(float left, float top,
+void ClipArea::rectangleListModeClipRectWithTransform(float left, float top,
         float right, float bottom, const mat4* transform, SkRegion::Op op) {
     Rect r(left, top, right, bottom);
-    return rectangleListModeClipRectWithTransform(r, transform, op);
+    rectangleListModeClipRectWithTransform(r, transform, op);
 }
 
 /*
@@ -329,9 +327,9 @@
 
 void ClipArea::enterRegionMode() {
     Mode oldMode = mMode;
-    mMode = kModeRegion;
-    if (oldMode != kModeRegion) {
-        if (oldMode == kModeRectangle) {
+    mMode = Mode::Region;
+    if (oldMode != Mode::Region) {
+        if (oldMode == Mode::Rectangle) {
             mClipRegion.setRect(mClipRect.left, mClipRect.top,
                     mClipRect.right, mClipRect.bottom);
         } else {
@@ -341,20 +339,18 @@
     }
 }
 
-bool ClipArea::regionModeClipRectWithTransform(const Rect& r,
+void ClipArea::regionModeClipRectWithTransform(const Rect& r,
         const mat4* transform, SkRegion::Op op) {
     SkPath transformedRect = pathFromTransformedRectangle(r, *transform);
     SkRegion transformedRectRegion;
     regionFromPath(transformedRect, transformedRectRegion);
     mClipRegion.op(transformedRectRegion, op);
     onClipRegionUpdated();
-    return true;
 }
 
-bool ClipArea::regionModeClipRectWithTransform(float left, float top,
+void ClipArea::regionModeClipRectWithTransform(float left, float top,
         float right, float bottom, const mat4* transform, SkRegion::Op op) {
-    return regionModeClipRectWithTransform(Rect(left, top, right, bottom),
-            transform, op);
+    regionModeClipRectWithTransform(Rect(left, top, right, bottom), transform, op);
 }
 
 void ClipArea::onClipRegionUpdated() {
diff --git a/libs/hwui/ClipArea.h b/libs/hwui/ClipArea.h
index 51ef27b..38fefe5 100644
--- a/libs/hwui/ClipArea.h
+++ b/libs/hwui/ClipArea.h
@@ -80,6 +80,13 @@
 };
 
 class ClipArea {
+private:
+    enum class Mode {
+        Rectangle,
+        Region,
+        RectangleList
+    };
+
 public:
     ClipArea();
 
@@ -91,12 +98,12 @@
 
     void setEmpty();
     void setClip(float left, float top, float right, float bottom);
-    bool clipRectWithTransform(float left, float top, float right, float bottom,
-            const mat4* transform, SkRegion::Op op = SkRegion::kIntersect_Op);
-    bool clipRectWithTransform(const Rect& r, const mat4* transform,
-            SkRegion::Op op = SkRegion::kIntersect_Op);
-    bool clipRegion(const SkRegion& region, SkRegion::Op op = SkRegion::kIntersect_Op);
-    bool clipPathWithTransform(const SkPath& path, const mat4* transform,
+    void clipRectWithTransform(float left, float top, float right, float bottom,
+            const mat4* transform, SkRegion::Op op);
+    void clipRectWithTransform(const Rect& r, const mat4* transform,
+            SkRegion::Op op);
+    void clipRegion(const SkRegion& region, SkRegion::Op op);
+    void clipPathWithTransform(const SkPath& path, const mat4* transform,
             SkRegion::Op op);
 
     const Rect& getClipRect() const {
@@ -112,41 +119,39 @@
     }
 
     bool isRegion() const {
-        return kModeRegion == mMode;
+        return Mode::Region == mMode;
     }
 
     bool isSimple() const {
-        return mMode == kModeRectangle;
+        return mMode == Mode::Rectangle;
     }
 
     bool isRectangleList() const {
-        return mMode == kModeRectangleList;
+        return mMode == Mode::RectangleList;
     }
 
 private:
     void enterRectangleMode();
-    bool rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
-    bool rectangleModeClipRectWithTransform(float left, float top, float right,
+    void rectangleModeClipRectWithTransform(const Rect& r, const mat4* transform, SkRegion::Op op);
+    void rectangleModeClipRectWithTransform(float left, float top, float right,
             float bottom, const mat4* transform, SkRegion::Op op);
 
     void enterRectangleListMode();
-    bool rectangleListModeClipRectWithTransform(float left, float top,
+    void rectangleListModeClipRectWithTransform(float left, float top,
             float right, float bottom, const mat4* transform, SkRegion::Op op);
-    bool rectangleListModeClipRectWithTransform(const Rect& r,
+    void rectangleListModeClipRectWithTransform(const Rect& r,
             const mat4* transform, SkRegion::Op op);
 
     void enterRegionModeFromRectangleMode();
     void enterRegionModeFromRectangleListMode();
     void enterRegionMode();
-    bool regionModeClipRectWithTransform(const Rect& r, const mat4* transform,
+    void regionModeClipRectWithTransform(const Rect& r, const mat4* transform,
             SkRegion::Op op);
-    bool regionModeClipRectWithTransform(float left, float top, float right,
+    void regionModeClipRectWithTransform(float left, float top, float right,
             float bottom, const mat4* transform, SkRegion::Op op);
 
     void ensureClipRegion();
     void onClipRegionUpdated();
-    bool clipRegionOp(float left, float top, float right, float bottom,
-            SkRegion::Op op);
 
     SkRegion createViewportRegion() {
         return SkRegion(mViewportBounds.toSkIRect());
@@ -158,12 +163,6 @@
         pathAsRegion.setPath(path, createViewportRegion());
     }
 
-    enum Mode {
-        kModeRectangle,
-        kModeRegion,
-        kModeRectangleList
-    };
-
     Mode mMode;
     Rect mViewportBounds;
     Rect mClipRect;
diff --git a/libs/hwui/Snapshot.cpp b/libs/hwui/Snapshot.cpp
index ca19a42..4d60b8d 100644
--- a/libs/hwui/Snapshot.cpp
+++ b/libs/hwui/Snapshot.cpp
@@ -83,24 +83,24 @@
 // Clipping
 ///////////////////////////////////////////////////////////////////////////////
 
-bool Snapshot::clipRegionTransformed(const SkRegion& region, SkRegion::Op op) {
+void Snapshot::clipRegionTransformed(const SkRegion& region, SkRegion::Op op) {
     flags |= Snapshot::kFlagClipSet;
-    return mClipArea->clipRegion(region, op);
+    mClipArea->clipRegion(region, op);
 }
 
-bool Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
+void Snapshot::clip(float left, float top, float right, float bottom, SkRegion::Op op) {
     flags |= Snapshot::kFlagClipSet;
-    return mClipArea->clipRectWithTransform(left, top, right, bottom, transform, op);
+    mClipArea->clipRectWithTransform(left, top, right, bottom, transform, op);
 }
 
-bool Snapshot::clipPath(const SkPath& path, SkRegion::Op op) {
+void Snapshot::clipPath(const SkPath& path, SkRegion::Op op) {
     flags |= Snapshot::kFlagClipSet;
-    return mClipArea->clipPathWithTransform(path, transform, op);
+    mClipArea->clipPathWithTransform(path, transform, op);
 }
 
 void Snapshot::setClip(float left, float top, float right, float bottom) {
-    mClipArea->setClip(left, top, right, bottom);
     flags |= Snapshot::kFlagClipSet;
+    mClipArea->setClip(left, top, right, bottom);
 }
 
 bool Snapshot::hasPerspectiveTransform() const {
diff --git a/libs/hwui/Snapshot.h b/libs/hwui/Snapshot.h
index af6ad72..cf8f11c 100644
--- a/libs/hwui/Snapshot.h
+++ b/libs/hwui/Snapshot.h
@@ -124,26 +124,25 @@
      * the specified operation. The specified rectangle is transformed
      * by this snapshot's trasnformation.
      */
-    bool clip(float left, float top, float right, float bottom,
-            SkRegion::Op op = SkRegion::kIntersect_Op);
+    void clip(float left, float top, float right, float bottom, SkRegion::Op op);
 
     /**
      * Modifies the current clip with the new clip rectangle and
      * the specified operation. The specified rectangle is considered
      * already transformed.
      */
-    bool clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op);
+    void clipTransformed(const Rect& r, SkRegion::Op op = SkRegion::kIntersect_Op);
 
     /**
      * Modifies the current clip with the specified region and operation.
      * The specified region is considered already transformed.
      */
-    bool clipRegionTransformed(const SkRegion& region, SkRegion::Op op);
+    void clipRegionTransformed(const SkRegion& region, SkRegion::Op op);
 
     /**
      * Modifies the current clip with the specified path and operation.
      */
-    bool clipPath(const SkPath& path, SkRegion::Op op);
+    void clipPath(const SkPath& path, SkRegion::Op op);
 
     /**
      * Sets the current clip.
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 55a2659..c1b0753 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -21,6 +21,7 @@
 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
 import static android.app.ActivityManager.DOCKED_STACK_ID;
 import static android.app.ActivityManager.HOME_STACK_ID;
+import static android.app.ActivityManager.INVALID_STACK_ID;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
 import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -9005,8 +9006,7 @@
         synchronized (this) {
             ActivityStack stack = ActivityRecord.getStackLocked(token);
             if (stack == null) {
-                throw new IllegalArgumentException(
-                        "getActivityStackId: No stack for token=" + token);
+                return INVALID_STACK_ID;
             }
             return stack.mStackId;
         }