diff --git a/libs/WindowManager/Shell/Android.bp b/libs/WindowManager/Shell/Android.bp
index 1591b06..0defbd6 100644
--- a/libs/WindowManager/Shell/Android.bp
+++ b/libs/WindowManager/Shell/Android.bp
@@ -23,7 +23,18 @@
 
 filegroup {
     name: "wm_shell-sources",
-    srcs: ["src/**/*.java"],
+    srcs: [
+        "src/**/*.java",
+    ],
+    path: "src",
+}
+
+// TODO(b/168581922) protologtool do not support kotlin(*.kt)
+filegroup {
+    name: "wm_shell-sources-kt",
+    srcs: [
+        "src/**/*.kt",
+    ],
     path: "src",
 }
 
@@ -97,15 +108,23 @@
     name: "WindowManager-Shell",
     srcs: [
         ":wm_shell_protolog_src",
+        // TODO(b/168581922) protologtool do not support kotlin(*.kt)
+        ":wm_shell-sources-kt",
         "src/**/I*.aidl",
     ],
     resource_dirs: [
         "res",
     ],
     static_libs: [
+        "androidx.dynamicanimation_dynamicanimation",
+        "kotlinx-coroutines-android",
+        "kotlinx-coroutines-core",
         "protolog-lib",
         "WindowManager-Shell-proto",
         "androidx.appcompat_appcompat",
     ],
+    kotlincflags: ["-Xjvm-default=enable"],
     manifest: "AndroidManifest.xml",
+
+    min_sdk_version: "26",
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/dismiss_circle_background.xml b/libs/WindowManager/Shell/res/drawable/dismiss_circle_background.xml
new file mode 100644
index 0000000..7809c83
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/dismiss_circle_background.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2020 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.
+  -->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="oval">
+
+    <stroke
+        android:width="1dp"
+        android:color="#AAFFFFFF" />
+
+    <solid android:color="#77000000" />
+
+</shape>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml
new file mode 100644
index 0000000..040c7e6
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_next_white.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2017 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z" />
+    <path
+        android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml
new file mode 100644
index 0000000..b9b94b7
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/pip_ic_skip_previous_white.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2017 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+
+    <path
+        android:fillColor="#FFFFFF"
+        android:pathData="M6 6h2v12H6zm3.5 6l8.5 6V6z" />
+    <path
+        android:pathData="M0 0h24v24H0z" />
+</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_control_button.xml b/libs/WindowManager/Shell/res/layout/tv_pip_control_button.xml
index 72287c1..727ac34 100644
--- a/libs/WindowManager/Shell/res/layout/tv_pip_control_button.xml
+++ b/libs/WindowManager/Shell/res/layout/tv_pip_control_button.xml
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<!-- Layout for {@link com.android.systemui.pip.tv.PipControlButtonView}. -->
+<!-- Layout for {@link com.android.wm.shell.pip.tv.PipControlButtonView}. -->
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
     <ImageView android:id="@+id/button"
diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_controls.xml b/libs/WindowManager/Shell/res/layout/tv_pip_controls.xml
index 22e0452..d2f235e 100644
--- a/libs/WindowManager/Shell/res/layout/tv_pip_controls.xml
+++ b/libs/WindowManager/Shell/res/layout/tv_pip_controls.xml
@@ -14,17 +14,17 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<!-- Layout for {@link com.android.systemui.pip.tv.PipControlsView}. -->
+<!-- Layout for {@link com.android.wm.shell.pip.tv.PipControlsView}. -->
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <com.android.systemui.pip.tv.PipControlButtonView
+    <com.android.wm.shell.pip.tv.PipControlButtonView
         android:id="@+id/full_button"
         android:layout_width="@dimen/picture_in_picture_button_width"
         android:layout_height="wrap_content"
         android:src="@drawable/pip_ic_fullscreen_white"
         android:text="@string/pip_fullscreen" />
 
-    <com.android.systemui.pip.tv.PipControlButtonView
+    <com.android.wm.shell.pip.tv.PipControlButtonView
         android:id="@+id/close_button"
         android:layout_width="@dimen/picture_in_picture_button_width"
         android:layout_height="wrap_content"
@@ -32,7 +32,7 @@
         android:src="@drawable/pip_ic_close_white"
         android:text="@string/pip_close" />
 
-    <com.android.systemui.pip.tv.PipControlButtonView
+    <com.android.wm.shell.pip.tv.PipControlButtonView
         android:id="@+id/play_pause_button"
         android:layout_width="@dimen/picture_in_picture_button_width"
         android:layout_height="wrap_content"
diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_custom_control.xml b/libs/WindowManager/Shell/res/layout/tv_pip_custom_control.xml
index e6cd112..452f2cd 100644
--- a/libs/WindowManager/Shell/res/layout/tv_pip_custom_control.xml
+++ b/libs/WindowManager/Shell/res/layout/tv_pip_custom_control.xml
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 -->
-<com.android.systemui.pip.tv.PipControlButtonView
+<com.android.wm.shell.pip.tv.PipControlButtonView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/picture_in_picture_button_width"
     android:layout_height="wrap_content"
diff --git a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
index a049787..d8474b8 100644
--- a/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/tv_pip_menu.xml
@@ -15,15 +15,15 @@
     limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="horizontal"
-    android:paddingTop="350dp"
-    android:background="#CC000000"
-    android:gravity="top|center_horizontal"
-    android:clipChildren="false">
+              android:layout_width="match_parent"
+              android:layout_height="match_parent"
+              android:orientation="horizontal"
+              android:paddingTop="350dp"
+              android:background="#CC000000"
+              android:gravity="top|center_horizontal"
+              android:clipChildren="false">
 
-    <com.android.systemui.pip.tv.PipControlsView
+    <com.android.wm.shell.pip.tv.PipControlsView
         android:id="@+id/pip_controls"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
diff --git a/libs/WindowManager/Shell/res/values/config.xml b/libs/WindowManager/Shell/res/values/config.xml
index 63b0f6f..e99350b 100644
--- a/libs/WindowManager/Shell/res/values/config.xml
+++ b/libs/WindowManager/Shell/res/values/config.xml
@@ -32,4 +32,8 @@
 
     <!-- Allow one handed to enable round corner -->
     <bool name="config_one_handed_enable_round_corner">true</bool>
+
+    <!-- Bounds [left top right bottom] on screen for picture-in-picture (PIP) windows,
+     when the PIP menu is shown in center. -->
+    <string translatable="false" name="pip_menu_bounds">"596 280 1324 690"</string>
 </resources>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 7fb641a..a9917a6 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -57,6 +57,9 @@
     <dimen name="pip_resize_handle_margin">4dp</dimen>
     <dimen name="pip_resize_handle_padding">0dp</dimen>
 
+    <dimen name="dismiss_target_x_size">24dp</dimen>
+    <dimen name="floating_dismiss_bottom_margin">50dp</dimen>
+
     <!-- How high we lift the divider when touching -->
     <dimen name="docked_stack_divider_lift_elevation">4dp</dimen>
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java
new file mode 100644
index 0000000..acb9a5da
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShellWrapper.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2020 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.wm.shell;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.app.WindowConfiguration;
+import android.os.RemoteException;
+import android.view.WindowManagerGlobal;
+
+import com.android.wm.shell.pip.PinnedStackListenerForwarder;
+
+/**
+ * The singleton wrapper to communicate between WindowManagerService and WMShell features
+ * (e.g: PIP, SplitScreen, Bubble, OneHandedMode...etc)
+ */
+public class WindowManagerShellWrapper {
+    private static final String TAG = WindowManagerShellWrapper.class.getSimpleName();
+
+    public static final int WINDOWING_MODE_PINNED = WindowConfiguration.WINDOWING_MODE_PINNED;
+
+    /**
+     * Forwarder to which we can add multiple pinned stack listeners. Each listener will receive
+     * updates from the window manager service.
+     */
+    private PinnedStackListenerForwarder mPinnedStackListenerForwarder =
+            new PinnedStackListenerForwarder();
+
+    /**
+     * Adds a pinned stack listener, which will receive updates from the window manager service
+     * along with any other pinned stack listeners that were added via this method.
+     */
+    public void addPinnedStackListener(PinnedStackListenerForwarder.PinnedStackListener listener)
+            throws
+            RemoteException {
+        mPinnedStackListenerForwarder.addListener(listener);
+        WindowManagerGlobal.getWindowManagerService().registerPinnedStackListener(
+                DEFAULT_DISPLAY, mPinnedStackListenerForwarder);
+    }
+
+    /**
+     * Removes a pinned stack listener.
+     */
+    public void removePinnedStackListener(
+            PinnedStackListenerForwarder.PinnedStackListener listener) {
+        mPinnedStackListenerForwarder.removeListener(listener);
+    }
+
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/FloatProperties.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/FloatProperties.kt
new file mode 100644
index 0000000..d4f8282
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/FloatProperties.kt
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.animation
+
+import android.graphics.Rect
+import android.graphics.RectF
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+
+/**
+ * Helpful extra properties to use with the [PhysicsAnimator]. These allow you to animate objects
+ * such as [Rect] and [RectF].
+ *
+ * There are additional, more basic properties available in [DynamicAnimation].
+ */
+class FloatProperties {
+    companion object {
+        /**
+         * Represents the x-coordinate of a [Rect]. Typically used to animate moving a Rect
+         * horizontally.
+         *
+         * This property's getter returns [Rect.left], and its setter uses [Rect.offsetTo], which
+         * sets [Rect.left] to the new value and offsets [Rect.right] so that the width of the Rect
+         * does not change.
+         */
+        @JvmField
+        val RECT_X = object : FloatPropertyCompat<Rect>("RectX") {
+            override fun setValue(rect: Rect?, value: Float) {
+                rect?.offsetTo(value.toInt(), rect.top)
+            }
+
+            override fun getValue(rect: Rect?): Float {
+                return rect?.left?.toFloat() ?: -Float.MAX_VALUE
+            }
+        }
+
+        /**
+         * Represents the y-coordinate of a [Rect]. Typically used to animate moving a Rect
+         * vertically.
+         *
+         * This property's getter returns [Rect.top], and its setter uses [Rect.offsetTo], which
+         * sets [Rect.top] to the new value and offsets [Rect.bottom] so that the height of the Rect
+         * does not change.
+         */
+        @JvmField
+        val RECT_Y = object : FloatPropertyCompat<Rect>("RectY") {
+            override fun setValue(rect: Rect?, value: Float) {
+                rect?.offsetTo(rect.left, value.toInt())
+            }
+
+            override fun getValue(rect: Rect?): Float {
+                return rect?.top?.toFloat() ?: -Float.MAX_VALUE
+            }
+        }
+
+        /**
+         * Represents the width of a [Rect]. Typically used to animate resizing a Rect horizontally.
+         *
+         * This property's getter returns [Rect.width], and its setter changes the value of
+         * [Rect.right] by adding the animated width value to [Rect.left].
+         */
+        @JvmField
+        val RECT_WIDTH = object : FloatPropertyCompat<Rect>("RectWidth") {
+            override fun getValue(rect: Rect): Float {
+                return rect.width().toFloat()
+            }
+
+            override fun setValue(rect: Rect, value: Float) {
+                rect.right = rect.left + value.toInt()
+            }
+        }
+
+        /**
+         * Represents the height of a [Rect]. Typically used to animate resizing a Rect vertically.
+         *
+         * This property's getter returns [Rect.height], and its setter changes the value of
+         * [Rect.bottom] by adding the animated height value to [Rect.top].
+         */
+        @JvmField
+        val RECT_HEIGHT = object : FloatPropertyCompat<Rect>("RectHeight") {
+            override fun getValue(rect: Rect): Float {
+                return rect.height().toFloat()
+            }
+
+            override fun setValue(rect: Rect, value: Float) {
+                rect.bottom = rect.top + value.toInt()
+            }
+        }
+
+        /**
+         * Represents the x-coordinate of a [RectF]. Typically used to animate moving a RectF
+         * horizontally.
+         *
+         * This property's getter returns [RectF.left], and its setter uses [RectF.offsetTo], which
+         * sets [RectF.left] to the new value and offsets [RectF.right] so that the width of the
+         * RectF does not change.
+         */
+        @JvmField
+        val RECTF_X = object : FloatPropertyCompat<RectF>("RectFX") {
+            override fun setValue(rect: RectF?, value: Float) {
+                rect?.offsetTo(value, rect.top)
+            }
+
+            override fun getValue(rect: RectF?): Float {
+                return rect?.left ?: -Float.MAX_VALUE
+            }
+        }
+
+        /**
+         * Represents the y-coordinate of a [RectF]. Typically used to animate moving a RectF
+         * vertically.
+         *
+         * This property's getter returns [RectF.top], and its setter uses [RectF.offsetTo], which
+         * sets [RectF.top] to the new value and offsets [RectF.bottom] so that the height of the
+         * RectF does not change.
+         */
+        @JvmField
+        val RECTF_Y = object : FloatPropertyCompat<RectF>("RectFY") {
+            override fun setValue(rect: RectF?, value: Float) {
+                rect?.offsetTo(rect.left, value)
+            }
+
+            override fun getValue(rect: RectF?): Float {
+                return rect?.top ?: -Float.MAX_VALUE
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java
index b794b91..416ada7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/Interpolators.java
@@ -24,6 +24,16 @@
  */
 public class Interpolators {
     /**
+     * Interpolator for alpha in animation.
+     */
+    public static final Interpolator ALPHA_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
+
+    /**
+     * Interpolator for alpha out animation.
+     */
+    public static final Interpolator ALPHA_OUT = new PathInterpolator(0f, 0f, 0.8f, 1f);
+
+    /**
      * Interpolator for fast out linear in animation.
      */
     public static final Interpolator FAST_OUT_LINEAR_IN = new PathInterpolator(0.4f, 0f, 1f, 1f);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
new file mode 100644
index 0000000..5cd660a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimator.kt
@@ -0,0 +1,1071 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.animation
+
+import android.os.Looper
+import android.util.ArrayMap
+import android.util.Log
+import android.view.View
+import androidx.dynamicanimation.animation.AnimationHandler
+import androidx.dynamicanimation.animation.DynamicAnimation
+import androidx.dynamicanimation.animation.FlingAnimation
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+import androidx.dynamicanimation.animation.SpringAnimation
+import androidx.dynamicanimation.animation.SpringForce
+import com.android.wm.shell.animation.PhysicsAnimator.Companion.getInstance
+import java.lang.ref.WeakReference
+import java.util.WeakHashMap
+import kotlin.math.abs
+import kotlin.math.max
+import kotlin.math.min
+
+/**
+ * Extension function for all objects which will return a PhysicsAnimator instance for that object.
+ */
+val <T : View> T.physicsAnimator: PhysicsAnimator<T> get() { return getInstance(this) }
+
+private const val TAG = "PhysicsAnimator"
+
+private val UNSET = -Float.MAX_VALUE
+
+/**
+ * [FlingAnimation] multiplies the friction set via [FlingAnimation.setFriction] by 4.2f, which is
+ * where this number comes from. We use it in [PhysicsAnimator.flingThenSpring] to calculate the
+ * minimum velocity for a fling to reach a certain value, given the fling's friction.
+ */
+private const val FLING_FRICTION_SCALAR_MULTIPLIER = 4.2f
+
+typealias EndAction = () -> Unit
+
+/** A map of Property -> AnimationUpdate, which is provided to update listeners on each frame. */
+typealias UpdateMap<T> =
+        ArrayMap<FloatPropertyCompat<in T>, PhysicsAnimator.AnimationUpdate>
+
+/**
+ * Map of the animators associated with a given object. This ensures that only one animator
+ * per object exists.
+ */
+internal val animators = WeakHashMap<Any, PhysicsAnimator<*>>()
+
+/**
+ * Default spring configuration to use for animations where stiffness and/or damping ratio
+ * were not provided, and a default spring was not set via [PhysicsAnimator.setDefaultSpringConfig].
+ */
+private val globalDefaultSpring = PhysicsAnimator.SpringConfig(
+        SpringForce.STIFFNESS_MEDIUM,
+        SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY)
+
+/**
+ * Default fling configuration to use for animations where friction was not provided, and a default
+ * fling config was not set via [PhysicsAnimator.setDefaultFlingConfig].
+ */
+private val globalDefaultFling = PhysicsAnimator.FlingConfig(
+        friction = 1f, min = -Float.MAX_VALUE, max = Float.MAX_VALUE)
+
+/** Whether to log helpful debug information about animations. */
+private var verboseLogging = false
+
+/**
+ * Animator that uses physics-based animations to animate properties on views and objects. Physics
+ * animations use real-world physical concepts, such as momentum and mass, to realistically simulate
+ * motion. PhysicsAnimator is heavily inspired by [android.view.ViewPropertyAnimator], and
+ * also uses the builder pattern to configure and start animations.
+ *
+ * The physics animations are backed by [DynamicAnimation].
+ *
+ * @param T The type of the object being animated.
+ */
+class PhysicsAnimator<T> private constructor (target: T) {
+    /** Weak reference to the animation target. */
+    val weakTarget = WeakReference(target)
+
+    /** Data class for representing animation frame updates. */
+    data class AnimationUpdate(val value: Float, val velocity: Float)
+
+    /** [DynamicAnimation] instances for the given properties. */
+    private val springAnimations = ArrayMap<FloatPropertyCompat<in T>, SpringAnimation>()
+    private val flingAnimations = ArrayMap<FloatPropertyCompat<in T>, FlingAnimation>()
+
+    /**
+     * Spring and fling configurations for the properties to be animated on the target. We'll
+     * configure and start the DynamicAnimations for these properties according to the provided
+     * configurations.
+     */
+    private val springConfigs = ArrayMap<FloatPropertyCompat<in T>, SpringConfig>()
+    private val flingConfigs = ArrayMap<FloatPropertyCompat<in T>, FlingConfig>()
+
+    /**
+     * Animation listeners for the animation. These will be notified when each property animation
+     * updates or ends.
+     */
+    private val updateListeners = ArrayList<UpdateListener<T>>()
+    private val endListeners = ArrayList<EndListener<T>>()
+
+    /** End actions to run when all animations have completed.  */
+    private val endActions = ArrayList<EndAction>()
+
+    /** SpringConfig to use by default for properties whose springs were not provided. */
+    private var defaultSpring: SpringConfig = globalDefaultSpring
+
+    /** FlingConfig to use by default for properties whose fling configs were not provided. */
+    private var defaultFling: FlingConfig = globalDefaultFling
+
+    /**
+     * AnimationHandler to use if it need custom AnimationHandler, if this is null, it will use
+     * the default AnimationHandler in the DynamicAnimation.
+     */
+    private var customAnimationHandler: AnimationHandler? = null
+
+    /**
+     * Internal listeners that respond to DynamicAnimations updating and ending, and dispatch to
+     * the listeners provided via [addUpdateListener] and [addEndListener]. This allows us to add
+     * just one permanent update and end listener to the DynamicAnimations.
+     */
+    internal var internalListeners = ArrayList<InternalListener>()
+
+    /**
+     * Action to run when [start] is called. This can be changed by
+     * [PhysicsAnimatorTestUtils.prepareForTest] to enable animators to run under test and provide
+     * helpful test utilities.
+     */
+    internal var startAction: () -> Unit = ::startInternal
+
+    /**
+     * Action to run when [cancel] is called. This can be changed by
+     * [PhysicsAnimatorTestUtils.prepareForTest] to cancel animations from the main thread, which
+     * is required.
+     */
+    internal var cancelAction: (Set<FloatPropertyCompat<in T>>) -> Unit = ::cancelInternal
+
+    /**
+     * Springs a property to the given value, using the provided configuration settings.
+     *
+     * Springs are used when you know the exact value to which you want to animate. They can be
+     * configured with a start velocity (typically used when the spring is initiated by a touch
+     * event), but this velocity will be realistically attenuated as forces are applied to move the
+     * property towards the end value.
+     *
+     * If you find yourself repeating the same stiffness and damping ratios many times, consider
+     * storing a single [SpringConfig] instance and passing that in instead of individual values.
+     *
+     * @param property The property to spring to the given value. The property must be an instance
+     * of FloatPropertyCompat&lt;? super T&gt;. For example, if this is a
+     * PhysicsAnimator&lt;FrameLayout&gt;, you can use a FloatPropertyCompat&lt;FrameLayout&gt;, as
+     * well as a FloatPropertyCompat&lt;ViewGroup&gt;, and so on.
+     * @param toPosition The value to spring the given property to.
+     * @param startVelocity The initial velocity to use for the animation.
+     * @param stiffness The stiffness to use for the spring. Higher stiffness values result in
+     * faster animations, while lower stiffness means a slower animation. Reasonable values for
+     * low, medium, and high stiffness can be found as constants in [SpringForce].
+     * @param dampingRatio The damping ratio (bounciness) to use for the spring. Higher values
+     * result in a less 'springy' animation, while lower values allow the animation to bounce
+     * back and forth for a longer time after reaching the final position. Reasonable values for
+     * low, medium, and high damping can be found in [SpringForce].
+     */
+    fun spring(
+        property: FloatPropertyCompat<in T>,
+        toPosition: Float,
+        startVelocity: Float = 0f,
+        stiffness: Float = defaultSpring.stiffness,
+        dampingRatio: Float = defaultSpring.dampingRatio
+    ): PhysicsAnimator<T> {
+        if (verboseLogging) {
+            Log.d(TAG, "Springing ${getReadablePropertyName(property)} to $toPosition.")
+        }
+
+        springConfigs[property] =
+                SpringConfig(stiffness, dampingRatio, startVelocity, toPosition)
+        return this
+    }
+
+    /**
+     * Springs a property to a given value using the provided start velocity and configuration
+     * options.
+     *
+     * @see spring
+     */
+    fun spring(
+        property: FloatPropertyCompat<in T>,
+        toPosition: Float,
+        startVelocity: Float,
+        config: SpringConfig = defaultSpring
+    ): PhysicsAnimator<T> {
+        return spring(
+                property, toPosition, startVelocity, config.stiffness, config.dampingRatio)
+    }
+
+    /**
+     * Springs a property to a given value using the provided configuration options, and a start
+     * velocity of 0f.
+     *
+     * @see spring
+     */
+    fun spring(
+        property: FloatPropertyCompat<in T>,
+        toPosition: Float,
+        config: SpringConfig = defaultSpring
+    ): PhysicsAnimator<T> {
+        return spring(property, toPosition, 0f, config)
+    }
+
+    /**
+     * Springs a property to a given value using the provided configuration options, and a start
+     * velocity of 0f.
+     *
+     * @see spring
+     */
+    fun spring(
+        property: FloatPropertyCompat<in T>,
+        toPosition: Float
+    ): PhysicsAnimator<T> {
+        return spring(property, toPosition, 0f)
+    }
+
+    /**
+     * Flings a property using the given start velocity, using a [FlingAnimation] configured using
+     * the provided configuration settings.
+     *
+     * Flings are used when you have a start velocity, and want the property value to realistically
+     * decrease as friction is applied until the velocity reaches zero. Flings do not have a
+     * deterministic end value. If you are attempting to animate to a specific end value, use
+     * [spring].
+     *
+     * If you find yourself repeating the same friction/min/max values, consider storing a single
+     * [FlingConfig] and passing that in instead.
+     *
+     * @param property The property to fling using the given start velocity.
+     * @param startVelocity The start velocity (in pixels per second) with which to start the fling.
+     * @param friction Friction value applied to slow down the animation over time. Higher values
+     * will more quickly slow the animation. Typical friction values range from 1f to 10f.
+     * @param min The minimum value allowed for the animation. If this value is reached, the
+     * animation will end abruptly.
+     * @param max The maximum value allowed for the animation. If this value is reached, the
+     * animation will end abruptly.
+     */
+    fun fling(
+        property: FloatPropertyCompat<in T>,
+        startVelocity: Float,
+        friction: Float = defaultFling.friction,
+        min: Float = defaultFling.min,
+        max: Float = defaultFling.max
+    ): PhysicsAnimator<T> {
+        if (verboseLogging) {
+            Log.d(TAG, "Flinging ${getReadablePropertyName(property)} " +
+                    "with velocity $startVelocity.")
+        }
+
+        flingConfigs[property] = FlingConfig(friction, min, max, startVelocity)
+        return this
+    }
+
+    /**
+     * Flings a property using the given start velocity, using a [FlingAnimation] configured using
+     * the provided configuration settings.
+     *
+     * @see fling
+     */
+    fun fling(
+        property: FloatPropertyCompat<in T>,
+        startVelocity: Float,
+        config: FlingConfig = defaultFling
+    ): PhysicsAnimator<T> {
+        return fling(property, startVelocity, config.friction, config.min, config.max)
+    }
+
+    /**
+     * Flings a property using the given start velocity. If the fling animation reaches the min/max
+     * bounds (from the [flingConfig]) with velocity remaining, it'll overshoot it and spring back.
+     *
+     * If the object is already out of the fling bounds, it will immediately spring back within
+     * bounds.
+     *
+     * This is useful for animating objects that are bounded by constraints such as screen edges,
+     * since otherwise the fling animation would end abruptly upon reaching the min/max bounds.
+     *
+     * @param property The property to animate.
+     * @param startVelocity The velocity, in pixels/second, with which to start the fling. If the
+     * object is already outside the fling bounds, this velocity will be used as the start velocity
+     * of the spring that will spring it back within bounds.
+     * @param flingMustReachMinOrMax If true, the fling animation is guaranteed to reach either its
+     * minimum bound (if [startVelocity] is negative) or maximum bound (if it's positive). The
+     * animator will use startVelocity if it's sufficient, or add more velocity if necessary. This
+     * is useful when fling's deceleration-based physics are preferable to the acceleration-based
+     * forces used by springs - typically, when you're allowing the user to move an object somewhere
+     * on the screen, but it needs to be along an edge.
+     * @param flingConfig The configuration to use for the fling portion of the animation.
+     * @param springConfig The configuration to use for the spring portion of the animation.
+     */
+    @JvmOverloads
+    fun flingThenSpring(
+        property: FloatPropertyCompat<in T>,
+        startVelocity: Float,
+        flingConfig: FlingConfig,
+        springConfig: SpringConfig,
+        flingMustReachMinOrMax: Boolean = false
+    ): PhysicsAnimator<T> {
+        val target = weakTarget.get()
+        if (target == null) {
+            Log.w(TAG, "Trying to animate a GC-ed target.")
+            return this
+        }
+        val flingConfigCopy = flingConfig.copy()
+        val springConfigCopy = springConfig.copy()
+        val toAtLeast = if (startVelocity < 0) flingConfig.min else flingConfig.max
+
+        if (flingMustReachMinOrMax && isValidValue(toAtLeast)) {
+            val currentValue = property.getValue(target)
+            val flingTravelDistance =
+                    startVelocity / (flingConfig.friction * FLING_FRICTION_SCALAR_MULTIPLIER)
+            val projectedFlingEndValue = currentValue + flingTravelDistance
+            val midpoint = (flingConfig.min + flingConfig.max) / 2
+
+            // If fling velocity is too low to push the target past the midpoint between min and
+            // max, then spring back towards the nearest edge, starting with the current velocity.
+            if ((startVelocity < 0 && projectedFlingEndValue > midpoint) ||
+                    (startVelocity > 0 && projectedFlingEndValue < midpoint)) {
+                val toPosition =
+                        if (projectedFlingEndValue < midpoint) flingConfig.min else flingConfig.max
+                if (isValidValue(toPosition)) {
+                    return spring(property, toPosition, startVelocity, springConfig)
+                }
+            }
+
+            // Projected fling end value is past the midpoint, so fling forward.
+            val distanceToDestination = toAtLeast - property.getValue(target)
+
+            // The minimum velocity required for the fling to end up at the given destination,
+            // taking the provided fling friction value.
+            val velocityToReachDestination = distanceToDestination *
+                    (flingConfig.friction * FLING_FRICTION_SCALAR_MULTIPLIER)
+
+            // If there's distance to cover, and the provided velocity is moving in the correct
+            // direction, ensure that the velocity is high enough to reach the destination.
+            // Otherwise, just use startVelocity - this means that the fling is at or out of bounds.
+            // The fling will immediately end and a spring will bring the object back into bounds
+            // with this startVelocity.
+            flingConfigCopy.startVelocity = when {
+                distanceToDestination > 0f && startVelocity >= 0f ->
+                    max(velocityToReachDestination, startVelocity)
+                distanceToDestination < 0f && startVelocity <= 0f ->
+                    min(velocityToReachDestination, startVelocity)
+                else -> startVelocity
+            }
+
+            springConfigCopy.finalPosition = toAtLeast
+        } else {
+            flingConfigCopy.startVelocity = startVelocity
+        }
+
+        flingConfigs[property] = flingConfigCopy
+        springConfigs[property] = springConfigCopy
+        return this
+    }
+
+    private fun isValidValue(value: Float) = value < Float.MAX_VALUE && value > -Float.MAX_VALUE
+
+    /**
+     * Adds a listener that will be called whenever any property on the animated object is updated.
+     * This will be called on every animation frame, with the current value of the animated object
+     * and the new property values.
+     */
+    fun addUpdateListener(listener: UpdateListener<T>): PhysicsAnimator<T> {
+        updateListeners.add(listener)
+        return this
+    }
+
+    /**
+     * Adds a listener that will be called when a property stops animating. This is useful if
+     * you care about a specific property ending, or want to use the end value/end velocity from a
+     * particular property's animation. If you just want to run an action when all property
+     * animations have ended, use [withEndActions].
+     */
+    fun addEndListener(listener: EndListener<T>): PhysicsAnimator<T> {
+        endListeners.add(listener)
+        return this
+    }
+
+    /**
+     * Adds end actions that will be run sequentially when animations for every property involved in
+     * this specific animation have ended (unless they were explicitly canceled). For example, if
+     * you call:
+     *
+     * animator
+     *   .spring(TRANSLATION_X, ...)
+     *   .spring(TRANSLATION_Y, ...)
+     *   .withEndAction(action)
+     *   .start()
+     *
+     * 'action' will be run when both TRANSLATION_X and TRANSLATION_Y end.
+     *
+     * Other properties may still be animating, if those animations were not started in the same
+     * call. For example:
+     *
+     * animator
+     *   .spring(ALPHA, ...)
+     *   .start()
+     *
+     * animator
+     *   .spring(TRANSLATION_X, ...)
+     *   .spring(TRANSLATION_Y, ...)
+     *   .withEndAction(action)
+     *   .start()
+     *
+     * 'action' will still be run as soon as TRANSLATION_X and TRANSLATION_Y end, even if ALPHA is
+     * still animating.
+     *
+     * If you want to run actions as soon as a subset of property animations have ended, you want
+     * access to the animation's end value/velocity, or you want to run these actions even if the
+     * animation is explicitly canceled, use [addEndListener]. End listeners have an allEnded param,
+     * which indicates that all relevant animations have ended.
+     */
+    fun withEndActions(vararg endActions: EndAction?): PhysicsAnimator<T> {
+        this.endActions.addAll(endActions.filterNotNull())
+        return this
+    }
+
+    /**
+     * Helper overload so that callers from Java can use Runnables or method references as end
+     * actions without having to explicitly return Unit.
+     */
+    fun withEndActions(vararg endActions: Runnable?): PhysicsAnimator<T> {
+        this.endActions.addAll(endActions.filterNotNull().map { it::run })
+        return this
+    }
+
+    fun setDefaultSpringConfig(defaultSpring: SpringConfig) {
+        this.defaultSpring = defaultSpring
+    }
+
+    fun setDefaultFlingConfig(defaultFling: FlingConfig) {
+        this.defaultFling = defaultFling
+    }
+
+    /**
+     * Set the custom AnimationHandler for all aniatmion in this animator. Set this with null for
+     * restoring to default AnimationHandler.
+     */
+    fun setCustomAnimationHandler(handler: AnimationHandler) {
+        this.customAnimationHandler = handler
+    }
+
+    /** Starts the animations! */
+    fun start() {
+        startAction()
+    }
+
+    /**
+     * Starts the animations for real! This is typically called immediately by [start] unless this
+     * animator is under test.
+     */
+    internal fun startInternal() {
+        if (!Looper.getMainLooper().isCurrentThread) {
+            Log.e(TAG, "Animations can only be started on the main thread. If you are seeing " +
+                    "this message in a test, call PhysicsAnimatorTestUtils#prepareForTest in " +
+                    "your test setup.")
+        }
+        val target = weakTarget.get()
+        if (target == null) {
+            Log.w(TAG, "Trying to animate a GC-ed object.")
+            return
+        }
+
+        // Functions that will actually start the animations. These are run after we build and add
+        // the InternalListener, since some animations might update/end immediately and we don't
+        // want to miss those updates.
+        val animationStartActions = ArrayList<() -> Unit>()
+
+        for (animatedProperty in getAnimatedProperties()) {
+            val flingConfig = flingConfigs[animatedProperty]
+            val springConfig = springConfigs[animatedProperty]
+
+            // The property's current value on the object.
+            val currentValue = animatedProperty.getValue(target)
+
+            // Start by checking for a fling configuration. If one is present, we're either flinging
+            // or flinging-then-springing. Either way, we'll want to start the fling first.
+            if (flingConfig != null) {
+                animationStartActions.add {
+                    // When the animation is starting, adjust the min/max bounds to include the
+                    // current value of the property, if necessary. This is required to allow a
+                    // fling to bring an out-of-bounds object back into bounds. For example, if an
+                    // object was dragged halfway off the left side of the screen, but then flung to
+                    // the right, we don't want the animation to end instantly just because the
+                    // object started out of bounds. If the fling is in the direction that would
+                    // take it farther out of bounds, it will end instantly as expected.
+                    flingConfig.apply {
+                        min = min(currentValue, this.min)
+                        max = max(currentValue, this.max)
+                    }
+
+                    // Flings can't be updated to a new position while maintaining velocity, because
+                    // we're using the explicitly provided start velocity. Cancel any flings (or
+                    // springs) on this property before flinging.
+                    cancel(animatedProperty)
+
+                    // Apply the custom animation handler if it not null
+                    val flingAnim = getFlingAnimation(animatedProperty, target)
+                    flingAnim.animationHandler =
+                            customAnimationHandler ?: flingAnim.animationHandler
+
+                    // Apply the configuration and start the animation.
+                    flingAnim.also { flingConfig.applyToAnimation(it) }.start()
+                }
+            }
+
+            // Check for a spring configuration. If one is present, we're either springing, or
+            // flinging-then-springing.
+            if (springConfig != null) {
+
+                // If there is no corresponding fling config, we're only springing.
+                if (flingConfig == null) {
+                    // Apply the configuration and start the animation.
+                    val springAnim = getSpringAnimation(animatedProperty, target)
+
+                    // If customAnimationHander is exist and has not been set to the animation,
+                    // it should set here.
+                    if (customAnimationHandler != null &&
+                            springAnim.animationHandler != customAnimationHandler) {
+                        // Cancel the animation before set animation handler
+                        if (springAnim.isRunning) {
+                            cancel(animatedProperty)
+                        }
+                        // Apply the custom animation handler if it not null
+                        springAnim.animationHandler =
+                                customAnimationHandler ?: springAnim.animationHandler
+                    }
+
+                    // Apply the configuration and start the animation.
+                    springConfig.applyToAnimation(springAnim)
+                    animationStartActions.add(springAnim::start)
+                } else {
+                    // If there's a corresponding fling config, we're flinging-then-springing. Save
+                    // the fling's original bounds so we can spring to them when the fling ends.
+                    val flingMin = flingConfig.min
+                    val flingMax = flingConfig.max
+
+                    // Add an end listener that will start the spring when the fling ends.
+                    endListeners.add(0, object : EndListener<T> {
+                        override fun onAnimationEnd(
+                            target: T,
+                            property: FloatPropertyCompat<in T>,
+                            wasFling: Boolean,
+                            canceled: Boolean,
+                            finalValue: Float,
+                            finalVelocity: Float,
+                            allRelevantPropertyAnimsEnded: Boolean
+                        ) {
+                            // If this isn't the relevant property, it wasn't a fling, or the fling
+                            // was explicitly cancelled, don't spring.
+                            if (property != animatedProperty || !wasFling || canceled) {
+                                return
+                            }
+
+                            val endedWithVelocity = abs(finalVelocity) > 0
+
+                            // If the object was out of bounds when the fling animation started, it
+                            // will immediately end. In that case, we'll spring it back in bounds.
+                            val endedOutOfBounds = finalValue !in flingMin..flingMax
+
+                            // If the fling ended either out of bounds or with remaining velocity,
+                            // it's time to spring.
+                            if (endedWithVelocity || endedOutOfBounds) {
+                                springConfig.startVelocity = finalVelocity
+
+                                // If the spring's final position isn't set, this is a
+                                // flingThenSpring where flingMustReachMinOrMax was false. We'll
+                                // need to set the spring's final position here.
+                                if (springConfig.finalPosition == UNSET) {
+                                    if (endedWithVelocity) {
+                                        // If the fling ended with negative velocity, that means it
+                                        // hit the min bound, so spring to that bound (and vice
+                                        // versa).
+                                        springConfig.finalPosition =
+                                                if (finalVelocity < 0) flingMin else flingMax
+                                    } else if (endedOutOfBounds) {
+                                        // If the fling ended out of bounds, spring it to the
+                                        // nearest bound.
+                                        springConfig.finalPosition =
+                                                if (finalValue < flingMin) flingMin else flingMax
+                                    }
+                                }
+
+                                // Apply the custom animation handler if it not null
+                                val springAnim = getSpringAnimation(animatedProperty, target)
+                                springAnim.animationHandler =
+                                        customAnimationHandler ?: springAnim.animationHandler
+
+                                // Apply the configuration and start the spring animation.
+                                springAnim.also { springConfig.applyToAnimation(it) }.start()
+                            }
+                        }
+                    })
+                }
+            }
+        }
+
+        // Add an internal listener that will dispatch animation events to the provided listeners.
+        internalListeners.add(InternalListener(
+                target,
+                getAnimatedProperties(),
+                ArrayList(updateListeners),
+                ArrayList(endListeners),
+                ArrayList(endActions)))
+
+        // Actually start the DynamicAnimations. This is delayed until after the InternalListener is
+        // constructed and added so that we don't miss the end listener firing for any animations
+        // that immediately end.
+        animationStartActions.forEach { it.invoke() }
+
+        clearAnimator()
+    }
+
+    /** Clear the animator's builder variables. */
+    private fun clearAnimator() {
+        springConfigs.clear()
+        flingConfigs.clear()
+
+        updateListeners.clear()
+        endListeners.clear()
+        endActions.clear()
+    }
+
+    /** Retrieves a spring animation for the given property, building one if needed. */
+    private fun getSpringAnimation(
+        property: FloatPropertyCompat<in T>,
+        target: T
+    ): SpringAnimation {
+        return springAnimations.getOrPut(
+                property,
+                { configureDynamicAnimation(SpringAnimation(target, property), property)
+                        as SpringAnimation })
+    }
+
+    /** Retrieves a fling animation for the given property, building one if needed. */
+    private fun getFlingAnimation(property: FloatPropertyCompat<in T>, target: T): FlingAnimation {
+        return flingAnimations.getOrPut(
+                property,
+                { configureDynamicAnimation(FlingAnimation(target, property), property)
+                        as FlingAnimation })
+    }
+
+    /**
+     * Adds update and end listeners to the DynamicAnimation which will dispatch to the internal
+     * listeners.
+     */
+    private fun configureDynamicAnimation(
+        anim: DynamicAnimation<*>,
+        property: FloatPropertyCompat<in T>
+    ): DynamicAnimation<*> {
+        anim.addUpdateListener { _, value, velocity ->
+            for (i in 0 until internalListeners.size) {
+                internalListeners[i].onInternalAnimationUpdate(property, value, velocity)
+            }
+        }
+        anim.addEndListener { _, canceled, value, velocity ->
+            internalListeners.removeAll {
+                it.onInternalAnimationEnd(
+                        property, canceled, value, velocity, anim is FlingAnimation)
+            }
+            if (springAnimations[property] == anim) {
+                springAnimations.remove(property)
+            }
+            if (flingAnimations[property] == anim) {
+                flingAnimations.remove(property)
+            }
+        }
+        return anim
+    }
+
+    /**
+     * Internal listener class that receives updates from DynamicAnimation listeners, and dispatches
+     * them to the appropriate update/end listeners. This class is also aware of which properties
+     * were being animated when the end listeners were passed in, so that we can provide the
+     * appropriate value for allEnded to [EndListener.onAnimationEnd].
+     */
+    internal inner class InternalListener constructor(
+        private val target: T,
+        private var properties: Set<FloatPropertyCompat<in T>>,
+        private var updateListeners: List<UpdateListener<T>>,
+        private var endListeners: List<EndListener<T>>,
+        private var endActions: List<EndAction>
+    ) {
+
+        /** The number of properties whose animations haven't ended. */
+        private var numPropertiesAnimating = properties.size
+
+        /**
+         * Update values that haven't yet been dispatched because not all property animations have
+         * updated yet.
+         */
+        private val undispatchedUpdates =
+                ArrayMap<FloatPropertyCompat<in T>, AnimationUpdate>()
+
+        /** Called when a DynamicAnimation updates.  */
+        internal fun onInternalAnimationUpdate(
+            property: FloatPropertyCompat<in T>,
+            value: Float,
+            velocity: Float
+        ) {
+
+            // If this property animation isn't relevant to this listener, ignore it.
+            if (!properties.contains(property)) {
+                return
+            }
+
+            undispatchedUpdates[property] = AnimationUpdate(value, velocity)
+            maybeDispatchUpdates()
+        }
+
+        /**
+         * Called when a DynamicAnimation ends.
+         *
+         * @return True if this listener should be removed from the list of internal listeners, so
+         * it no longer receives updates from DynamicAnimations.
+         */
+        internal fun onInternalAnimationEnd(
+            property: FloatPropertyCompat<in T>,
+            canceled: Boolean,
+            finalValue: Float,
+            finalVelocity: Float,
+            isFling: Boolean
+        ): Boolean {
+
+            // If this property animation isn't relevant to this listener, ignore it.
+            if (!properties.contains(property)) {
+                return false
+            }
+
+            // Dispatch updates if we have one for each property.
+            numPropertiesAnimating--
+            maybeDispatchUpdates()
+
+            // If we didn't have an update for each property, dispatch the update for the ending
+            // property. This guarantees that an update isn't sent for this property *after* we call
+            // onAnimationEnd for that property.
+            if (undispatchedUpdates.contains(property)) {
+                updateListeners.forEach { updateListener ->
+                    updateListener.onAnimationUpdateForProperty(
+                            target,
+                            UpdateMap<T>().also { it[property] = undispatchedUpdates[property] })
+                }
+
+                undispatchedUpdates.remove(property)
+            }
+
+            val allEnded = !arePropertiesAnimating(properties)
+            endListeners.forEach {
+                it.onAnimationEnd(
+                        target, property, isFling, canceled, finalValue, finalVelocity,
+                        allEnded)
+
+                // Check that the end listener didn't restart this property's animation.
+                if (isPropertyAnimating(property)) {
+                    return false
+                }
+            }
+
+            // If all of the animations that this listener cares about have ended, run the end
+            // actions unless the animation was canceled.
+            if (allEnded && !canceled) {
+                endActions.forEach { it() }
+            }
+
+            return allEnded
+        }
+
+        /**
+         * Dispatch undispatched values if we've received an update from each of the animating
+         * properties.
+         */
+        private fun maybeDispatchUpdates() {
+            if (undispatchedUpdates.size >= numPropertiesAnimating &&
+                    undispatchedUpdates.size > 0) {
+                updateListeners.forEach {
+                    it.onAnimationUpdateForProperty(target, ArrayMap(undispatchedUpdates))
+                }
+
+                undispatchedUpdates.clear()
+            }
+        }
+    }
+
+    /** Return true if any animations are running on the object.  */
+    fun isRunning(): Boolean {
+        return arePropertiesAnimating(springAnimations.keys.union(flingAnimations.keys))
+    }
+
+    /** Returns whether the given property is animating.  */
+    fun isPropertyAnimating(property: FloatPropertyCompat<in T>): Boolean {
+        return springAnimations[property]?.isRunning ?: false ||
+                flingAnimations[property]?.isRunning ?: false
+    }
+
+    /** Returns whether any of the given properties are animating.  */
+    fun arePropertiesAnimating(properties: Set<FloatPropertyCompat<in T>>): Boolean {
+        return properties.any { isPropertyAnimating(it) }
+    }
+
+    /** Return the set of properties that will begin animating upon calling [start]. */
+    internal fun getAnimatedProperties(): Set<FloatPropertyCompat<in T>> {
+        return springConfigs.keys.union(flingConfigs.keys)
+    }
+
+    /**
+     * Cancels the given properties. This is typically called immediately by [cancel], unless this
+     * animator is under test.
+     */
+    internal fun cancelInternal(properties: Set<FloatPropertyCompat<in T>>) {
+        for (property in properties) {
+            flingAnimations[property]?.cancel()
+            springAnimations[property]?.cancel()
+        }
+    }
+
+    /** Cancels all in progress animations on all properties. */
+    fun cancel() {
+        cancelAction(flingAnimations.keys)
+        cancelAction(springAnimations.keys)
+    }
+
+    /** Cancels in progress animations on the provided properties only. */
+    fun cancel(vararg properties: FloatPropertyCompat<in T>) {
+        cancelAction(properties.toSet())
+    }
+
+    /**
+     * Container object for spring animation configuration settings. This allows you to store
+     * default stiffness and damping ratio values in a single configuration object, which you can
+     * pass to [spring].
+     */
+    data class SpringConfig internal constructor(
+        internal var stiffness: Float,
+        internal var dampingRatio: Float,
+        internal var startVelocity: Float = 0f,
+        internal var finalPosition: Float = UNSET
+    ) {
+
+        constructor() :
+                this(globalDefaultSpring.stiffness, globalDefaultSpring.dampingRatio)
+
+        constructor(stiffness: Float, dampingRatio: Float) :
+                this(stiffness = stiffness, dampingRatio = dampingRatio, startVelocity = 0f)
+
+        /** Apply these configuration settings to the given SpringAnimation. */
+        internal fun applyToAnimation(anim: SpringAnimation) {
+            val springForce = anim.spring ?: SpringForce()
+            anim.spring = springForce.apply {
+                stiffness = this@SpringConfig.stiffness
+                dampingRatio = this@SpringConfig.dampingRatio
+                finalPosition = this@SpringConfig.finalPosition
+            }
+
+            if (startVelocity != 0f) anim.setStartVelocity(startVelocity)
+        }
+    }
+
+    /**
+     * Container object for fling animation configuration settings. This allows you to store default
+     * friction values (as well as optional min/max values) in a single configuration object, which
+     * you can pass to [fling] and related methods.
+     */
+    data class FlingConfig internal constructor(
+        internal var friction: Float,
+        internal var min: Float,
+        internal var max: Float,
+        internal var startVelocity: Float
+    ) {
+
+        constructor() : this(globalDefaultFling.friction)
+
+        constructor(friction: Float) :
+                this(friction, globalDefaultFling.min, globalDefaultFling.max)
+
+        constructor(friction: Float, min: Float, max: Float) :
+                this(friction, min, max, startVelocity = 0f)
+
+        /** Apply these configuration settings to the given FlingAnimation. */
+        internal fun applyToAnimation(anim: FlingAnimation) {
+            anim.apply {
+                friction = this@FlingConfig.friction
+                setMinValue(min)
+                setMaxValue(max)
+                setStartVelocity(startVelocity)
+            }
+        }
+    }
+
+    /**
+     * Listener for receiving values from in progress animations. Used with
+     * [PhysicsAnimator.addUpdateListener].
+     *
+     * @param <T> The type of the object being animated.
+    </T> */
+    interface UpdateListener<T> {
+
+        /**
+         * Called on each animation frame with the target object, and a map of FloatPropertyCompat
+         * -> AnimationUpdate, containing the latest value and velocity for that property. When
+         * multiple properties are animating together, the map will typically contain one entry for
+         * each property. However, you should never assume that this is the case - when a property
+         * animation ends earlier than the others, you'll receive an UpdateMap containing only that
+         * property's final update. Subsequently, you'll only receive updates for the properties
+         * that are still animating.
+         *
+         * Always check that the map contains an update for the property you're interested in before
+         * accessing it.
+         *
+         * @param target The animated object itself.
+         * @param values Map of property to AnimationUpdate, which contains that property
+         * animation's latest value and velocity. You should never assume that a particular property
+         * is present in this map.
+         */
+        fun onAnimationUpdateForProperty(
+            target: T,
+            values: UpdateMap<T>
+        )
+    }
+
+    /**
+     * Listener for receiving callbacks when animations end.
+     *
+     * @param <T> The type of the object being animated.
+    </T> */
+    interface EndListener<T> {
+
+        /**
+         * Called with the final animation values as each property animation ends. This can be used
+         * to respond to specific property animations concluding (such as hiding a view when ALPHA
+         * ends, even if the corresponding TRANSLATION animations have not ended).
+         *
+         * If you just want to run an action when all of the property animations have ended, you can
+         * use [PhysicsAnimator.withEndActions].
+         *
+         * @param target The animated object itself.
+         * @param property The property whose animation has just ended.
+         * @param wasFling Whether this property ended after a fling animation (as opposed to a
+         * spring animation). If this property was animated via [flingThenSpring], this will be true
+         * if the fling animation did not reach the min/max bounds, decelerating to a stop
+         * naturally. It will be false if it hit the bounds and was sprung back.
+         * @param canceled Whether the animation was explicitly canceled before it naturally ended.
+         * @param finalValue The final value of the animated property.
+         * @param finalVelocity The final velocity (in pixels per second) of the ended animation.
+         * This is typically zero, unless this was a fling animation which ended abruptly due to
+         * reaching its configured min/max values.
+         * @param allRelevantPropertyAnimsEnded Whether all properties relevant to this end listener
+         * have ended. Relevant properties are those which were animated alongside the
+         * [addEndListener] call where this animator was passed in. For example:
+         *
+         * animator
+         *    .spring(TRANSLATION_X, 100f)
+         *    .spring(TRANSLATION_Y, 200f)
+         *    .withEndListener(firstEndListener)
+         *    .start()
+         *
+         * firstEndListener will be called first for TRANSLATION_X, with allEnded = false,
+         * because TRANSLATION_Y is still running. When TRANSLATION_Y ends, it'll be called with
+         * allEnded = true.
+         *
+         * If a subsequent call to start() is made with other properties, those properties are not
+         * considered relevant and allEnded will still equal true when only TRANSLATION_X and
+         * TRANSLATION_Y end. For example, if immediately after the prior example, while
+         * TRANSLATION_X and TRANSLATION_Y are still animating, we called:
+         *
+         * animator.
+         *    .spring(SCALE_X, 2f, stiffness = 10f) // That will take awhile...
+         *    .withEndListener(secondEndListener)
+         *    .start()
+         *
+         * firstEndListener will still be called with allEnded = true when TRANSLATION_X/Y end, even
+         * though SCALE_X is still animating. Similarly, secondEndListener will be called with
+         * allEnded = true as soon as SCALE_X ends, even if the translation animations are still
+         * running.
+         */
+        fun onAnimationEnd(
+            target: T,
+            property: FloatPropertyCompat<in T>,
+            wasFling: Boolean,
+            canceled: Boolean,
+            finalValue: Float,
+            finalVelocity: Float,
+            allRelevantPropertyAnimsEnded: Boolean
+        )
+    }
+
+    companion object {
+
+        /**
+         * Constructor to use to for new physics animator instances in [getInstance]. This is
+         * typically the default constructor, but [PhysicsAnimatorTestUtils] can change it so that
+         * all code using the physics animator is given testable instances instead.
+         */
+        internal var instanceConstructor: (Any) -> PhysicsAnimator<*> = ::PhysicsAnimator
+
+        @JvmStatic
+        @Suppress("UNCHECKED_CAST")
+        fun <T : Any> getInstance(target: T): PhysicsAnimator<T> {
+            if (!animators.containsKey(target)) {
+                animators[target] = instanceConstructor(target)
+            }
+
+            return animators[target] as PhysicsAnimator<T>
+        }
+
+        /**
+         * Set whether all physics animators should log a lot of information about animations.
+         * Useful for debugging!
+         */
+        @JvmStatic
+        fun setVerboseLogging(debug: Boolean) {
+            verboseLogging = debug
+        }
+
+        /**
+         * Estimates the end value of a fling that starts at the given value using the provided
+         * start velocity and fling configuration.
+         *
+         * This is only an estimate. Fling animations use a timing-based physics simulation that is
+         * non-deterministic, so this exact value may not be reached.
+         */
+        @JvmStatic
+        fun estimateFlingEndValue(
+            startValue: Float,
+            startVelocity: Float,
+            flingConfig: FlingConfig
+        ): Float {
+            val distance = startVelocity / (flingConfig.friction * FLING_FRICTION_SCALAR_MULTIPLIER)
+            return Math.min(flingConfig.max, Math.max(flingConfig.min, startValue + distance))
+        }
+
+        @JvmStatic
+        fun getReadablePropertyName(property: FloatPropertyCompat<*>): String {
+            return when (property) {
+                DynamicAnimation.TRANSLATION_X -> "translationX"
+                DynamicAnimation.TRANSLATION_Y -> "translationY"
+                DynamicAnimation.TRANSLATION_Z -> "translationZ"
+                DynamicAnimation.SCALE_X -> "scaleX"
+                DynamicAnimation.SCALE_Y -> "scaleY"
+                DynamicAnimation.ROTATION -> "rotation"
+                DynamicAnimation.ROTATION_X -> "rotationX"
+                DynamicAnimation.ROTATION_Y -> "rotationY"
+                DynamicAnimation.SCROLL_X -> "scrollX"
+                DynamicAnimation.SCROLL_Y -> "scrollY"
+                DynamicAnimation.ALPHA -> "alpha"
+                else -> "Custom FloatPropertyCompat instance"
+            }
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimatorTestUtils.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimatorTestUtils.kt
new file mode 100644
index 0000000..86eb8da
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/animation/PhysicsAnimatorTestUtils.kt
@@ -0,0 +1,485 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.animation
+
+import android.os.Handler
+import android.os.Looper
+import android.util.ArrayMap
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+import com.android.wm.shell.animation.PhysicsAnimatorTestUtils.prepareForTest
+import java.util.*
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+import kotlin.collections.ArrayList
+import kotlin.collections.HashMap
+import kotlin.collections.HashSet
+import kotlin.collections.Set
+import kotlin.collections.component1
+import kotlin.collections.component2
+import kotlin.collections.drop
+import kotlin.collections.forEach
+import kotlin.collections.getOrPut
+import kotlin.collections.set
+import kotlin.collections.toList
+import kotlin.collections.toTypedArray
+
+typealias UpdateMatcher = (PhysicsAnimator.AnimationUpdate) -> Boolean
+typealias UpdateFramesPerProperty<T> =
+        ArrayMap<FloatPropertyCompat<in T>, ArrayList<PhysicsAnimator.AnimationUpdate>>
+
+/**
+ * Utilities for testing code that uses [PhysicsAnimator].
+ *
+ * Start by calling [prepareForTest] at the beginning of each test - this will modify the behavior
+ * of all PhysicsAnimator instances so that they post animations to the main thread (so they don't
+ * crash). It'll also enable the use of the other static helper methods in this class, which you can
+ * use to do things like block the test until animations complete (so you can test end states), or
+ * verify keyframes.
+ */
+object PhysicsAnimatorTestUtils {
+    var timeoutMs: Long = 2000
+    private var startBlocksUntilAnimationsEnd = false
+    private val animationThreadHandler = Handler(Looper.getMainLooper())
+    private val allAnimatedObjects = HashSet<Any>()
+    private val animatorTestHelpers = HashMap<PhysicsAnimator<*>, AnimatorTestHelper<*>>()
+
+    /**
+     * Modifies the behavior of all [PhysicsAnimator] instances so that they post animations to the
+     * main thread, and report all of their
+     */
+    @JvmStatic
+    fun prepareForTest() {
+        val defaultConstructor = PhysicsAnimator.instanceConstructor
+        PhysicsAnimator.instanceConstructor = fun(target: Any): PhysicsAnimator<*> {
+            val animator = defaultConstructor(target)
+            allAnimatedObjects.add(target)
+            animatorTestHelpers[animator] = AnimatorTestHelper(animator)
+            return animator
+        }
+
+        timeoutMs = 2000
+        startBlocksUntilAnimationsEnd = false
+        allAnimatedObjects.clear()
+    }
+
+    @JvmStatic
+    fun tearDown() {
+        val latch = CountDownLatch(1)
+        animationThreadHandler.post {
+            animatorTestHelpers.keys.forEach { it.cancel() }
+            latch.countDown()
+        }
+
+        latch.await()
+
+        animatorTestHelpers.clear()
+        animators.clear()
+        allAnimatedObjects.clear()
+    }
+
+    /**
+     * Sets the maximum time (in milliseconds) to block the test thread while waiting for animations
+     * before throwing an exception.
+     */
+    @JvmStatic
+    fun setBlockTimeout(timeoutMs: Long) {
+        PhysicsAnimatorTestUtils.timeoutMs = timeoutMs
+    }
+
+    /**
+     * Sets whether all animations should block the test thread until they end. This is typically
+     * the desired behavior, since you can invoke code that runs an animation and then assert things
+     * about its end state.
+     */
+    @JvmStatic
+    fun setAllAnimationsBlock(block: Boolean) {
+        startBlocksUntilAnimationsEnd = block
+    }
+
+    /**
+     * Blocks the calling thread until animations of the given property on the target object end.
+     */
+    @JvmStatic
+    @Throws(InterruptedException::class)
+    fun <T : Any> blockUntilAnimationsEnd(
+        animator: PhysicsAnimator<T>,
+        vararg properties: FloatPropertyCompat<in T>
+    ) {
+        val animatingProperties = HashSet<FloatPropertyCompat<in T>>()
+        for (property in properties) {
+            if (animator.isPropertyAnimating(property)) {
+                animatingProperties.add(property)
+            }
+        }
+
+        if (animatingProperties.size > 0) {
+            val latch = CountDownLatch(animatingProperties.size)
+            getAnimationTestHelper(animator).addTestEndListener(
+                    object : PhysicsAnimator.EndListener<T> {
+                override fun onAnimationEnd(
+                    target: T,
+                    property: FloatPropertyCompat<in T>,
+                    wasFling: Boolean,
+                    canceled: Boolean,
+                    finalValue: Float,
+                    finalVelocity: Float,
+                    allRelevantPropertyAnimsEnded: Boolean
+                ) {
+                    if (animatingProperties.contains(property)) {
+                        latch.countDown()
+                    }
+                }
+            })
+
+            latch.await(timeoutMs, TimeUnit.MILLISECONDS)
+        }
+    }
+
+    /**
+     * Blocks the calling thread until all animations of the given property (on all target objects)
+     * have ended. Useful when you don't have access to the objects being animated, but still need
+     * to wait for them to end so that other testable side effects occur (such as update/end
+     * listeners).
+     */
+    @JvmStatic
+    @Throws(InterruptedException::class)
+    @Suppress("UNCHECKED_CAST")
+    fun <T : Any> blockUntilAnimationsEnd(
+        properties: FloatPropertyCompat<in T>
+    ) {
+        for (target in allAnimatedObjects) {
+            try {
+                blockUntilAnimationsEnd(
+                        PhysicsAnimator.getInstance(target) as PhysicsAnimator<T>, properties)
+            } catch (e: ClassCastException) {
+                // Keep checking the other objects for ones whose types match the provided
+                // properties.
+            }
+        }
+    }
+
+    /**
+     * Blocks the calling thread until the first animation frame in which predicate returns true. If
+     * the given object isn't animating, returns without blocking.
+     */
+    @JvmStatic
+    @Throws(InterruptedException::class)
+    fun <T : Any> blockUntilFirstAnimationFrameWhereTrue(
+        animator: PhysicsAnimator<T>,
+        predicate: (T) -> Boolean
+    ) {
+        if (animator.isRunning()) {
+            val latch = CountDownLatch(1)
+            getAnimationTestHelper(animator).addTestUpdateListener(object : PhysicsAnimator
+            .UpdateListener<T> {
+                override fun onAnimationUpdateForProperty(
+                    target: T,
+                    values: UpdateMap<T>
+                ) {
+                    if (predicate(target)) {
+                        latch.countDown()
+                    }
+                }
+            })
+
+            latch.await(timeoutMs, TimeUnit.MILLISECONDS)
+        }
+    }
+
+    /**
+     * Verifies that the animator reported animation frame values to update listeners that satisfy
+     * the given matchers, in order. Not all frames need to satisfy a matcher - we'll run through
+     * all animation frames, and check them against the current predicate. If it returns false, we
+     * continue through the frames until it returns true, and then move on to the next matcher.
+     * Verification fails if we run out of frames while unsatisfied matchers remain.
+     *
+     * If verification is successful, all frames to this point are considered 'verified' and will be
+     * cleared. Subsequent calls to this method will start verification at the next animation frame.
+     *
+     * Example: Verify that an animation surpassed x = 50f before going negative.
+     * verifyAnimationUpdateFrames(
+     *    animator, TRANSLATION_X,
+     *    { u -> u.value > 50f },
+     *    { u -> u.value < 0f })
+     *
+     * Example: verify that an animation went backwards at some point while still being on-screen.
+     * verifyAnimationUpdateFrames(
+     *    animator, TRANSLATION_X,
+     *    { u -> u.velocity < 0f && u.value >= 0f })
+     *
+     * This method is intended to help you test longer, more complicated animations where it's
+     * critical that certain values were reached. Using this method to test short animations can
+     * fail due to the animation having fewer frames than provided matchers. For example, an
+     * animation from x = 1f to x = 5f might only have two frames, at x = 3f and x = 5f. The
+     * following would then fail despite it seeming logically sound:
+     *
+     * verifyAnimationUpdateFrames(
+     *    animator, TRANSLATION_X,
+     *    { u -> u.value > 1f },
+     *    { u -> u.value > 2f },
+     *    { u -> u.value > 3f })
+     *
+     * Tests might also fail if your matchers are too granular, such as this example test after an
+     * animation from x = 0f to x = 100f. It's unlikely there was a frame specifically between 2f
+     * and 3f.
+     *
+     * verifyAnimationUpdateFrames(
+     *    animator, TRANSLATION_X,
+     *    { u -> u.value > 2f && u.value < 3f },
+     *    { u -> u.value >= 50f })
+     *
+     * Failures will print a helpful log of all animation frames so you can see what caused the test
+     * to fail.
+     */
+    fun <T : Any> verifyAnimationUpdateFrames(
+        animator: PhysicsAnimator<T>,
+        property: FloatPropertyCompat<in T>,
+        firstUpdateMatcher: UpdateMatcher,
+        vararg additionalUpdateMatchers: UpdateMatcher
+    ) {
+        val updateFrames: UpdateFramesPerProperty<T> = getAnimationUpdateFrames(animator)
+
+        if (!updateFrames.containsKey(property)) {
+            error("No frames for given target object and property.")
+        }
+
+        // Copy the frames to avoid a ConcurrentModificationException if the animation update
+        // listeners attempt to add a new frame while we're verifying these.
+        val framesForProperty = ArrayList(updateFrames[property]!!)
+        val matchers = ArrayDeque<UpdateMatcher>(
+                additionalUpdateMatchers.toList())
+        val frameTraceMessage = StringBuilder()
+
+        var curMatcher = firstUpdateMatcher
+
+        // Loop through the updates from the testable animator.
+        for (update in framesForProperty) {
+
+            // Check whether this frame satisfies the current matcher.
+            if (curMatcher(update)) {
+
+                // If that was the last unsatisfied matcher, we're good here. 'Verify' all remaining
+                // frames and return without failing.
+                if (matchers.size == 0) {
+                    getAnimationUpdateFrames(animator).remove(property)
+                    return
+                }
+
+                frameTraceMessage.append("$update\t(satisfied matcher)\n")
+                curMatcher = matchers.pop() // Get the next matcher and keep going.
+            } else {
+                frameTraceMessage.append("${update}\n")
+            }
+        }
+
+        val readablePropertyName = PhysicsAnimator.getReadablePropertyName(property)
+        getAnimationUpdateFrames(animator).remove(property)
+
+        throw RuntimeException(
+                "Failed to verify animation frames for property $readablePropertyName: " +
+                        "Provided ${additionalUpdateMatchers.size + 1} matchers, " +
+                        "however ${matchers.size + 1} remained unsatisfied.\n\n" +
+                        "All frames:\n$frameTraceMessage")
+    }
+
+    /**
+     * Overload of [verifyAnimationUpdateFrames] that builds matchers for you, from given float
+     * values. For example, to verify that an animations passed from 0f to 50f to 100f back to 50f:
+     *
+     * verifyAnimationUpdateFrames(animator, TRANSLATION_X, 0f, 50f, 100f, 50f)
+     *
+     * This verifies that update frames were received with values of >= 0f, >= 50f, >= 100f, and
+     * <= 50f.
+     *
+     * The same caveats apply: short animations might not have enough frames to satisfy all of the
+     * matchers, and overly specific calls (such as 0f, 1f, 2f, 3f, etc. for an animation from
+     * x = 0f to x = 100f) might fail as the animation only had frames at 0f, 25f, 50f, 75f, and
+     * 100f. As with [verifyAnimationUpdateFrames], failures will print a helpful log of all frames
+     * so you can see what caused the test to fail.
+     */
+    fun <T : Any> verifyAnimationUpdateFrames(
+        animator: PhysicsAnimator<T>,
+        property: FloatPropertyCompat<in T>,
+        startValue: Float,
+        firstTargetValue: Float,
+        vararg additionalTargetValues: Float
+    ) {
+        val matchers = ArrayList<UpdateMatcher>()
+
+        val values = ArrayList<Float>().also {
+            it.add(firstTargetValue)
+            it.addAll(additionalTargetValues.toList())
+        }
+
+        var prevVal = startValue
+        for (value in values) {
+            if (value > prevVal) {
+                matchers.add { update -> update.value >= value }
+            } else {
+                matchers.add { update -> update.value <= value }
+            }
+
+            prevVal = value
+        }
+
+        verifyAnimationUpdateFrames(
+                animator, property, matchers[0], *matchers.drop(0).toTypedArray())
+    }
+
+    /**
+     * Returns all of the values that have ever been reported to update listeners, per property.
+     */
+    @Suppress("UNCHECKED_CAST")
+    fun <T : Any> getAnimationUpdateFrames(animator: PhysicsAnimator<T>):
+            UpdateFramesPerProperty<T> {
+        return animatorTestHelpers[animator]?.getUpdates() as UpdateFramesPerProperty<T>
+    }
+
+    /**
+     * Clears animation frame updates from the given animator so they aren't used the next time its
+     * passed to [verifyAnimationUpdateFrames].
+     */
+    fun <T : Any> clearAnimationUpdateFrames(animator: PhysicsAnimator<T>) {
+        animatorTestHelpers[animator]?.clearUpdates()
+    }
+
+    @Suppress("UNCHECKED_CAST")
+    private fun <T> getAnimationTestHelper(animator: PhysicsAnimator<T>): AnimatorTestHelper<T> {
+        return animatorTestHelpers[animator] as AnimatorTestHelper<T>
+    }
+
+    /**
+     * Helper class for testing an animator. This replaces the animator's start action with
+     * [startForTest] and adds test listeners to enable other test utility behaviors. We build one
+     * these for each Animator and keep them around so we can access the updates.
+     */
+    class AnimatorTestHelper<T> (private val animator: PhysicsAnimator<T>) {
+
+        /** All updates received for each property animation. */
+        private val allUpdates =
+                ArrayMap<FloatPropertyCompat<in T>, ArrayList<PhysicsAnimator.AnimationUpdate>>()
+
+        private val testEndListeners = ArrayList<PhysicsAnimator.EndListener<T>>()
+        private val testUpdateListeners = ArrayList<PhysicsAnimator.UpdateListener<T>>()
+
+        /** Whether we're currently in the middle of executing startInternal(). */
+        private var currentlyRunningStartInternal = false
+
+        init {
+            animator.startAction = ::startForTest
+            animator.cancelAction = ::cancelForTest
+        }
+
+        internal fun addTestEndListener(listener: PhysicsAnimator.EndListener<T>) {
+            testEndListeners.add(listener)
+        }
+
+        internal fun addTestUpdateListener(listener: PhysicsAnimator.UpdateListener<T>) {
+            testUpdateListeners.add(listener)
+        }
+
+        internal fun getUpdates(): UpdateFramesPerProperty<T> {
+            return allUpdates
+        }
+
+        internal fun clearUpdates() {
+            allUpdates.clear()
+        }
+
+        private fun startForTest() {
+            // The testable animator needs to block the main thread until super.start() has been
+            // called, since callers expect .start() to be synchronous but we're posting it to a
+            // handler here. We may also continue blocking until all animations end, if
+            // startBlocksUntilAnimationsEnd = true.
+            val unblockLatch = CountDownLatch(if (startBlocksUntilAnimationsEnd) 2 else 1)
+
+            animationThreadHandler.post {
+                // Add an update listener that dispatches to any test update listeners added by
+                // tests.
+                animator.addUpdateListener(object : PhysicsAnimator.UpdateListener<T> {
+                    override fun onAnimationUpdateForProperty(
+                        target: T,
+                        values: ArrayMap<FloatPropertyCompat<in T>, PhysicsAnimator.AnimationUpdate>
+                    ) {
+                        values.forEach { (property, value) ->
+                            allUpdates.getOrPut(property, { ArrayList() }).add(value)
+                        }
+
+                        for (listener in testUpdateListeners) {
+                            listener.onAnimationUpdateForProperty(target, values)
+                        }
+                    }
+                })
+
+                // Add an end listener that dispatches to any test end listeners added by tests, and
+                // unblocks the main thread if required.
+                animator.addEndListener(object : PhysicsAnimator.EndListener<T> {
+                    override fun onAnimationEnd(
+                        target: T,
+                        property: FloatPropertyCompat<in T>,
+                        wasFling: Boolean,
+                        canceled: Boolean,
+                        finalValue: Float,
+                        finalVelocity: Float,
+                        allRelevantPropertyAnimsEnded: Boolean
+                    ) {
+                        for (listener in testEndListeners) {
+                            listener.onAnimationEnd(
+                                    target, property, wasFling, canceled, finalValue, finalVelocity,
+                                    allRelevantPropertyAnimsEnded)
+                        }
+
+                        if (allRelevantPropertyAnimsEnded) {
+                            testEndListeners.clear()
+                            testUpdateListeners.clear()
+
+                            if (startBlocksUntilAnimationsEnd) {
+                                unblockLatch.countDown()
+                            }
+                        }
+                    }
+                })
+
+                currentlyRunningStartInternal = true
+                animator.startInternal()
+                currentlyRunningStartInternal = false
+                unblockLatch.countDown()
+            }
+
+            unblockLatch.await(timeoutMs, TimeUnit.MILLISECONDS)
+        }
+
+        private fun cancelForTest(properties: Set<FloatPropertyCompat<in T>>) {
+            // If this was called from startInternal, we are already on the animation thread, and
+            // should just call cancelInternal rather than posting it. If we post it, the
+            // cancellation will occur after the rest of startInternal() and we'll immediately
+            // cancel the animation we worked so hard to start!
+            if (currentlyRunningStartInternal) {
+                animator.cancelInternal(properties)
+                return
+            }
+
+            val unblockLatch = CountDownLatch(1)
+
+            animationThreadHandler.post {
+                animator.cancelInternal(properties)
+                unblockLatch.countDown()
+            }
+
+            unblockLatch.await(timeoutMs, TimeUnit.MILLISECONDS)
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/DismissCircleView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DismissCircleView.java
new file mode 100644
index 0000000..976fba5
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/DismissCircleView.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.common;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.view.Gravity;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+
+import com.android.wm.shell.R;
+
+/**
+ * Circular view with a semitransparent, circular background with an 'X' inside it.
+ *
+ * This is used by both Bubbles and PIP as the dismiss target.
+ */
+public class DismissCircleView extends FrameLayout {
+
+    private final ImageView mIconView = new ImageView(getContext());
+
+    public DismissCircleView(Context context) {
+        super(context);
+        final Resources res = getResources();
+
+        setBackground(res.getDrawable(R.drawable.dismiss_circle_background));
+
+        mIconView.setImageDrawable(res.getDrawable(R.drawable.pip_ic_close_white));
+        addView(mIconView);
+
+        setViewSizes();
+    }
+
+    @Override
+    protected void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        setViewSizes();
+    }
+
+    /** Retrieves the current dimensions for the icon and circle and applies them. */
+    private void setViewSizes() {
+        final Resources res = getResources();
+        final int iconSize = res.getDimensionPixelSize(R.dimen.dismiss_target_x_size);
+        mIconView.setLayoutParams(
+                new FrameLayout.LayoutParams(iconSize, iconSize, Gravity.CENTER));
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/FloatingContentCoordinator.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/FloatingContentCoordinator.kt
new file mode 100644
index 0000000..d5d072a
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/FloatingContentCoordinator.kt
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.common
+
+import android.graphics.Rect
+import android.util.Log
+import com.android.wm.shell.common.FloatingContentCoordinator.FloatingContent
+import java.util.HashMap
+
+/** Tag for debug logging. */
+private const val TAG = "FloatingCoordinator"
+
+/**
+ * Coordinates the positions and movement of floating content, such as PIP and Bubbles, to ensure
+ * that they don't overlap. If content does overlap due to content appearing or moving, the
+ * coordinator will ask content to move to resolve the conflict.
+ *
+ * After implementing [FloatingContent], content should call [onContentAdded] to begin coordination.
+ * Subsequently, call [onContentMoved] whenever the content moves, and the coordinator will move
+ * other content out of the way. [onContentRemoved] should be called when the content is removed or
+ * no longer visible.
+ */
+
+class FloatingContentCoordinator constructor() {
+    /**
+     * Represents a piece of floating content, such as PIP or the Bubbles stack. Provides methods
+     * that allow the [FloatingContentCoordinator] to determine the current location of the content,
+     * as well as the ability to ask it to move out of the way of other content.
+     *
+     * The default implementation of [calculateNewBoundsOnOverlap] moves the content up or down,
+     * depending on the position of the conflicting content. You can override this method if you
+     * want your own custom conflict resolution logic.
+     */
+    interface FloatingContent {
+
+        /**
+         * Return the bounds claimed by this content. This should include the bounds occupied by the
+         * content itself, as well as any padding, if desired. The coordinator will ensure that no
+         * other content is located within these bounds.
+         *
+         * If the content is animating, this method should return the bounds to which the content is
+         * animating. If that animation is cancelled, or updated, be sure that your implementation
+         * of this method returns the appropriate bounds, and call [onContentMoved] so that the
+         * coordinator moves other content out of the way.
+         */
+        fun getFloatingBoundsOnScreen(): Rect
+
+        /**
+         * Return the area within which this floating content is allowed to move. When resolving
+         * conflicts, the coordinator will never ask your content to move to a position where any
+         * part of the content would be out of these bounds.
+         */
+        fun getAllowedFloatingBoundsRegion(): Rect
+
+        /**
+         * Called when the coordinator needs this content to move to the given bounds. It's up to
+         * you how to do that.
+         *
+         * Note that if you start an animation to these bounds, [getFloatingBoundsOnScreen] should
+         * return the destination bounds, not the in-progress animated bounds. This is so the
+         * coordinator knows where floating content is going to be and can resolve conflicts
+         * accordingly.
+         */
+        fun moveToBounds(bounds: Rect)
+
+        /**
+         * Called by the coordinator when it needs to find a new home for this floating content,
+         * because a new or moving piece of content is now overlapping with it.
+         *
+         * [findAreaForContentVertically] and [findAreaForContentAboveOrBelow] are helpful utility
+         * functions that will find new bounds for your content automatically. Unless you require
+         * specific conflict resolution logic, these should be sufficient. By default, this method
+         * delegates to [findAreaForContentVertically].
+         *
+         * @param overlappingContentBounds The bounds of the other piece of content, which
+         * necessitated this content's relocation. Your new position must not overlap with these
+         * bounds.
+         * @param otherContentBounds The bounds of any other pieces of floating content. Your new
+         * position must not overlap with any of these either. These bounds are guaranteed to be
+         * non-overlapping.
+         * @return The new bounds for this content.
+         */
+        @JvmDefault
+        fun calculateNewBoundsOnOverlap(
+            overlappingContentBounds: Rect,
+            otherContentBounds: List<Rect>
+        ): Rect {
+            return findAreaForContentVertically(
+                    getFloatingBoundsOnScreen(),
+                    overlappingContentBounds,
+                    otherContentBounds,
+                    getAllowedFloatingBoundsRegion())
+        }
+    }
+
+    /** The bounds of all pieces of floating content added to the coordinator. */
+    private val allContentBounds: MutableMap<FloatingContent, Rect> = HashMap()
+
+    /**
+     * Whether we are currently resolving conflicts by asking content to move. If we are, we'll
+     * temporarily ignore calls to [onContentMoved] - those calls are from the content that is
+     * moving to new, conflict-free bounds, so we don't need to perform conflict detection
+     * calculations in response.
+     */
+    private var currentlyResolvingConflicts = false
+
+    /**
+     * Makes the coordinator aware of a new piece of floating content, and moves any existing
+     * content out of the way, if necessary.
+     *
+     * If you don't want your new content to move existing content, use [getOccupiedBounds] to find
+     * an unoccupied area, and move the content there before calling this method.
+     */
+    fun onContentAdded(newContent: FloatingContent) {
+        updateContentBounds()
+        allContentBounds[newContent] = newContent.getFloatingBoundsOnScreen()
+        maybeMoveConflictingContent(newContent)
+    }
+
+    /**
+     * Called to notify the coordinator that a piece of floating content has moved (or is animating)
+     * to a new position, and that any conflicting floating content should be moved out of the way.
+     *
+     * The coordinator will call [FloatingContent.getFloatingBoundsOnScreen] to find the new bounds
+     * for the moving content. If you're animating the content, be sure that your implementation of
+     * getFloatingBoundsOnScreen returns the bounds to which it's animating, not the content's
+     * current bounds.
+     *
+     * If the animation moving this content is cancelled or updated, you'll need to call this method
+     * again, to ensure that content is moved out of the way of the latest bounds.
+     *
+     * @param content The content that has moved.
+     */
+    fun onContentMoved(content: FloatingContent) {
+
+        // Ignore calls when we are currently resolving conflicts, since those calls are from
+        // content that is moving to new, conflict-free bounds.
+        if (currentlyResolvingConflicts) {
+            return
+        }
+
+        if (!allContentBounds.containsKey(content)) {
+            Log.wtf(TAG, "Received onContentMoved call before onContentAdded! " +
+                    "This should never happen.")
+            return
+        }
+
+        updateContentBounds()
+        maybeMoveConflictingContent(content)
+    }
+
+    /**
+     * Called to notify the coordinator that a piece of floating content has been removed or is no
+     * longer visible.
+     */
+    fun onContentRemoved(removedContent: FloatingContent) {
+        allContentBounds.remove(removedContent)
+    }
+
+    /**
+     * Returns a set of Rects that represent the bounds of all of the floating content on the
+     * screen.
+     *
+     * [onContentAdded] will move existing content out of the way if the added content intersects
+     * existing content. That's fine - but if your specific starting position is not important, you
+     * can use this function to find unoccupied space for your content before calling
+     * [onContentAdded], so that moving existing content isn't necessary.
+     */
+    fun getOccupiedBounds(): Collection<Rect> {
+        return allContentBounds.values
+    }
+
+    /**
+     * Identifies any pieces of content that are now overlapping with the given content, and asks
+     * them to move out of the way.
+     */
+    private fun maybeMoveConflictingContent(fromContent: FloatingContent) {
+        currentlyResolvingConflicts = true
+
+        val conflictingNewBounds = allContentBounds[fromContent]!!
+        allContentBounds
+                // Filter to content that intersects with the new bounds. That's content that needs
+                // to move.
+                .filter { (content, bounds) ->
+                    content != fromContent && Rect.intersects(conflictingNewBounds, bounds) }
+                // Tell that content to get out of the way, and save the bounds it says it's moving
+                // (or animating) to.
+                .forEach { (content, bounds) ->
+                    val newBounds = content.calculateNewBoundsOnOverlap(
+                            conflictingNewBounds,
+                            // Pass all of the content bounds except the bounds of the
+                            // content we're asking to move, and the conflicting new bounds
+                            // (since those are passed separately).
+                            otherContentBounds = allContentBounds.values
+                                    .minus(bounds)
+                                    .minus(conflictingNewBounds))
+
+                    // If the new bounds are empty, it means there's no non-overlapping position
+                    // that is in bounds. Just leave the content where it is. This should normally
+                    // not happen, but sometimes content like PIP reports incorrect bounds
+                    // temporarily.
+                    if (!newBounds.isEmpty) {
+                        content.moveToBounds(newBounds)
+                        allContentBounds[content] = content.getFloatingBoundsOnScreen()
+                    }
+                }
+
+        currentlyResolvingConflicts = false
+    }
+
+    /**
+     * Update [allContentBounds] by calling [FloatingContent.getFloatingBoundsOnScreen] for all
+     * content and saving the result.
+     */
+    private fun updateContentBounds() {
+        allContentBounds.keys.forEach { allContentBounds[it] = it.getFloatingBoundsOnScreen() }
+    }
+
+    companion object {
+        /**
+         * Finds new bounds for the given content, either above or below its current position. The
+         * new bounds won't intersect with the newly overlapping rect or the exclusion rects, and
+         * will be within the allowed bounds unless no possible position exists.
+         *
+         * You can use this method to help find a new position for your content when the coordinator
+         * calls [FloatingContent.moveToAreaExcluding].
+         *
+         * @param contentRect The bounds of the content for which we're finding a new home.
+         * @param newlyOverlappingRect The bounds of the content that forced this relocation by
+         * intersecting with the content we now need to move. If the overlapping content is
+         * overlapping the top half of this content, we'll try to move this content downward if
+         * possible (since the other content is 'pushing' it down), and vice versa.
+         * @param exclusionRects Any other areas that we need to avoid when finding a new home for
+         * the content. These areas must be non-overlapping with each other.
+         * @param allowedBounds The area within which we're allowed to find new bounds for the
+         * content.
+         * @return New bounds for the content that don't intersect the exclusion rects or the
+         * newly overlapping rect, and that is within bounds - or an empty Rect if no in-bounds
+         * position exists.
+         */
+        @JvmStatic
+        fun findAreaForContentVertically(
+            contentRect: Rect,
+            newlyOverlappingRect: Rect,
+            exclusionRects: Collection<Rect>,
+            allowedBounds: Rect
+        ): Rect {
+            // If the newly overlapping Rect's center is above the content's center, we'll prefer to
+            // find a space for this content that is below the overlapping content, since it's
+            // 'pushing' it down. This may not be possible due to to screen bounds, in which case
+            // we'll find space in the other direction.
+            val overlappingContentPushingDown =
+                    newlyOverlappingRect.centerY() < contentRect.centerY()
+
+            // Filter to exclusion rects that are above or below the content that we're finding a
+            // place for. Then, split into two lists - rects above the content, and rects below it.
+            var (rectsToAvoidAbove, rectsToAvoidBelow) = exclusionRects
+                    .filter { rectToAvoid -> rectsIntersectVertically(rectToAvoid, contentRect) }
+                    .partition { rectToAvoid -> rectToAvoid.top < contentRect.top }
+
+            // Lazily calculate the closest possible new tops for the content, above and below its
+            // current location.
+            val newContentBoundsAbove by lazy {
+                findAreaForContentAboveOrBelow(
+                        contentRect,
+                        exclusionRects = rectsToAvoidAbove.plus(newlyOverlappingRect),
+                        findAbove = true)
+            }
+            val newContentBoundsBelow by lazy {
+                findAreaForContentAboveOrBelow(
+                        contentRect,
+                        exclusionRects = rectsToAvoidBelow.plus(newlyOverlappingRect),
+                        findAbove = false)
+            }
+
+            val positionAboveInBounds by lazy { allowedBounds.contains(newContentBoundsAbove) }
+            val positionBelowInBounds by lazy { allowedBounds.contains(newContentBoundsBelow) }
+
+            // Use the 'below' position if the content is being overlapped from the top, unless it's
+            // out of bounds. Also use it if the content is being overlapped from the bottom, but
+            // the 'above' position is out of bounds. Otherwise, use the 'above' position.
+            val usePositionBelow =
+                    overlappingContentPushingDown && positionBelowInBounds ||
+                            !overlappingContentPushingDown && !positionAboveInBounds
+
+            // Return the content rect, but offset to reflect the new position.
+            val newBounds = if (usePositionBelow) newContentBoundsBelow else newContentBoundsAbove
+
+            // If the new bounds are within the allowed bounds, return them. If not, it means that
+            // there are no legal new bounds. This can happen if the new content's bounds are too
+            // large (for example, full-screen PIP). Since there is no reasonable action to take
+            // here, return an empty Rect and we will just not move the content.
+            return if (allowedBounds.contains(newBounds)) newBounds else Rect()
+        }
+
+        /**
+         * Finds a new position for the given content, either above or below its current position
+         * depending on whether [findAbove] is true or false, respectively. This new position will
+         * not intersect with any of the [exclusionRects].
+         *
+         * This method is useful as a helper method for implementing your own conflict resolution
+         * logic. Otherwise, you'd want to use [findAreaForContentVertically], which takes screen
+         * bounds and conflicting bounds' location into account when deciding whether to move to new
+         * bounds above or below the current bounds.
+         *
+         * @param contentRect The content we're finding an area for.
+         * @param exclusionRects The areas we need to avoid when finding a new area for the content.
+         * These areas must be non-overlapping with each other.
+         * @param findAbove Whether we are finding an area above the content's current position,
+         * rather than an area below it.
+         */
+        fun findAreaForContentAboveOrBelow(
+            contentRect: Rect,
+            exclusionRects: Collection<Rect>,
+            findAbove: Boolean
+        ): Rect {
+            // Sort the rects, since we want to move the content as little as possible. We'll
+            // start with the rects closest to the content and move outward. If we're finding an
+            // area above the content, that means we sort in reverse order to search the rects
+            // from highest to lowest y-value.
+            val sortedExclusionRects =
+                    exclusionRects.sortedBy { if (findAbove) -it.top else it.top }
+
+            val proposedNewBounds = Rect(contentRect)
+            for (exclusionRect in sortedExclusionRects) {
+                // If the proposed new bounds don't intersect with this exclusion rect, that
+                // means there's room for the content here. We know this because the rects are
+                // sorted and non-overlapping, so any subsequent exclusion rects would be higher
+                // (or lower) than this one and can't possibly intersect if this one doesn't.
+                if (!Rect.intersects(proposedNewBounds, exclusionRect)) {
+                    break
+                } else {
+                    // Otherwise, we need to keep searching for new bounds. If we're finding an
+                    // area above, propose new bounds that place the content just above the
+                    // exclusion rect. If we're finding an area below, propose new bounds that
+                    // place the content just below the exclusion rect.
+                    val verticalOffset =
+                            if (findAbove) -contentRect.height() else exclusionRect.height()
+                    proposedNewBounds.offsetTo(
+                            proposedNewBounds.left,
+                            exclusionRect.top + verticalOffset)
+                }
+            }
+
+            return proposedNewBounds
+        }
+
+        /** Returns whether or not the two Rects share any of the same space on the X axis. */
+        private fun rectsIntersectVertically(r1: Rect, r2: Rect): Boolean {
+            return (r1.left >= r2.left && r1.left <= r2.right) ||
+                    (r1.right <= r2.right && r1.right >= r2.left)
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/magnetictarget/MagnetizedObject.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/common/magnetictarget/MagnetizedObject.kt
new file mode 100644
index 0000000..b4d7387
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/magnetictarget/MagnetizedObject.kt
@@ -0,0 +1,699 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.common.magnetictarget
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.database.ContentObserver
+import android.graphics.PointF
+import android.os.Handler
+import android.os.UserHandle
+import android.os.VibrationEffect
+import android.os.Vibrator
+import android.provider.Settings
+import android.view.MotionEvent
+import android.view.VelocityTracker
+import android.view.View
+import android.view.ViewConfiguration
+import androidx.dynamicanimation.animation.DynamicAnimation
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+import androidx.dynamicanimation.animation.SpringForce
+import com.android.wm.shell.animation.PhysicsAnimator
+import kotlin.math.abs
+import kotlin.math.hypot
+
+/**
+ * Utility class for creating 'magnetized' objects that are attracted to one or more magnetic
+ * targets. Magnetic targets attract objects that are dragged near them, and hold them there unless
+ * they're moved away or released. Releasing objects inside a magnetic target typically performs an
+ * action on the object.
+ *
+ * MagnetizedObject also supports flinging to targets, which will result in the object being pulled
+ * into the target and released as if it was dragged into it.
+ *
+ * To use this class, either construct an instance with an object of arbitrary type, or use the
+ * [MagnetizedObject.magnetizeView] shortcut method if you're magnetizing a view. Then, set
+ * [magnetListener] to receive event callbacks. In your touch handler, pass all MotionEvents
+ * that move this object to [maybeConsumeMotionEvent]. If that method returns true, consider the
+ * event consumed by the MagnetizedObject and don't move the object unless it begins returning false
+ * again.
+ *
+ * @param context Context, used to retrieve a Vibrator instance for vibration effects.
+ * @param underlyingObject The actual object that we're magnetizing.
+ * @param xProperty Property that sets the x value of the object's position.
+ * @param yProperty Property that sets the y value of the object's position.
+ */
+abstract class MagnetizedObject<T : Any>(
+    val context: Context,
+
+    /** The actual object that is animated. */
+    val underlyingObject: T,
+
+    /** Property that gets/sets the object's X value. */
+    val xProperty: FloatPropertyCompat<in T>,
+
+    /** Property that gets/sets the object's Y value. */
+    val yProperty: FloatPropertyCompat<in T>
+) {
+
+    /** Return the width of the object. */
+    abstract fun getWidth(underlyingObject: T): Float
+
+    /** Return the height of the object. */
+    abstract fun getHeight(underlyingObject: T): Float
+
+    /**
+     * Fill the provided array with the location of the top-left of the object, relative to the
+     * entire screen. Compare to [View.getLocationOnScreen].
+     */
+    abstract fun getLocationOnScreen(underlyingObject: T, loc: IntArray)
+
+    /** Methods for listening to events involving a magnetized object.  */
+    interface MagnetListener {
+
+        /**
+         * Called when touch events move within the magnetic field of a target, causing the
+         * object to animate to the target and become 'stuck' there. The animation happens
+         * automatically here - you should not move the object. You can, however, change its state
+         * to indicate to the user that it's inside the target and releasing it will have an effect.
+         *
+         * [maybeConsumeMotionEvent] is now returning true and will continue to do so until a call
+         * to [onUnstuckFromTarget] or [onReleasedInTarget].
+         *
+         * @param target The target that the object is now stuck to.
+         */
+        fun onStuckToTarget(target: MagneticTarget)
+
+        /**
+         * Called when the object is no longer stuck to a target. This means that either touch
+         * events moved outside of the magnetic field radius, or that a forceful fling out of the
+         * target was detected.
+         *
+         * The object won't be automatically animated out of the target, since you're responsible
+         * for moving the object again. You should move it (or animate it) using your own
+         * movement/animation logic.
+         *
+         * Reverse any effects applied in [onStuckToTarget] here.
+         *
+         * If [wasFlungOut] is true, [maybeConsumeMotionEvent] returned true for the ACTION_UP event
+         * that concluded the fling. If [wasFlungOut] is false, that means a drag gesture is ongoing
+         * and [maybeConsumeMotionEvent] is now returning false.
+         *
+         * @param target The target that this object was just unstuck from.
+         * @param velX The X velocity of the touch gesture when it exited the magnetic field.
+         * @param velY The Y velocity of the touch gesture when it exited the magnetic field.
+         * @param wasFlungOut Whether the object was unstuck via a fling gesture. This means that
+         * an ACTION_UP event was received, and that the gesture velocity was sufficient to conclude
+         * that the user wants to un-stick the object despite no touch events occurring outside of
+         * the magnetic field radius.
+         */
+        fun onUnstuckFromTarget(
+            target: MagneticTarget,
+            velX: Float,
+            velY: Float,
+            wasFlungOut: Boolean
+        )
+
+        /**
+         * Called when the object is released inside a target, or flung towards it with enough
+         * velocity to reach it.
+         *
+         * @param target The target that the object was released in.
+         */
+        fun onReleasedInTarget(target: MagneticTarget)
+    }
+
+    private val animator: PhysicsAnimator<T> = PhysicsAnimator.getInstance(underlyingObject)
+    private val objectLocationOnScreen = IntArray(2)
+
+    /**
+     * Targets that have been added to this object. These will all be considered when determining
+     * magnetic fields and fling trajectories.
+     */
+    private val associatedTargets = ArrayList<MagneticTarget>()
+
+    private val velocityTracker: VelocityTracker = VelocityTracker.obtain()
+    private val vibrator: Vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
+
+    private var touchDown = PointF()
+    private var touchSlop = 0
+    private var movedBeyondSlop = false
+
+    /** Whether touch events are presently occurring within the magnetic field area of a target. */
+    val objectStuckToTarget: Boolean
+        get() = targetObjectIsStuckTo != null
+
+    /** The target the object is stuck to, or null if the object is not stuck to any target. */
+    private var targetObjectIsStuckTo: MagneticTarget? = null
+
+    /**
+     * Sets the listener to receive events. This must be set, or [maybeConsumeMotionEvent]
+     * will always return false and no magnetic effects will occur.
+     */
+    lateinit var magnetListener: MagnetizedObject.MagnetListener
+
+    /**
+     * Optional update listener to provide to the PhysicsAnimator that is used to spring the object
+     * into the target.
+     */
+    var physicsAnimatorUpdateListener: PhysicsAnimator.UpdateListener<T>? = null
+
+    /**
+     * Optional end listener to provide to the PhysicsAnimator that is used to spring the object
+     * into the target.
+     */
+    var physicsAnimatorEndListener: PhysicsAnimator.EndListener<T>? = null
+
+    /**
+     * Method that is called when the object should be animated stuck to the target. The default
+     * implementation uses the object's x and y properties to animate the object centered inside the
+     * target. You can override this if you need custom animation.
+     *
+     * The method is invoked with the MagneticTarget that the object is sticking to, the X and Y
+     * velocities of the gesture that brought the object into the magnetic radius, whether or not it
+     * was flung, and a callback you must call after your animation completes.
+     */
+    var animateStuckToTarget: (MagneticTarget, Float, Float, Boolean, (() -> Unit)?) -> Unit =
+            ::animateStuckToTargetInternal
+
+    /**
+     * Sets whether forcefully flinging the object vertically towards a target causes it to be
+     * attracted to the target and then released immediately, despite never being dragged within the
+     * magnetic field.
+     */
+    var flingToTargetEnabled = true
+
+    /**
+     * If fling to target is enabled, forcefully flinging the object towards a target will cause
+     * it to be attracted to the target and then released immediately, despite never being dragged
+     * within the magnetic field.
+     *
+     * This sets the width of the area considered 'near' enough a target to be considered a fling,
+     * in terms of percent of the target view's width. For example, setting this to 3f means that
+     * flings towards a 100px-wide target will be considered 'near' enough if they're towards the
+     * 300px-wide area around the target.
+     *
+     * Flings whose trajectory intersects the area will be attracted and released - even if the
+     * target view itself isn't intersected:
+     *
+     * |             |
+     * |           0 |
+     * |          /  |
+     * |         /   |
+     * |      X /    |
+     * |.....###.....|
+     *
+     *
+     * Flings towards the target whose trajectories do not intersect the area will be treated as
+     * normal flings and the magnet will leave the object alone:
+     *
+     * |             |
+     * |             |
+     * |   0         |
+     * |  /          |
+     * | /    X      |
+     * |.....###.....|
+     *
+     */
+    var flingToTargetWidthPercent = 3f
+
+    /**
+     * Sets the minimum velocity (in pixels per second) required to fling an object to the target
+     * without dragging it into the magnetic field.
+     */
+    var flingToTargetMinVelocity = 4000f
+
+    /**
+     * Sets the minimum velocity (in pixels per second) required to fling un-stuck an object stuck
+     * to the target. If this velocity is reached, the object will be freed even if it wasn't moved
+     * outside the magnetic field radius.
+     */
+    var flingUnstuckFromTargetMinVelocity = 4000f
+
+    /**
+     * Sets the maximum X velocity above which the object will not stick to the target. Even if the
+     * object is dragged through the magnetic field, it will not stick to the target until the
+     * horizontal velocity is below this value.
+     */
+    var stickToTargetMaxXVelocity = 2000f
+
+    /**
+     * Enable or disable haptic vibration effects when the object interacts with the magnetic field.
+     *
+     * If you're experiencing crashes when the object enters targets, ensure that you have the
+     * android.permission.VIBRATE permission!
+     */
+    var hapticsEnabled = true
+
+    /** Default spring configuration to use for animating the object into a target. */
+    var springConfig = PhysicsAnimator.SpringConfig(
+            SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_NO_BOUNCY)
+
+    /**
+     * Spring configuration to use to spring the object into a target specifically when it's flung
+     * towards (rather than dragged near) it.
+     */
+    var flungIntoTargetSpringConfig = springConfig
+
+    init {
+        initHapticSettingObserver(context)
+    }
+
+    /**
+     * Adds the provided MagneticTarget to this object. The object will now be attracted to the
+     * target if it strays within its magnetic field or is flung towards it.
+     *
+     * If this target (or its magnetic field) overlaps another target added to this object, the
+     * prior target will take priority.
+     */
+    fun addTarget(target: MagneticTarget) {
+        associatedTargets.add(target)
+        target.updateLocationOnScreen()
+    }
+
+    /**
+     * Shortcut that accepts a View and a magnetic field radius and adds it as a magnetic target.
+     *
+     * @return The MagneticTarget instance for the given View. This can be used to change the
+     * target's magnetic field radius after it's been added. It can also be added to other
+     * magnetized objects.
+     */
+    fun addTarget(target: View, magneticFieldRadiusPx: Int): MagneticTarget {
+        return MagneticTarget(target, magneticFieldRadiusPx).also { addTarget(it) }
+    }
+
+    /**
+     * Removes the given target from this object. The target will no longer attract the object.
+     */
+    fun removeTarget(target: MagneticTarget) {
+        associatedTargets.remove(target)
+    }
+
+    /**
+     * Provide this method with all motion events that move the magnetized object. If the
+     * location of the motion events moves within the magnetic field of a target, or indicate a
+     * fling-to-target gesture, this method will return true and you should not move the object
+     * yourself until it returns false again.
+     *
+     * Note that even when this method returns true, you should continue to pass along new motion
+     * events so that we know when the events move back outside the magnetic field area.
+     *
+     * This method will always return false if you haven't set a [magnetListener].
+     */
+    fun maybeConsumeMotionEvent(ev: MotionEvent): Boolean {
+        // Short-circuit if we don't have a listener or any targets, since those are required.
+        if (associatedTargets.size == 0) {
+            return false
+        }
+
+        // When a gesture begins, recalculate target views' positions on the screen in case they
+        // have changed. Also, clear state.
+        if (ev.action == MotionEvent.ACTION_DOWN) {
+            updateTargetViews()
+
+            // Clear the velocity tracker and stuck target.
+            velocityTracker.clear()
+            targetObjectIsStuckTo = null
+
+            // Set the touch down coordinates and reset movedBeyondSlop.
+            touchDown.set(ev.rawX, ev.rawY)
+            movedBeyondSlop = false
+        }
+
+        // Always pass events to the VelocityTracker.
+        addMovement(ev)
+
+        // If we haven't yet moved beyond the slop distance, check if we have.
+        if (!movedBeyondSlop) {
+            val dragDistance = hypot(ev.rawX - touchDown.x, ev.rawY - touchDown.y)
+            if (dragDistance > touchSlop) {
+                // If we're beyond the slop distance, save that and continue.
+                movedBeyondSlop = true
+            } else {
+                // Otherwise, don't do anything yet.
+                return false
+            }
+        }
+
+        val targetObjectIsInMagneticFieldOf = associatedTargets.firstOrNull { target ->
+            val distanceFromTargetCenter = hypot(
+                    ev.rawX - target.centerOnScreen.x,
+                    ev.rawY - target.centerOnScreen.y)
+            distanceFromTargetCenter < target.magneticFieldRadiusPx
+        }
+
+        // If we aren't currently stuck to a target, and we're in the magnetic field of a target,
+        // we're newly stuck.
+        val objectNewlyStuckToTarget =
+                !objectStuckToTarget && targetObjectIsInMagneticFieldOf != null
+
+        // If we are currently stuck to a target, we're in the magnetic field of a target, and that
+        // target isn't the one we're currently stuck to, then touch events have moved into a
+        // adjacent target's magnetic field.
+        val objectMovedIntoDifferentTarget =
+                objectStuckToTarget &&
+                        targetObjectIsInMagneticFieldOf != null &&
+                        targetObjectIsStuckTo != targetObjectIsInMagneticFieldOf
+
+        if (objectNewlyStuckToTarget || objectMovedIntoDifferentTarget) {
+            velocityTracker.computeCurrentVelocity(1000)
+            val velX = velocityTracker.xVelocity
+            val velY = velocityTracker.yVelocity
+
+            // If the object is moving too quickly within the magnetic field, do not stick it. This
+            // only applies to objects newly stuck to a target. If the object is moved into a new
+            // target, it wasn't moving at all (since it was stuck to the previous one).
+            if (objectNewlyStuckToTarget && abs(velX) > stickToTargetMaxXVelocity) {
+                return false
+            }
+
+            // This touch event is newly within the magnetic field - let the listener know, and
+            // animate sticking to the magnet.
+            targetObjectIsStuckTo = targetObjectIsInMagneticFieldOf
+            cancelAnimations()
+            magnetListener.onStuckToTarget(targetObjectIsInMagneticFieldOf!!)
+            animateStuckToTarget(targetObjectIsInMagneticFieldOf, velX, velY, false, null)
+
+            vibrateIfEnabled(VibrationEffect.EFFECT_HEAVY_CLICK)
+        } else if (targetObjectIsInMagneticFieldOf == null && objectStuckToTarget) {
+            velocityTracker.computeCurrentVelocity(1000)
+
+            // This touch event is newly outside the magnetic field - let the listener know. It will
+            // move the object out of the target using its own movement logic.
+            cancelAnimations()
+            magnetListener.onUnstuckFromTarget(
+                    targetObjectIsStuckTo!!, velocityTracker.xVelocity, velocityTracker.yVelocity,
+                    wasFlungOut = false)
+            targetObjectIsStuckTo = null
+
+            vibrateIfEnabled(VibrationEffect.EFFECT_TICK)
+        }
+
+        // First, check for relevant gestures concluding with an ACTION_UP.
+        if (ev.action == MotionEvent.ACTION_UP) {
+
+            velocityTracker.computeCurrentVelocity(1000 /* units */)
+            val velX = velocityTracker.xVelocity
+            val velY = velocityTracker.yVelocity
+
+            // Cancel the magnetic animation since we might still be springing into the magnetic
+            // target, but we're about to fling away or release.
+            cancelAnimations()
+
+            if (objectStuckToTarget) {
+                if (-velY > flingUnstuckFromTargetMinVelocity) {
+                    // If the object is stuck, but it was forcefully flung away from the target in
+                    // the upward direction, tell the listener so the object can be animated out of
+                    // the target.
+                    magnetListener.onUnstuckFromTarget(
+                            targetObjectIsStuckTo!!, velX, velY, wasFlungOut = true)
+                } else {
+                    // If the object is stuck and not flung away, it was released inside the target.
+                    magnetListener.onReleasedInTarget(targetObjectIsStuckTo!!)
+                    vibrateIfEnabled(VibrationEffect.EFFECT_HEAVY_CLICK)
+                }
+
+                // Either way, we're no longer stuck.
+                targetObjectIsStuckTo = null
+                return true
+            }
+
+            // The target we're flinging towards, or null if we're not flinging towards any target.
+            val flungToTarget = associatedTargets.firstOrNull { target ->
+                isForcefulFlingTowardsTarget(target, ev.rawX, ev.rawY, velX, velY)
+            }
+
+            if (flungToTarget != null) {
+                // If this is a fling-to-target, animate the object to the magnet and then release
+                // it.
+                magnetListener.onStuckToTarget(flungToTarget)
+                targetObjectIsStuckTo = flungToTarget
+
+                animateStuckToTarget(flungToTarget, velX, velY, true) {
+                    magnetListener.onReleasedInTarget(flungToTarget)
+                    targetObjectIsStuckTo = null
+                    vibrateIfEnabled(VibrationEffect.EFFECT_HEAVY_CLICK)
+                }
+
+                return true
+            }
+
+            // If it's not either of those things, we are not interested.
+            return false
+        }
+
+        return objectStuckToTarget // Always consume touch events if the object is stuck.
+    }
+
+    /** Plays the given vibration effect if haptics are enabled. */
+    @SuppressLint("MissingPermission")
+    private fun vibrateIfEnabled(effect: Int) {
+        if (hapticsEnabled && systemHapticsEnabled) {
+            vibrator.vibrate(effect.toLong())
+        }
+    }
+
+    /** Adds the movement to the velocity tracker using raw coordinates. */
+    private fun addMovement(event: MotionEvent) {
+        // Add movement to velocity tracker using raw screen X and Y coordinates instead
+        // of window coordinates because the window frame may be moving at the same time.
+        val deltaX = event.rawX - event.x
+        val deltaY = event.rawY - event.y
+        event.offsetLocation(deltaX, deltaY)
+        velocityTracker.addMovement(event)
+        event.offsetLocation(-deltaX, -deltaY)
+    }
+
+    /** Animates sticking the object to the provided target with the given start velocities.  */
+    private fun animateStuckToTargetInternal(
+        target: MagneticTarget,
+        velX: Float,
+        velY: Float,
+        flung: Boolean,
+        after: (() -> Unit)? = null
+    ) {
+        target.updateLocationOnScreen()
+        getLocationOnScreen(underlyingObject, objectLocationOnScreen)
+
+        // Calculate the difference between the target's center coordinates and the object's.
+        // Animating the object's x/y properties by these values will center the object on top
+        // of the magnetic target.
+        val xDiff = target.centerOnScreen.x -
+                getWidth(underlyingObject) / 2f - objectLocationOnScreen[0]
+        val yDiff = target.centerOnScreen.y -
+                getHeight(underlyingObject) / 2f - objectLocationOnScreen[1]
+
+        val springConfig = if (flung) flungIntoTargetSpringConfig else springConfig
+
+        cancelAnimations()
+
+        // Animate to the center of the target.
+        animator
+                .spring(xProperty, xProperty.getValue(underlyingObject) + xDiff, velX,
+                        springConfig)
+                .spring(yProperty, yProperty.getValue(underlyingObject) + yDiff, velY,
+                        springConfig)
+
+        if (physicsAnimatorUpdateListener != null) {
+            animator.addUpdateListener(physicsAnimatorUpdateListener!!)
+        }
+
+        if (physicsAnimatorEndListener != null) {
+            animator.addEndListener(physicsAnimatorEndListener!!)
+        }
+
+        if (after != null) {
+            animator.withEndActions(after)
+        }
+
+        animator.start()
+    }
+
+    /**
+     * Whether or not the provided values match a 'fast fling' towards the provided target. If it
+     * does, we consider it a fling-to-target gesture.
+     */
+    private fun isForcefulFlingTowardsTarget(
+        target: MagneticTarget,
+        rawX: Float,
+        rawY: Float,
+        velX: Float,
+        velY: Float
+    ): Boolean {
+        if (!flingToTargetEnabled) {
+            return false
+        }
+
+        // Whether velocity is sufficient, depending on whether we're flinging into a target at the
+        // top or the bottom of the screen.
+        val velocitySufficient =
+                if (rawY < target.centerOnScreen.y) velY > flingToTargetMinVelocity
+                else velY < flingToTargetMinVelocity
+
+        if (!velocitySufficient) {
+            return false
+        }
+
+        // Whether the trajectory of the fling intersects the target area.
+        var targetCenterXIntercept = rawX
+
+        // Only do math if the X velocity is non-zero, otherwise X won't change.
+        if (velX != 0f) {
+            // Rise over run...
+            val slope = velY / velX
+            // ...y = mx + b, b = y / mx...
+            val yIntercept = rawY - slope * rawX
+
+            // ...calculate the x value when y = the target's y-coordinate.
+            targetCenterXIntercept = (target.centerOnScreen.y - yIntercept) / slope
+        }
+
+        // The width of the area we're looking for a fling towards.
+        val targetAreaWidth = target.targetView.width * flingToTargetWidthPercent
+
+        // Velocity was sufficient, so return true if the intercept is within the target area.
+        return targetCenterXIntercept > target.centerOnScreen.x - targetAreaWidth / 2 &&
+                targetCenterXIntercept < target.centerOnScreen.x + targetAreaWidth / 2
+    }
+
+    /** Cancel animations on this object's x/y properties. */
+    internal fun cancelAnimations() {
+        animator.cancel(xProperty, yProperty)
+    }
+
+    /** Updates the locations on screen of all of the [associatedTargets]. */
+    internal fun updateTargetViews() {
+        associatedTargets.forEach { it.updateLocationOnScreen() }
+
+        // Update the touch slop, since the configuration may have changed.
+        if (associatedTargets.size > 0) {
+            touchSlop =
+                    ViewConfiguration.get(associatedTargets[0].targetView.context).scaledTouchSlop
+        }
+    }
+
+    /**
+     * Represents a target view with a magnetic field radius and cached center-on-screen
+     * coordinates.
+     *
+     * Instances of MagneticTarget are passed to a MagnetizedObject's [addTarget], and can then
+     * attract the object if it's dragged near or flung towards it. MagneticTargets can be added to
+     * multiple objects.
+     */
+    class MagneticTarget(
+        val targetView: View,
+        var magneticFieldRadiusPx: Int
+    ) {
+        val centerOnScreen = PointF()
+
+        private val tempLoc = IntArray(2)
+
+        fun updateLocationOnScreen() {
+            targetView.post {
+                targetView.getLocationOnScreen(tempLoc)
+
+                // Add half of the target size to get the center, and subtract translation since the
+                // target could be animating in while we're doing this calculation.
+                centerOnScreen.set(
+                        tempLoc[0] + targetView.width / 2f - targetView.translationX,
+                        tempLoc[1] + targetView.height / 2f - targetView.translationY)
+            }
+        }
+    }
+
+    companion object {
+
+        /**
+         * Whether the HAPTIC_FEEDBACK_ENABLED setting is true.
+         *
+         * We put it in the companion object because we need to register a settings observer and
+         * [MagnetizedObject] doesn't have an obvious lifecycle so we don't have a good time to
+         * remove that observer. Since this settings is shared among all instances we just let all
+         * instances read from this value.
+         */
+        private var systemHapticsEnabled = false
+        private var hapticSettingObserverInitialized = false
+
+        private fun initHapticSettingObserver(context: Context) {
+            if (hapticSettingObserverInitialized) {
+                return
+            }
+
+            val hapticSettingObserver =
+                    object : ContentObserver(Handler.getMain()) {
+                        override fun onChange(selfChange: Boolean) {
+                            systemHapticsEnabled =
+                                    Settings.System.getIntForUser(
+                                            context.contentResolver,
+                                            Settings.System.HAPTIC_FEEDBACK_ENABLED,
+                                            0,
+                                            UserHandle.USER_CURRENT) != 0
+                        }
+                    }
+
+            context.contentResolver.registerContentObserver(
+                    Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_ENABLED),
+                    true /* notifyForDescendants */, hapticSettingObserver)
+
+            // Trigger the observer once to initialize systemHapticsEnabled.
+            hapticSettingObserver.onChange(false /* selfChange */)
+            hapticSettingObserverInitialized = true
+        }
+
+        /**
+         * Magnetizes the given view. Magnetized views are attracted to one or more magnetic
+         * targets. Magnetic targets attract objects that are dragged near them, and hold them there
+         * unless they're moved away or released. Releasing objects inside a magnetic target
+         * typically performs an action on the object.
+         *
+         * Magnetized views can also be flung to targets, which will result in the view being pulled
+         * into the target and released as if it was dragged into it.
+         *
+         * To use the returned MagnetizedObject<View> instance, first set [magnetListener] to
+         * receive event callbacks. In your touch handler, pass all MotionEvents that move this view
+         * to [maybeConsumeMotionEvent]. If that method returns true, consider the event consumed by
+         * MagnetizedObject and don't move the view unless it begins returning false again.
+         *
+         * The view will be moved via translationX/Y properties, and its
+         * width/height will be determined via getWidth()/getHeight(). If you are animating
+         * something other than a view, or want to position your view using properties other than
+         * translationX/Y, implement an instance of [MagnetizedObject].
+         *
+         * Note that the magnetic library can't re-order your view automatically. If the view
+         * renders on top of the target views, it will obscure the target when it sticks to it.
+         * You'll want to bring the view to the front in [MagnetListener.onStuckToTarget].
+         */
+        @JvmStatic
+        fun <T : View> magnetizeView(view: T): MagnetizedObject<T> {
+            return object : MagnetizedObject<T>(
+                    view.context,
+                    view,
+                    DynamicAnimation.TRANSLATION_X,
+                    DynamicAnimation.TRANSLATION_Y) {
+                override fun getWidth(underlyingObject: T): Float {
+                    return underlyingObject.width.toFloat()
+                }
+
+                override fun getHeight(underlyingObject: T): Float {
+                    return underlyingObject.height.toFloat() }
+
+                override fun getLocationOnScreen(underlyingObject: T, loc: IntArray) {
+                    underlyingObject.getLocationOnScreen(loc)
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
new file mode 100644
index 0000000..993e0e7
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PinnedStackListenerForwarder.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2019 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.wm.shell.pip;
+
+import android.app.RemoteAction;
+import android.content.ComponentName;
+import android.content.pm.ParceledListSlice;
+import android.view.DisplayInfo;
+import android.view.IPinnedStackController;
+import android.view.IPinnedStackListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * PinnedStackListener that simply forwards all calls to each listener added via
+ * {@link #addListener}. This is necessary since calling
+ * {@link com.android.server.wm.WindowManagerService#registerPinnedStackListener} replaces any
+ * previously set listener.
+ */
+public class PinnedStackListenerForwarder extends IPinnedStackListener.Stub {
+    private List<PinnedStackListener> mListeners = new ArrayList<>();
+
+    /** Adds a listener to receive updates from the WindowManagerService. */
+    public void addListener(PinnedStackListener listener) {
+        mListeners.add(listener);
+    }
+
+    /** Removes a listener so it will no longer receive updates from the WindowManagerService. */
+    public void removeListener(PinnedStackListener listener) {
+        mListeners.remove(listener);
+    }
+
+    @Override
+    public void onListenerRegistered(IPinnedStackController controller) {
+        for (PinnedStackListener listener : mListeners) {
+            listener.onListenerRegistered(controller);
+        }
+    }
+
+    @Override
+    public void onMovementBoundsChanged(boolean fromImeAdjustment) {
+        for (PinnedStackListener listener : mListeners) {
+            listener.onMovementBoundsChanged(fromImeAdjustment);
+        }
+    }
+
+    @Override
+    public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+        for (PinnedStackListener listener : mListeners) {
+            listener.onImeVisibilityChanged(imeVisible, imeHeight);
+        }
+    }
+
+    @Override
+    public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
+        for (PinnedStackListener listener : mListeners) {
+            listener.onActionsChanged(actions);
+        }
+    }
+
+    @Override
+    public void onActivityHidden(ComponentName componentName) {
+        for (PinnedStackListener listener : mListeners) {
+            listener.onActivityHidden(componentName);
+        }
+    }
+
+    @Override
+    public void onDisplayInfoChanged(DisplayInfo displayInfo) {
+        for (PinnedStackListener listener : mListeners) {
+            listener.onDisplayInfoChanged(displayInfo);
+        }
+    }
+
+    @Override
+    public void onConfigurationChanged() {
+        for (PinnedStackListener listener : mListeners) {
+            listener.onConfigurationChanged();
+        }
+    }
+
+    @Override
+    public void onAspectRatioChanged(float aspectRatio) {
+        for (PinnedStackListener listener : mListeners) {
+            listener.onAspectRatioChanged(aspectRatio);
+        }
+    }
+
+    /**
+     * A counterpart of {@link IPinnedStackListener} with empty implementations.
+     * Subclasses can ignore those methods they do not intend to take action upon.
+     */
+    public static class PinnedStackListener {
+        public void onListenerRegistered(IPinnedStackController controller) {}
+
+        public void onMovementBoundsChanged(boolean fromImeAdjustment) {}
+
+        public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {}
+
+        public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {}
+
+        public void onActivityHidden(ComponentName componentName) {}
+
+        public void onDisplayInfoChanged(DisplayInfo displayInfo) {}
+
+        public void onConfigurationChanged() {}
+
+        public void onAspectRatioChanged(float aspectRatio) {}
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
new file mode 100644
index 0000000..7c26251
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/Pip.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.media.session.MediaController;
+
+import com.android.wm.shell.pip.phone.PipTouchHandler;
+import com.android.wm.shell.pip.tv.PipController;
+
+import java.io.PrintWriter;
+import java.util.function.Consumer;
+
+/**
+ * Interface to engage picture in picture feature.
+ */
+public interface Pip {
+    /**
+     * Registers {@link com.android.wm.shell.pip.tv.PipController.Listener} that gets called.
+     * whenever receiving notification on changes in PIP.
+     */
+    default void addListener(PipController.Listener listener) {
+    }
+
+    /**
+     * Registers a {@link PipController.MediaListener} to PipController.
+     */
+    default void addMediaListener(PipController.MediaListener listener) {
+    }
+
+    /**
+     * Closes PIP (PIPed activity and PIP system UI).
+     */
+    default void closePip() {
+    }
+
+    /**
+     * Dump the current state and information if need.
+     *
+     * @param pw The stream to dump information to.
+     */
+    default void dump(PrintWriter pw) {
+    }
+
+    /**
+     * Expand PIP, it's possible that specific request to activate the window via Alt-tab.
+     */
+    default void expandPip() {
+    }
+
+    /**
+     * Get current play back state. (e.g: Used in TV)
+     *
+     * @return The state of defined in PipController.
+     */
+    default int getPlaybackState() {
+        return -1;
+    }
+
+    /**
+     * Get the touch handler which manages all the touch handling for PIP on the Phone,
+     * including moving, dismissing and expanding the PIP. (Do not used in TV)
+     *
+     * @return
+     */
+    default @Nullable PipTouchHandler getPipTouchHandler() {
+        return null;
+    }
+
+    /**
+     * Get MediaController.
+     *
+     * @return The MediaController instance.
+     */
+    default MediaController getMediaController() {
+        return null;
+    }
+
+    /**
+     * Hides the PIP menu.
+     */
+    void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback);
+
+    /**
+     * Returns {@code true} if PIP is shown.
+     */
+    default boolean isPipShown() {
+        return false;
+    }
+
+    /**
+     * Moves the PIPed activity to the fullscreen and closes PIP system UI.
+     */
+    default void movePipToFullscreen() {
+    }
+
+    /**
+     * Called whenever an Activity is moved to the pinned stack from another stack.
+     */
+    default void onActivityPinned(String packageName) {
+    }
+
+    /**
+     * Called whenever an Activity is moved from the pinned stack to another stack
+     */
+    default void onActivityUnpinned(ComponentName topActivity) {
+    }
+
+    /**
+     * Called whenever IActivityManager.startActivity is called on an activity that is already
+     * running, but the task is either brought to the front or a new Intent is delivered to it.
+     *
+     * @param task        information about the task the activity was relaunched into
+     * @param clearedTask whether or not the launch activity also cleared the task as a part of
+     *                    starting
+     */
+    default void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+            boolean clearedTask) {
+    }
+
+    /**
+     * Called when display size or font size of settings changed
+     */
+    default void onDensityOrFontScaleChanged() {
+    }
+
+    /**
+     * Called when overlay package change invoked.
+     */
+    default void onOverlayChanged() {
+    }
+
+    /**
+     * Registers the session listener for the current user.
+     */
+    default void registerSessionListenerForCurrentUser() {
+    }
+
+    /**
+     * Called when SysUI state changed.
+     *
+     * @param isSysUiStateValid Is SysUI state valid or not.
+     * @param flag Current SysUI state.
+     */
+    default void onSystemUiStateChanged(boolean isSysUiStateValid, int flag) {
+    }
+
+    /**
+     * Called when task stack changed.
+     */
+    default void onTaskStackChanged() {
+    }
+
+    /**
+     * Removes a {@link PipController.Listener} from PipController.
+     */
+    default void removeListener(PipController.Listener listener) {
+    }
+
+    /**
+     * Removes a {@link PipController.MediaListener} from PipController.
+     */
+    default void removeMediaListener(PipController.MediaListener listener) {
+    }
+
+    /**
+     * Resize the Pip to the appropriate size for the input state.
+     *
+     * @param state In Pip state also used to determine the new size for the Pip.
+     */
+    default void resizePinnedStack(int state) {
+    }
+
+    /**
+     * Resumes resizing operation on the Pip that was previously suspended.
+     *
+     * @param reason The reason resizing operations on the Pip was suspended.
+     */
+    default void resumePipResizing(int reason) {
+    }
+
+    /**
+     * Sets both shelf visibility and its height.
+     *
+     * @param visible visibility of shelf.
+     * @param height  to specify the height for shelf.
+     */
+    default void setShelfHeight(boolean visible, int height) {
+    }
+
+    /**
+     * Registers the pinned stack animation listener.
+     *
+     * @param callback The callback of pinned stack animation.
+     */
+    default void setPinnedStackAnimationListener(Consumer<Boolean> callback) {
+    }
+
+    /**
+     * Set the pinned stack with {@link PipAnimationController.AnimationType}
+     *
+     * @param animationType The pre-defined {@link PipAnimationController.AnimationType}
+     */
+    default void setPinnedStackAnimationType(int animationType) {
+    }
+
+    /**
+     * Called when showing Pip menu.
+     */
+    void showPictureInPictureMenu();
+
+    /**
+     * Suspends resizing operation on the Pip until {@link #resumePipResizing} is called.
+     *
+     * @param reason The reason for suspending resizing operations on the Pip.
+     */
+    default void suspendPipResizing(int reason) {
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
new file mode 100644
index 0000000..d829462
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip;
+
+import android.animation.AnimationHandler;
+import android.animation.Animator;
+import android.animation.RectEvaluator;
+import android.animation.ValueAnimator;
+import android.annotation.IntDef;
+import android.graphics.Rect;
+import android.view.SurfaceControl;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.SfVsyncFrameCallbackProvider;
+import com.android.wm.shell.animation.Interpolators;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Controller class of PiP animations (both from and to PiP mode).
+ */
+public class PipAnimationController {
+    private static final float FRACTION_START = 0f;
+    private static final float FRACTION_END = 1f;
+
+    public static final int ANIM_TYPE_BOUNDS = 0;
+    public static final int ANIM_TYPE_ALPHA = 1;
+
+    @IntDef(prefix = { "ANIM_TYPE_" }, value = {
+            ANIM_TYPE_BOUNDS,
+            ANIM_TYPE_ALPHA
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AnimationType {}
+
+    public static final int TRANSITION_DIRECTION_NONE = 0;
+    public static final int TRANSITION_DIRECTION_SAME = 1;
+    public static final int TRANSITION_DIRECTION_TO_PIP = 2;
+    public static final int TRANSITION_DIRECTION_LEAVE_PIP = 3;
+    public static final int TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN = 4;
+    public static final int TRANSITION_DIRECTION_REMOVE_STACK = 5;
+
+    @IntDef(prefix = { "TRANSITION_DIRECTION_" }, value = {
+            TRANSITION_DIRECTION_NONE,
+            TRANSITION_DIRECTION_SAME,
+            TRANSITION_DIRECTION_TO_PIP,
+            TRANSITION_DIRECTION_LEAVE_PIP,
+            TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN,
+            TRANSITION_DIRECTION_REMOVE_STACK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TransitionDirection {}
+
+    public static boolean isInPipDirection(@TransitionDirection int direction) {
+        return direction == TRANSITION_DIRECTION_TO_PIP;
+    }
+
+    public static boolean isOutPipDirection(@TransitionDirection int direction) {
+        return direction == TRANSITION_DIRECTION_LEAVE_PIP
+                || direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN;
+    }
+
+    private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
+
+    private PipTransitionAnimator mCurrentAnimator;
+
+    private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
+            ThreadLocal.withInitial(() -> {
+                AnimationHandler handler = new AnimationHandler();
+                handler.setProvider(new SfVsyncFrameCallbackProvider());
+                return handler;
+            });
+
+    public PipAnimationController(PipSurfaceTransactionHelper helper) {
+        mSurfaceTransactionHelper = helper;
+    }
+
+    @SuppressWarnings("unchecked")
+    @VisibleForTesting
+    public PipTransitionAnimator getAnimator(SurfaceControl leash,
+            Rect destinationBounds, float alphaStart, float alphaEnd) {
+        if (mCurrentAnimator == null) {
+            mCurrentAnimator = setupPipTransitionAnimator(
+                    PipTransitionAnimator.ofAlpha(leash, destinationBounds, alphaStart, alphaEnd));
+        } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA
+                && mCurrentAnimator.isRunning()) {
+            mCurrentAnimator.updateEndValue(alphaEnd);
+        } else {
+            mCurrentAnimator.cancel();
+            mCurrentAnimator = setupPipTransitionAnimator(
+                    PipTransitionAnimator.ofAlpha(leash, destinationBounds, alphaStart, alphaEnd));
+        }
+        return mCurrentAnimator;
+    }
+
+    @SuppressWarnings("unchecked")
+    @VisibleForTesting
+    public PipTransitionAnimator getAnimator(SurfaceControl leash, Rect startBounds, Rect endBounds,
+            Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction) {
+        if (mCurrentAnimator == null) {
+            mCurrentAnimator = setupPipTransitionAnimator(
+                    PipTransitionAnimator.ofBounds(leash, startBounds, endBounds, sourceHintRect,
+                            direction));
+        } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_ALPHA
+                && mCurrentAnimator.isRunning()) {
+            // If we are still animating the fade into pip, then just move the surface and ensure
+            // we update with the new destination bounds, but don't interrupt the existing animation
+            // with a new bounds
+            mCurrentAnimator.setDestinationBounds(endBounds);
+        } else if (mCurrentAnimator.getAnimationType() == ANIM_TYPE_BOUNDS
+                && mCurrentAnimator.isRunning()) {
+            mCurrentAnimator.setDestinationBounds(endBounds);
+            // construct new Rect instances in case they are recycled
+            mCurrentAnimator.updateEndValue(new Rect(endBounds));
+        } else {
+            mCurrentAnimator.cancel();
+            mCurrentAnimator = setupPipTransitionAnimator(
+                    PipTransitionAnimator.ofBounds(leash, startBounds, endBounds, sourceHintRect,
+                            direction));
+        }
+        return mCurrentAnimator;
+    }
+
+    PipTransitionAnimator getCurrentAnimator() {
+        return mCurrentAnimator;
+    }
+
+    private PipTransitionAnimator setupPipTransitionAnimator(PipTransitionAnimator animator) {
+        animator.setSurfaceTransactionHelper(mSurfaceTransactionHelper);
+        animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+        animator.setFloatValues(FRACTION_START, FRACTION_END);
+        animator.setAnimationHandler(mSfAnimationHandlerThreadLocal.get());
+        return animator;
+    }
+
+    /**
+     * Additional callback interface for PiP animation
+     */
+    public static class PipAnimationCallback {
+        /**
+         * Called when PiP animation is started.
+         */
+        public void onPipAnimationStart(PipTransitionAnimator animator) {}
+
+        /**
+         * Called when PiP animation is ended.
+         */
+        public void onPipAnimationEnd(SurfaceControl.Transaction tx,
+                PipTransitionAnimator animator) {}
+
+        /**
+         * Called when PiP animation is cancelled.
+         */
+        public void onPipAnimationCancel(PipTransitionAnimator animator) {}
+    }
+
+    /**
+     * Animator for PiP transition animation which supports both alpha and bounds animation.
+     * @param <T> Type of property to animate, either alpha (float) or bounds (Rect)
+     */
+    public abstract static class PipTransitionAnimator<T> extends ValueAnimator implements
+            ValueAnimator.AnimatorUpdateListener,
+            ValueAnimator.AnimatorListener {
+        private final SurfaceControl mLeash;
+        private final @AnimationType int mAnimationType;
+        private final Rect mDestinationBounds = new Rect();
+
+        protected T mCurrentValue;
+        protected T mStartValue;
+        private T mEndValue;
+        private PipAnimationCallback mPipAnimationCallback;
+        private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
+                mSurfaceControlTransactionFactory;
+        private PipSurfaceTransactionHelper mSurfaceTransactionHelper;
+        private @TransitionDirection int mTransitionDirection;
+
+        private PipTransitionAnimator(SurfaceControl leash, @AnimationType int animationType,
+                Rect destinationBounds, T startValue, T endValue) {
+            mLeash = leash;
+            mAnimationType = animationType;
+            mDestinationBounds.set(destinationBounds);
+            mStartValue = startValue;
+            mEndValue = endValue;
+            addListener(this);
+            addUpdateListener(this);
+            mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
+            mTransitionDirection = TRANSITION_DIRECTION_NONE;
+        }
+
+        @Override
+        public void onAnimationStart(Animator animation) {
+            mCurrentValue = mStartValue;
+            onStartTransaction(mLeash, newSurfaceControlTransaction());
+            if (mPipAnimationCallback != null) {
+                mPipAnimationCallback.onPipAnimationStart(this);
+            }
+        }
+
+        @Override
+        public void onAnimationUpdate(ValueAnimator animation) {
+            applySurfaceControlTransaction(mLeash, newSurfaceControlTransaction(),
+                    animation.getAnimatedFraction());
+        }
+
+        @Override
+        public void onAnimationEnd(Animator animation) {
+            mCurrentValue = mEndValue;
+            final SurfaceControl.Transaction tx = newSurfaceControlTransaction();
+            onEndTransaction(mLeash, tx, mTransitionDirection);
+            if (mPipAnimationCallback != null) {
+                mPipAnimationCallback.onPipAnimationEnd(tx, this);
+            }
+        }
+
+        @Override
+        public void onAnimationCancel(Animator animation) {
+            if (mPipAnimationCallback != null) {
+                mPipAnimationCallback.onPipAnimationCancel(this);
+            }
+        }
+
+        @Override public void onAnimationRepeat(Animator animation) {}
+
+        @VisibleForTesting
+        @AnimationType public int getAnimationType() {
+            return mAnimationType;
+        }
+
+        @VisibleForTesting
+        public PipTransitionAnimator<T> setPipAnimationCallback(PipAnimationCallback callback) {
+            mPipAnimationCallback = callback;
+            return this;
+        }
+        @VisibleForTesting
+        @TransitionDirection public int getTransitionDirection() {
+            return mTransitionDirection;
+        }
+
+        @VisibleForTesting
+        public PipTransitionAnimator<T> setTransitionDirection(@TransitionDirection int direction) {
+            if (direction != TRANSITION_DIRECTION_SAME) {
+                mTransitionDirection = direction;
+            }
+            return this;
+        }
+
+        T getStartValue() {
+            return mStartValue;
+        }
+
+        @VisibleForTesting
+        public T getEndValue() {
+            return mEndValue;
+        }
+
+        Rect getDestinationBounds() {
+            return mDestinationBounds;
+        }
+
+        void setDestinationBounds(Rect destinationBounds) {
+            mDestinationBounds.set(destinationBounds);
+            if (mAnimationType == ANIM_TYPE_ALPHA) {
+                onStartTransaction(mLeash, newSurfaceControlTransaction());
+            }
+        }
+
+        void setCurrentValue(T value) {
+            mCurrentValue = value;
+        }
+
+        boolean shouldApplyCornerRadius() {
+            return !isOutPipDirection(mTransitionDirection);
+        }
+
+        boolean inScaleTransition() {
+            if (mAnimationType != ANIM_TYPE_BOUNDS) return false;
+            final int direction = getTransitionDirection();
+            return !isInPipDirection(direction) && !isOutPipDirection(direction);
+        }
+
+        /**
+         * Updates the {@link #mEndValue}.
+         *
+         * NOTE: Do not forget to call {@link #setDestinationBounds(Rect)} for bounds animation.
+         * This is typically used when we receive a shelf height adjustment during the bounds
+         * animation. In which case we can update the end bounds and keep the existing animation
+         * running instead of cancelling it.
+         */
+        public void updateEndValue(T endValue) {
+            mEndValue = endValue;
+        }
+
+        SurfaceControl.Transaction newSurfaceControlTransaction() {
+            return mSurfaceControlTransactionFactory.getTransaction();
+        }
+
+        @VisibleForTesting
+        public void setSurfaceControlTransactionFactory(
+                PipSurfaceTransactionHelper.SurfaceControlTransactionFactory factory) {
+            mSurfaceControlTransactionFactory = factory;
+        }
+
+        PipSurfaceTransactionHelper getSurfaceTransactionHelper() {
+            return mSurfaceTransactionHelper;
+        }
+
+        void setSurfaceTransactionHelper(PipSurfaceTransactionHelper helper) {
+            mSurfaceTransactionHelper = helper;
+        }
+
+        void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) {}
+
+        void onEndTransaction(SurfaceControl leash, SurfaceControl.Transaction tx,
+                @TransitionDirection int transitionDirection) {}
+
+        abstract void applySurfaceControlTransaction(SurfaceControl leash,
+                SurfaceControl.Transaction tx, float fraction);
+
+        static PipTransitionAnimator<Float> ofAlpha(SurfaceControl leash,
+                Rect destinationBounds, float startValue, float endValue) {
+            return new PipTransitionAnimator<Float>(leash, ANIM_TYPE_ALPHA,
+                    destinationBounds, startValue, endValue) {
+                @Override
+                void applySurfaceControlTransaction(SurfaceControl leash,
+                        SurfaceControl.Transaction tx, float fraction) {
+                    final float alpha = getStartValue() * (1 - fraction) + getEndValue() * fraction;
+                    setCurrentValue(alpha);
+                    getSurfaceTransactionHelper().alpha(tx, leash, alpha);
+                    tx.apply();
+                }
+
+                @Override
+                void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) {
+                    if (getTransitionDirection() == TRANSITION_DIRECTION_REMOVE_STACK) {
+                        // while removing the pip stack, no extra work needs to be done here.
+                        return;
+                    }
+                    getSurfaceTransactionHelper()
+                            .resetScale(tx, leash, getDestinationBounds())
+                            .crop(tx, leash, getDestinationBounds())
+                            .round(tx, leash, shouldApplyCornerRadius());
+                    tx.show(leash);
+                    tx.apply();
+                }
+
+                @Override
+                public void updateEndValue(Float endValue) {
+                    super.updateEndValue(endValue);
+                    mStartValue = mCurrentValue;
+                }
+            };
+        }
+
+        static PipTransitionAnimator<Rect> ofBounds(SurfaceControl leash,
+                Rect startValue, Rect endValue, Rect sourceHintRect,
+                @PipAnimationController.TransitionDirection int direction) {
+            // Just for simplicity we'll interpolate between the source rect hint insets and empty
+            // insets to calculate the window crop
+            final Rect initialSourceValue;
+            if (isOutPipDirection(direction)) {
+                initialSourceValue = new Rect(endValue);
+            } else {
+                initialSourceValue = new Rect(startValue);
+            }
+
+            final Rect sourceHintRectInsets;
+            if (sourceHintRect == null) {
+                sourceHintRectInsets = null;
+            } else {
+                sourceHintRectInsets = new Rect(sourceHintRect.left - initialSourceValue.left,
+                        sourceHintRect.top - initialSourceValue.top,
+                        initialSourceValue.right - sourceHintRect.right,
+                        initialSourceValue.bottom - sourceHintRect.bottom);
+            }
+            final Rect sourceInsets = new Rect(0, 0, 0, 0);
+
+            // construct new Rect instances in case they are recycled
+            return new PipTransitionAnimator<Rect>(leash, ANIM_TYPE_BOUNDS,
+                    endValue, new Rect(startValue), new Rect(endValue)) {
+                private final RectEvaluator mRectEvaluator = new RectEvaluator(new Rect());
+                private final RectEvaluator mInsetsEvaluator = new RectEvaluator(new Rect());
+
+                @Override
+                void applySurfaceControlTransaction(SurfaceControl leash,
+                        SurfaceControl.Transaction tx, float fraction) {
+                    final Rect start = getStartValue();
+                    final Rect end = getEndValue();
+                    Rect bounds = mRectEvaluator.evaluate(fraction, start, end);
+                    setCurrentValue(bounds);
+                    if (inScaleTransition() || sourceHintRect == null) {
+                        if (isOutPipDirection(direction)) {
+                            getSurfaceTransactionHelper().scale(tx, leash, end, bounds);
+                        } else {
+                            getSurfaceTransactionHelper().scale(tx, leash, start, bounds);
+                        }
+                    } else {
+                        final Rect insets;
+                        if (isOutPipDirection(direction)) {
+                            insets = mInsetsEvaluator.evaluate(fraction, sourceHintRectInsets,
+                                    sourceInsets);
+                        } else {
+                            insets = mInsetsEvaluator.evaluate(fraction, sourceInsets,
+                                    sourceHintRectInsets);
+                        }
+                        getSurfaceTransactionHelper().scaleAndCrop(tx, leash,
+                                initialSourceValue, bounds, insets);
+                    }
+                    tx.apply();
+                }
+
+                @Override
+                void onStartTransaction(SurfaceControl leash, SurfaceControl.Transaction tx) {
+                    getSurfaceTransactionHelper()
+                            .alpha(tx, leash, 1f)
+                            .round(tx, leash, shouldApplyCornerRadius());
+                    tx.show(leash);
+                    tx.apply();
+                }
+
+                @Override
+                void onEndTransaction(SurfaceControl leash, SurfaceControl.Transaction tx,
+                        int transitionDirection) {
+                    // NOTE: intentionally does not apply the transaction here.
+                    // this end transaction should get executed synchronously with the final
+                    // WindowContainerTransaction in task organizer
+                    final Rect destBounds = getDestinationBounds();
+                    getSurfaceTransactionHelper().resetScale(tx, leash, destBounds);
+                    if (transitionDirection == TRANSITION_DIRECTION_LEAVE_PIP) {
+                        // Leaving to fullscreen, reset crop to null.
+                        tx.setPosition(leash, destBounds.left, destBounds.top);
+                        tx.setWindowCrop(leash, 0, 0);
+                    } else {
+                        getSurfaceTransactionHelper().crop(tx, leash, destBounds);
+                    }
+                }
+
+                @Override
+                public void updateEndValue(Rect endValue) {
+                    super.updateEndValue(endValue);
+                    if (mStartValue != null && mCurrentValue != null) {
+                        mStartValue.set(mCurrentValue);
+                    }
+                }
+            };
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
new file mode 100644
index 0000000..de3261b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsHandler.java
@@ -0,0 +1,551 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.util.TypedValue.COMPLEX_UNIT_DIP;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+
+import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.util.Size;
+import android.util.TypedValue;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.Gravity;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.common.DisplayLayout;
+
+import java.io.PrintWriter;
+
+/**
+ * Handles bounds calculation for PIP on Phone and other form factors, it keeps tracking variant
+ * state changes originated from Window Manager and is the source of truth for PiP window bounds.
+ */
+public class PipBoundsHandler {
+
+    private static final String TAG = PipBoundsHandler.class.getSimpleName();
+    private static final float INVALID_SNAP_FRACTION = -1f;
+
+    private final PipSnapAlgorithm mSnapAlgorithm;
+    private final DisplayInfo mDisplayInfo = new DisplayInfo();
+    private DisplayLayout mDisplayLayout;
+
+    private ComponentName mLastPipComponentName;
+    private float mReentrySnapFraction = INVALID_SNAP_FRACTION;
+    private Size mReentrySize;
+
+    private float mDefaultAspectRatio;
+    private float mMinAspectRatio;
+    private float mMaxAspectRatio;
+    private float mAspectRatio;
+    private int mDefaultStackGravity;
+    private int mDefaultMinSize;
+    private Point mScreenEdgeInsets;
+    private int mCurrentMinSize;
+    private Size mOverrideMinimalSize;
+
+    private boolean mIsImeShowing;
+    private int mImeHeight;
+    private boolean mIsShelfShowing;
+    private int mShelfHeight;
+
+    public PipBoundsHandler(Context context) {
+        mSnapAlgorithm = new PipSnapAlgorithm(context);
+        mDisplayLayout = new DisplayLayout();
+        reloadResources(context);
+        // Initialize the aspect ratio to the default aspect ratio.  Don't do this in reload
+        // resources as it would clobber mAspectRatio when entering PiP from fullscreen which
+        // triggers a configuration change and the resources to be reloaded.
+        mAspectRatio = mDefaultAspectRatio;
+    }
+
+    /**
+     * TODO: move the resources to SysUI package.
+     */
+    private void reloadResources(Context context) {
+        final Resources res = context.getResources();
+        mDefaultAspectRatio = res.getFloat(
+                com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio);
+        mDefaultStackGravity = res.getInteger(
+                com.android.internal.R.integer.config_defaultPictureInPictureGravity);
+        mDefaultMinSize = res.getDimensionPixelSize(
+                com.android.internal.R.dimen.default_minimal_size_pip_resizable_task);
+        mCurrentMinSize = mDefaultMinSize;
+        final String screenEdgeInsetsDpString = res.getString(
+                com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets);
+        final Size screenEdgeInsetsDp = !screenEdgeInsetsDpString.isEmpty()
+                ? Size.parseSize(screenEdgeInsetsDpString)
+                : null;
+        mScreenEdgeInsets = screenEdgeInsetsDp == null ? new Point()
+                : new Point(dpToPx(screenEdgeInsetsDp.getWidth(), res.getDisplayMetrics()),
+                        dpToPx(screenEdgeInsetsDp.getHeight(), res.getDisplayMetrics()));
+        mMinAspectRatio = res.getFloat(
+                com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio);
+        mMaxAspectRatio = res.getFloat(
+                com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio);
+    }
+
+    /**
+     * Sets or update latest {@link DisplayLayout} when new display added or rotation callbacks
+     * from {@link DisplayController.OnDisplaysChangedListener}
+     * @param newDisplayLayout latest {@link DisplayLayout}
+     */
+    public void setDisplayLayout(DisplayLayout newDisplayLayout) {
+        mDisplayLayout.set(newDisplayLayout);
+    }
+
+    /**
+     * Update the Min edge size for {@link PipSnapAlgorithm} to calculate corresponding bounds
+     * @param minEdgeSize
+     */
+    public void setMinEdgeSize(int minEdgeSize) {
+        mCurrentMinSize = minEdgeSize;
+    }
+
+    protected float getAspectRatio() {
+        return mAspectRatio;
+    }
+
+    /**
+     * Sets both shelf visibility and its height if applicable.
+     * @return {@code true} if the internal shelf state is changed, {@code false} otherwise.
+     */
+    public boolean setShelfHeight(boolean shelfVisible, int shelfHeight) {
+        final boolean shelfShowing = shelfVisible && shelfHeight > 0;
+        if (shelfShowing == mIsShelfShowing && shelfHeight == mShelfHeight) {
+            return false;
+        }
+
+        mIsShelfShowing = shelfVisible;
+        mShelfHeight = shelfHeight;
+        return true;
+    }
+
+    /**
+     * Responds to IPinnedStackListener on IME visibility change.
+     */
+    public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+        mIsImeShowing = imeVisible;
+        mImeHeight = imeHeight;
+    }
+
+    /**
+     * Responds to IPinnedStackListener on movement bounds change.
+     * Note that both inset and normal bounds will be calculated here rather than in the caller.
+     */
+    public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds,
+            Rect animatingBounds, DisplayInfo displayInfo) {
+        getInsetBounds(insetBounds);
+        final Rect defaultBounds = getDefaultBounds(INVALID_SNAP_FRACTION, null);
+        normalBounds.set(defaultBounds);
+        if (animatingBounds.isEmpty()) {
+            animatingBounds.set(defaultBounds);
+        }
+        if (isValidPictureInPictureAspectRatio(mAspectRatio)) {
+            transformBoundsToAspectRatio(normalBounds, mAspectRatio,
+                    false /* useCurrentMinEdgeSize */, false /* useCurrentSize */);
+        }
+        displayInfo.copyFrom(mDisplayInfo);
+    }
+
+    /**
+     * Responds to IPinnedStackListener on saving reentry snap fraction and size
+     * for a given {@link ComponentName}.
+     */
+    public void onSaveReentryBounds(ComponentName componentName, Rect bounds) {
+        mReentrySnapFraction = getSnapFraction(bounds);
+        mReentrySize = new Size(bounds.width(), bounds.height());
+        mLastPipComponentName = componentName;
+    }
+
+    /**
+     * Responds to IPinnedStackListener on resetting reentry snap fraction and size
+     * for a given {@link ComponentName}.
+     */
+    public void onResetReentryBounds(ComponentName componentName) {
+        if (componentName.equals(mLastPipComponentName)) {
+            onResetReentryBoundsUnchecked();
+        }
+    }
+
+    private void onResetReentryBoundsUnchecked() {
+        mReentrySnapFraction = INVALID_SNAP_FRACTION;
+        mReentrySize = null;
+        mLastPipComponentName = null;
+    }
+
+    /**
+     * Returns ture if there's a valid snap fraction. This is used with {@link EXTRA_IS_FIRST_ENTRY}
+     * to see if this is the first time user has entered PIP for the component.
+     */
+    public boolean hasSaveReentryBounds() {
+        return mReentrySnapFraction != INVALID_SNAP_FRACTION;
+    }
+
+    /**
+     * The {@link PipSnapAlgorithm} is couple on display bounds
+     * @return {@link PipSnapAlgorithm}.
+     */
+    public PipSnapAlgorithm getSnapAlgorithm() {
+        return mSnapAlgorithm;
+    }
+
+    public Rect getDisplayBounds() {
+        return new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
+    }
+
+    public int getDisplayRotation() {
+        return mDisplayInfo.rotation;
+    }
+
+    /**
+     * Responds to IPinnedStackListener on {@link DisplayInfo} change.
+     * It will normally follow up with a
+     * {@link #onMovementBoundsChanged(Rect, Rect, Rect, DisplayInfo)} callback.
+     */
+    public void onDisplayInfoChanged(DisplayInfo displayInfo) {
+        mDisplayInfo.copyFrom(displayInfo);
+    }
+
+    /**
+     * Responds to IPinnedStackListener on configuration change.
+     */
+    public void onConfigurationChanged(Context context) {
+        reloadResources(context);
+    }
+
+    /**
+     * Responds to IPinnedStackListener on resetting aspect ratio for the pinned window.
+     * It will normally follow up with a
+     * {@link #onMovementBoundsChanged(Rect, Rect, Rect, DisplayInfo)} callback.
+     */
+    public void onAspectRatioChanged(float aspectRatio) {
+        mAspectRatio = aspectRatio;
+    }
+
+    /**
+     * See {@link #getDestinationBounds(ComponentName, float, Rect, Size, boolean)}
+     */
+    public Rect getDestinationBounds(ComponentName componentName, float aspectRatio, Rect bounds,
+            Size minimalSize) {
+        return getDestinationBounds(componentName, aspectRatio, bounds, minimalSize,
+                false /* useCurrentMinEdgeSize */);
+    }
+
+    /**
+     * @return {@link Rect} of the destination PiP window bounds.
+     */
+    public Rect getDestinationBounds(ComponentName componentName, float aspectRatio, Rect bounds,
+            Size minimalSize, boolean useCurrentMinEdgeSize) {
+        if (!componentName.equals(mLastPipComponentName)) {
+            onResetReentryBoundsUnchecked();
+            mLastPipComponentName = componentName;
+        }
+        final Rect destinationBounds;
+        if (bounds == null) {
+            final Rect defaultBounds = getDefaultBounds(mReentrySnapFraction, mReentrySize);
+            destinationBounds = new Rect(defaultBounds);
+            if (mReentrySnapFraction == INVALID_SNAP_FRACTION && mReentrySize == null) {
+                mOverrideMinimalSize = minimalSize;
+            }
+        } else {
+            destinationBounds = new Rect(bounds);
+        }
+        if (isValidPictureInPictureAspectRatio(aspectRatio)) {
+            boolean useCurrentSize = bounds == null && mReentrySize != null;
+            transformBoundsToAspectRatio(destinationBounds, aspectRatio, useCurrentMinEdgeSize,
+                    useCurrentSize);
+        }
+        mAspectRatio = aspectRatio;
+        return destinationBounds;
+    }
+
+    public float getDefaultAspectRatio() {
+        return mDefaultAspectRatio;
+    }
+
+    public void onOverlayChanged(Context context, Display display) {
+        mDisplayLayout = new DisplayLayout(context, display);
+    }
+
+    /**
+     * Updatest the display info and display layout on rotation change. This is needed even when we
+     * aren't in PIP because the rotation layout is used to calculate the proper insets for the
+     * next enter animation into PIP.
+     */
+    public void onDisplayRotationChangedNotInPip(Context context, int toRotation) {
+        // Update the display layout, note that we have to do this on every rotation even if we
+        // aren't in PIP since we need to update the display layout to get the right resources
+        mDisplayLayout.rotateTo(context.getResources(), toRotation);
+
+        // Populate the new {@link #mDisplayInfo}.
+        // The {@link DisplayInfo} queried from DisplayManager would be the one before rotation,
+        // therefore, the width/height may require a swap first.
+        // Moving forward, we should get the new dimensions after rotation from DisplayLayout.
+        mDisplayInfo.rotation = toRotation;
+        updateDisplayInfoIfNeeded();
+    }
+
+    /**
+     * Updates the display info, calculating and returning the new stack and movement bounds in the
+     * new orientation of the device if necessary.
+     *
+     * @return {@code true} if internal {@link DisplayInfo} is rotated, {@code false} otherwise.
+     */
+    public boolean onDisplayRotationChanged(Context context, Rect outBounds, Rect oldBounds,
+            Rect outInsetBounds,
+            int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) {
+        // Bail early if the event is not sent to current {@link #mDisplayInfo}
+        if ((displayId != mDisplayInfo.displayId) || (fromRotation == toRotation)) {
+            return false;
+        }
+
+        // Bail early if the pinned task is staled.
+        final RootTaskInfo pinnedTaskInfo;
+        try {
+            pinnedTaskInfo = ActivityTaskManager.getService()
+                    .getRootTaskInfo(WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+            if (pinnedTaskInfo == null) return false;
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to get RootTaskInfo for pinned task", e);
+            return false;
+        }
+
+        // Calculate the snap fraction of the current stack along the old movement bounds
+        final Rect postChangeStackBounds = new Rect(oldBounds);
+        final float snapFraction = getSnapFraction(postChangeStackBounds);
+
+        // Update the display layout
+        mDisplayLayout.rotateTo(context.getResources(), toRotation);
+
+        // Populate the new {@link #mDisplayInfo}.
+        // The {@link DisplayInfo} queried from DisplayManager would be the one before rotation,
+        // therefore, the width/height may require a swap first.
+        // Moving forward, we should get the new dimensions after rotation from DisplayLayout.
+        mDisplayInfo.rotation = toRotation;
+        updateDisplayInfoIfNeeded();
+
+        // Calculate the stack bounds in the new orientation based on same fraction along the
+        // rotated movement bounds.
+        final Rect postChangeMovementBounds = getMovementBounds(postChangeStackBounds,
+                false /* adjustForIme */);
+        mSnapAlgorithm.applySnapFraction(postChangeStackBounds, postChangeMovementBounds,
+                snapFraction);
+
+        getInsetBounds(outInsetBounds);
+        outBounds.set(postChangeStackBounds);
+        t.setBounds(pinnedTaskInfo.token, outBounds);
+        return true;
+    }
+
+    private void updateDisplayInfoIfNeeded() {
+        final boolean updateNeeded;
+        if ((mDisplayInfo.rotation == ROTATION_0) || (mDisplayInfo.rotation == ROTATION_180)) {
+            updateNeeded = (mDisplayInfo.logicalWidth > mDisplayInfo.logicalHeight);
+        } else {
+            updateNeeded = (mDisplayInfo.logicalWidth < mDisplayInfo.logicalHeight);
+        }
+        if (updateNeeded) {
+            final int newLogicalHeight = mDisplayInfo.logicalWidth;
+            mDisplayInfo.logicalWidth = mDisplayInfo.logicalHeight;
+            mDisplayInfo.logicalHeight = newLogicalHeight;
+        }
+    }
+
+    /**
+     * @return whether the given {@param aspectRatio} is valid.
+     */
+    private boolean isValidPictureInPictureAspectRatio(float aspectRatio) {
+        return Float.compare(mMinAspectRatio, aspectRatio) <= 0
+                && Float.compare(aspectRatio, mMaxAspectRatio) <= 0;
+    }
+
+    /**
+     * Sets the current bound with the currently store aspect ratio.
+     * @param stackBounds
+     */
+    public void transformBoundsToAspectRatio(Rect stackBounds) {
+        transformBoundsToAspectRatio(stackBounds, mAspectRatio, true /* useCurrentMinEdgeSize */,
+                true /* useCurrentSize */);
+    }
+
+    /**
+     * Set the current bounds (or the default bounds if there are no current bounds) with the
+     * specified aspect ratio.
+     */
+    private void transformBoundsToAspectRatio(Rect stackBounds, float aspectRatio,
+            boolean useCurrentMinEdgeSize, boolean useCurrentSize) {
+        // Save the snap fraction and adjust the size based on the new aspect ratio.
+        final float snapFraction = mSnapAlgorithm.getSnapFraction(stackBounds,
+                getMovementBounds(stackBounds));
+        final int minEdgeSize = useCurrentMinEdgeSize ? mCurrentMinSize : mDefaultMinSize;
+        final Size size;
+        if (useCurrentMinEdgeSize || useCurrentSize) {
+            size = mSnapAlgorithm.getSizeForAspectRatio(
+                    new Size(stackBounds.width(), stackBounds.height()), aspectRatio, minEdgeSize);
+        } else {
+            size = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, minEdgeSize,
+                    mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
+        }
+
+        final int left = (int) (stackBounds.centerX() - size.getWidth() / 2f);
+        final int top = (int) (stackBounds.centerY() - size.getHeight() / 2f);
+        stackBounds.set(left, top, left + size.getWidth(), top + size.getHeight());
+        // apply the override minimal size if applicable, this minimal size is specified by app
+        if (mOverrideMinimalSize != null) {
+            transformBoundsToMinimalSize(stackBounds, aspectRatio, mOverrideMinimalSize);
+        }
+        mSnapAlgorithm.applySnapFraction(stackBounds, getMovementBounds(stackBounds), snapFraction);
+    }
+
+    /**
+     * Transforms a given bounds to meet the minimal size constraints.
+     * This function assumes the given {@param stackBounds} qualifies {@param aspectRatio}.
+     */
+    private void transformBoundsToMinimalSize(Rect stackBounds, float aspectRatio,
+            Size minimalSize) {
+        if (minimalSize == null) return;
+        final Size adjustedMinimalSize;
+        final float minimalSizeAspectRatio =
+                minimalSize.getWidth() / (float) minimalSize.getHeight();
+        if (minimalSizeAspectRatio > aspectRatio) {
+            // minimal size is wider, fixed the width and increase the height
+            adjustedMinimalSize = new Size(
+                    minimalSize.getWidth(), (int) (minimalSize.getWidth() / aspectRatio));
+        } else {
+            adjustedMinimalSize = new Size(
+                    (int) (minimalSize.getHeight() * aspectRatio), minimalSize.getHeight());
+        }
+        final Rect containerBounds = new Rect(stackBounds);
+        Gravity.apply(mDefaultStackGravity,
+                adjustedMinimalSize.getWidth(), adjustedMinimalSize.getHeight(),
+                containerBounds, stackBounds);
+    }
+
+    /**
+     * @return the default bounds to show the PIP, if a {@param snapFraction} and {@param size} are
+     * provided, then it will apply the default bounds to the provided snap fraction and size.
+     */
+    private Rect getDefaultBounds(float snapFraction, Size size) {
+        final Rect defaultBounds = new Rect();
+        if (snapFraction != INVALID_SNAP_FRACTION && size != null) {
+            defaultBounds.set(0, 0, size.getWidth(), size.getHeight());
+            final Rect movementBounds = getMovementBounds(defaultBounds);
+            mSnapAlgorithm.applySnapFraction(defaultBounds, movementBounds, snapFraction);
+        } else {
+            final Rect insetBounds = new Rect();
+            getInsetBounds(insetBounds);
+            size = mSnapAlgorithm.getSizeForAspectRatio(mDefaultAspectRatio,
+                    mDefaultMinSize, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
+            Gravity.apply(mDefaultStackGravity, size.getWidth(), size.getHeight(), insetBounds,
+                    0, Math.max(mIsImeShowing ? mImeHeight : 0,
+                            mIsShelfShowing ? mShelfHeight : 0),
+                    defaultBounds);
+        }
+        return defaultBounds;
+    }
+
+    /**
+     * Populates the bounds on the screen that the PIP can be visible in.
+     */
+    protected void getInsetBounds(Rect outRect) {
+        Rect insets = mDisplayLayout.stableInsets();
+        outRect.set(insets.left + mScreenEdgeInsets.x,
+                insets.top + mScreenEdgeInsets.y,
+                mDisplayInfo.logicalWidth - insets.right - mScreenEdgeInsets.x,
+                mDisplayInfo.logicalHeight - insets.bottom - mScreenEdgeInsets.y);
+    }
+
+    /**
+     * @return the movement bounds for the given {@param stackBounds} and the current state of the
+     *         controller.
+     */
+    private Rect getMovementBounds(Rect stackBounds) {
+        return getMovementBounds(stackBounds, true /* adjustForIme */);
+    }
+
+    /**
+     * @return the movement bounds for the given {@param stackBounds} and the current state of the
+     *         controller.
+     */
+    private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
+        final Rect movementBounds = new Rect();
+        getInsetBounds(movementBounds);
+
+        // Apply the movement bounds adjustments based on the current state.
+        mSnapAlgorithm.getMovementBounds(stackBounds, movementBounds, movementBounds,
+                (adjustForIme && mIsImeShowing) ? mImeHeight : 0);
+        return movementBounds;
+    }
+
+    /**
+     * @return the default snap fraction to apply instead of the default gravity when calculating
+     *         the default stack bounds when first entering PiP.
+     */
+    public float getSnapFraction(Rect stackBounds) {
+        return mSnapAlgorithm.getSnapFraction(stackBounds, getMovementBounds(stackBounds));
+    }
+
+    /**
+     * Applies the given snap fraction to the given stack bounds.
+     */
+    public void applySnapFraction(Rect stackBounds, float snapFraction) {
+        final Rect movementBounds = getMovementBounds(stackBounds);
+        mSnapAlgorithm.applySnapFraction(stackBounds, movementBounds, snapFraction);
+    }
+
+    /**
+     * @return the pixels for a given dp value.
+     */
+    private int dpToPx(float dpValue, DisplayMetrics dm) {
+        return (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, dpValue, dm);
+    }
+
+    /**
+     * Dumps internal states.
+     */
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mLastPipComponentName=" + mLastPipComponentName);
+        pw.println(innerPrefix + "mReentrySnapFraction=" + mReentrySnapFraction);
+        pw.println(innerPrefix + "mReentrySize=" + mReentrySize);
+        pw.println(innerPrefix + "mDisplayInfo=" + mDisplayInfo);
+        pw.println(innerPrefix + "mDefaultAspectRatio=" + mDefaultAspectRatio);
+        pw.println(innerPrefix + "mMinAspectRatio=" + mMinAspectRatio);
+        pw.println(innerPrefix + "mMaxAspectRatio=" + mMaxAspectRatio);
+        pw.println(innerPrefix + "mAspectRatio=" + mAspectRatio);
+        pw.println(innerPrefix + "mDefaultStackGravity=" + mDefaultStackGravity);
+        pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
+        pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
+        pw.println(innerPrefix + "mIsShelfShowing=" + mIsShelfShowing);
+        pw.println(innerPrefix + "mShelfHeight=" + mShelfHeight);
+        pw.println(innerPrefix + "mSnapAlgorithm" + mSnapAlgorithm);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java
new file mode 100644
index 0000000..820930c
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSnapAlgorithm.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.util.Size;
+
+/**
+ * Calculates the snap targets and the snap position for the PIP given a position and a velocity.
+ * All bounds are relative to the display top/left.
+ */
+public class PipSnapAlgorithm {
+
+    private final float mDefaultSizePercent;
+    private final float mMinAspectRatioForMinSize;
+    private final float mMaxAspectRatioForMinSize;
+
+    public PipSnapAlgorithm(Context context) {
+        Resources res = context.getResources();
+        mDefaultSizePercent = res.getFloat(
+                com.android.internal.R.dimen.config_pictureInPictureDefaultSizePercent);
+        mMaxAspectRatioForMinSize = res.getFloat(
+                com.android.internal.R.dimen.config_pictureInPictureAspectRatioLimitForMinSize);
+        mMinAspectRatioForMinSize = 1f / mMaxAspectRatioForMinSize;
+    }
+
+    /**
+     * @return returns a fraction that describes where along the {@param movementBounds} the
+     *         {@param stackBounds} are. If the {@param stackBounds} are not currently on the
+     *         {@param movementBounds} exactly, then they will be snapped to the movement bounds.
+     *
+     *         The fraction is defined in a clockwise fashion against the {@param movementBounds}:
+     *
+     *            0   1
+     *          4 +---+ 1
+     *            |   |
+     *          3 +---+ 2
+     *            3   2
+     */
+    public float getSnapFraction(Rect stackBounds, Rect movementBounds) {
+        final Rect tmpBounds = new Rect();
+        snapRectToClosestEdge(stackBounds, movementBounds, tmpBounds);
+        final float widthFraction = (float) (tmpBounds.left - movementBounds.left) /
+                movementBounds.width();
+        final float heightFraction = (float) (tmpBounds.top - movementBounds.top) /
+                movementBounds.height();
+        if (tmpBounds.top == movementBounds.top) {
+            return widthFraction;
+        } else if (tmpBounds.left == movementBounds.right) {
+            return 1f + heightFraction;
+        } else if (tmpBounds.top == movementBounds.bottom) {
+            return 2f + (1f - widthFraction);
+        } else {
+            return 3f + (1f - heightFraction);
+        }
+    }
+
+    /**
+     * Moves the {@param stackBounds} along the {@param movementBounds} to the given snap fraction.
+     * See {@link #getSnapFraction(Rect, Rect)}.
+     *
+     * The fraction is define in a clockwise fashion against the {@param movementBounds}:
+     *
+     *    0   1
+     *  4 +---+ 1
+     *    |   |
+     *  3 +---+ 2
+     *    3   2
+     */
+    public void applySnapFraction(Rect stackBounds, Rect movementBounds, float snapFraction) {
+        if (snapFraction < 1f) {
+            int offset = movementBounds.left + (int) (snapFraction * movementBounds.width());
+            stackBounds.offsetTo(offset, movementBounds.top);
+        } else if (snapFraction < 2f) {
+            snapFraction -= 1f;
+            int offset = movementBounds.top + (int) (snapFraction * movementBounds.height());
+            stackBounds.offsetTo(movementBounds.right, offset);
+        } else if (snapFraction < 3f) {
+            snapFraction -= 2f;
+            int offset = movementBounds.left + (int) ((1f - snapFraction) * movementBounds.width());
+            stackBounds.offsetTo(offset, movementBounds.bottom);
+        } else {
+            snapFraction -= 3f;
+            int offset = movementBounds.top + (int) ((1f - snapFraction) * movementBounds.height());
+            stackBounds.offsetTo(movementBounds.left, offset);
+        }
+    }
+
+    /**
+     * Adjusts {@param movementBoundsOut} so that it is the movement bounds for the given
+     * {@param stackBounds}.
+     */
+    public void getMovementBounds(Rect stackBounds, Rect insetBounds, Rect movementBoundsOut,
+            int bottomOffset) {
+        // Adjust the right/bottom to ensure the stack bounds never goes offscreen
+        movementBoundsOut.set(insetBounds);
+        movementBoundsOut.right = Math.max(insetBounds.left, insetBounds.right -
+                stackBounds.width());
+        movementBoundsOut.bottom = Math.max(insetBounds.top, insetBounds.bottom -
+                stackBounds.height());
+        movementBoundsOut.bottom -= bottomOffset;
+    }
+
+    /**
+     * @return the size of the PiP at the given {@param aspectRatio}, ensuring that the minimum edge
+     * is at least {@param minEdgeSize}.
+     */
+    public Size getSizeForAspectRatio(float aspectRatio, float minEdgeSize, int displayWidth,
+            int displayHeight) {
+        final int smallestDisplaySize = Math.min(displayWidth, displayHeight);
+        final int minSize = (int) Math.max(minEdgeSize, smallestDisplaySize * mDefaultSizePercent);
+
+        final int width;
+        final int height;
+        if (aspectRatio <= mMinAspectRatioForMinSize || aspectRatio > mMaxAspectRatioForMinSize) {
+            // Beyond these points, we can just use the min size as the shorter edge
+            if (aspectRatio <= 1) {
+                // Portrait, width is the minimum size
+                width = minSize;
+                height = Math.round(width / aspectRatio);
+            } else {
+                // Landscape, height is the minimum size
+                height = minSize;
+                width = Math.round(height * aspectRatio);
+            }
+        } else {
+            // Within these points, we ensure that the bounds fit within the radius of the limits
+            // at the points
+            final float widthAtMaxAspectRatioForMinSize = mMaxAspectRatioForMinSize * minSize;
+            final float radius = PointF.length(widthAtMaxAspectRatioForMinSize, minSize);
+            height = (int) Math.round(Math.sqrt((radius * radius) /
+                    (aspectRatio * aspectRatio + 1)));
+            width = Math.round(height * aspectRatio);
+        }
+        return new Size(width, height);
+    }
+
+    /**
+     * @return the adjusted size so that it conforms to the given aspectRatio, ensuring that the
+     * minimum edge is at least minEdgeSize.
+     */
+    public Size getSizeForAspectRatio(Size size, float aspectRatio, float minEdgeSize) {
+        final int smallestSize = Math.min(size.getWidth(), size.getHeight());
+        final int minSize = (int) Math.max(minEdgeSize, smallestSize);
+
+        final int width;
+        final int height;
+        if (aspectRatio <= 1) {
+            // Portrait, width is the minimum size.
+            width = minSize;
+            height = Math.round(width / aspectRatio);
+        } else {
+            // Landscape, height is the minimum size
+            height = minSize;
+            width = Math.round(height * aspectRatio);
+        }
+        return new Size(width, height);
+    }
+
+    /**
+     * Snaps the {@param stackBounds} to the closest edge of the {@param movementBounds} and writes
+     * the new bounds out to {@param boundsOut}.
+     */
+    public void snapRectToClosestEdge(Rect stackBounds, Rect movementBounds, Rect boundsOut) {
+        final int boundedLeft = Math.max(movementBounds.left, Math.min(movementBounds.right,
+                stackBounds.left));
+        final int boundedTop = Math.max(movementBounds.top, Math.min(movementBounds.bottom,
+                stackBounds.top));
+        boundsOut.set(stackBounds);
+
+        // Otherwise, just find the closest edge
+        final int fromLeft = Math.abs(stackBounds.left - movementBounds.left);
+        final int fromTop = Math.abs(stackBounds.top - movementBounds.top);
+        final int fromRight = Math.abs(movementBounds.right - stackBounds.left);
+        final int fromBottom = Math.abs(movementBounds.bottom - stackBounds.top);
+        final int shortest = Math.min(Math.min(fromLeft, fromRight), Math.min(fromTop, fromBottom));
+        if (shortest == fromLeft) {
+            boundsOut.offsetTo(movementBounds.left, boundedTop);
+        } else if (shortest == fromTop) {
+            boundsOut.offsetTo(boundedLeft, movementBounds.top);
+        } else if (shortest == fromRight) {
+            boundsOut.offsetTo(movementBounds.right, boundedTop);
+        } else {
+            boundsOut.offsetTo(boundedLeft, movementBounds.bottom);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
new file mode 100644
index 0000000..b9a5536
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipSurfaceTransactionHelper.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.view.SurfaceControl;
+
+import com.android.wm.shell.R;
+
+/**
+ * Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition.
+ */
+public class PipSurfaceTransactionHelper {
+
+    private final boolean mEnableCornerRadius;
+    private int mCornerRadius;
+
+    /** for {@link #scale(SurfaceControl.Transaction, SurfaceControl, Rect, Rect)} operation */
+    private final Matrix mTmpTransform = new Matrix();
+    private final float[] mTmpFloat9 = new float[9];
+    private final RectF mTmpSourceRectF = new RectF();
+    private final RectF mTmpDestinationRectF = new RectF();
+    private final Rect mTmpDestinationRect = new Rect();
+
+    public PipSurfaceTransactionHelper(Context context) {
+        final Resources res = context.getResources();
+        mEnableCornerRadius = res.getBoolean(R.bool.config_pipEnableRoundCorner);
+    }
+
+    /**
+     * Called when display size or font size of settings changed
+     *
+     * @param context the current context
+     */
+    public void onDensityOrFontScaleChanged(Context context) {
+        if (mEnableCornerRadius) {
+            final Resources res = context.getResources();
+            mCornerRadius = res.getDimensionPixelSize(R.dimen.pip_corner_radius);
+        }
+    }
+
+    /**
+     * Operates the alpha on a given transaction and leash
+     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+     */
+    public PipSurfaceTransactionHelper alpha(SurfaceControl.Transaction tx, SurfaceControl leash,
+            float alpha) {
+        tx.setAlpha(leash, alpha);
+        return this;
+    }
+
+    /**
+     * Operates the crop (and position) on a given transaction and leash
+     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+     */
+    public PipSurfaceTransactionHelper crop(SurfaceControl.Transaction tx, SurfaceControl leash,
+            Rect destinationBounds) {
+        tx.setWindowCrop(leash, destinationBounds.width(), destinationBounds.height())
+                .setPosition(leash, destinationBounds.left, destinationBounds.top);
+        return this;
+    }
+
+    /**
+     * Operates the scale (setMatrix) on a given transaction and leash
+     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+     */
+    public PipSurfaceTransactionHelper scale(SurfaceControl.Transaction tx, SurfaceControl leash,
+            Rect sourceBounds, Rect destinationBounds) {
+        mTmpSourceRectF.set(sourceBounds);
+        mTmpDestinationRectF.set(destinationBounds);
+        mTmpTransform.setRectToRect(mTmpSourceRectF, mTmpDestinationRectF, Matrix.ScaleToFit.FILL);
+        tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
+                .setPosition(leash, mTmpDestinationRectF.left, mTmpDestinationRectF.top);
+        return this;
+    }
+
+    /**
+     * Operates the scale (setMatrix) on a given transaction and leash
+     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+     */
+    public PipSurfaceTransactionHelper scaleAndCrop(SurfaceControl.Transaction tx,
+            SurfaceControl leash,
+            Rect sourceBounds, Rect destinationBounds, Rect insets) {
+        mTmpSourceRectF.set(sourceBounds);
+        mTmpDestinationRect.set(sourceBounds);
+        mTmpDestinationRect.inset(insets);
+        // Scale by the shortest edge and offset such that the top/left of the scaled inset source
+        // rect aligns with the top/left of the destination bounds
+        final float scale = sourceBounds.width() <= sourceBounds.height()
+                ? (float) destinationBounds.width() / sourceBounds.width()
+                : (float) destinationBounds.height() / sourceBounds.height();
+        final float left = destinationBounds.left - insets.left * scale;
+        final float top = destinationBounds.top - insets.top * scale;
+        mTmpTransform.setScale(scale, scale);
+        tx.setMatrix(leash, mTmpTransform, mTmpFloat9)
+                .setWindowCrop(leash, mTmpDestinationRect)
+                .setPosition(leash, left, top);
+        return this;
+    }
+
+    /**
+     * Resets the scale (setMatrix) on a given transaction and leash if there's any
+     *
+     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+     */
+    public PipSurfaceTransactionHelper resetScale(SurfaceControl.Transaction tx,
+            SurfaceControl leash,
+            Rect destinationBounds) {
+        tx.setMatrix(leash, Matrix.IDENTITY_MATRIX, mTmpFloat9)
+                .setPosition(leash, destinationBounds.left, destinationBounds.top);
+        return this;
+    }
+
+    /**
+     * Operates the round corner radius on a given transaction and leash
+     * @return same {@link PipSurfaceTransactionHelper} instance for method chaining
+     */
+    public PipSurfaceTransactionHelper round(SurfaceControl.Transaction tx, SurfaceControl leash,
+            boolean applyCornerRadius) {
+        if (mEnableCornerRadius) {
+            tx.setCornerRadius(leash, applyCornerRadius ? mCornerRadius : 0);
+        }
+        return this;
+    }
+
+    public interface SurfaceControlTransactionFactory {
+        SurfaceControl.Transaction getTransaction();
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
new file mode 100644
index 0000000..bb501fb
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -0,0 +1,1108 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
+import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_ALPHA;
+import static com.android.wm.shell.pip.PipAnimationController.ANIM_TYPE_BOUNDS;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_NONE;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_REMOVE_STACK;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_SAME;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
+import static com.android.wm.shell.pip.PipAnimationController.isInPipDirection;
+import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.PictureInPictureParams;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Rational;
+import android.util.Size;
+import android.view.SurfaceControl;
+import android.view.SurfaceControlViewHost;
+import android.view.View;
+import android.view.WindowManager;
+import android.window.TaskOrganizer;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+import android.window.WindowContainerTransactionCallback;
+
+import com.android.internal.os.SomeArgs;
+import com.android.wm.shell.R;
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.pip.phone.PipMenuActivityController;
+import com.android.wm.shell.pip.phone.PipMotionHelper;
+import com.android.wm.shell.pip.phone.PipUpdateThread;
+import com.android.wm.shell.pip.phone.PipUtils;
+import com.android.wm.shell.splitscreen.SplitScreen;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Consumer;
+
+/**
+ * Manages PiP tasks such as resize and offset.
+ *
+ * This class listens on {@link TaskOrganizer} callbacks for windowing mode change
+ * both to and from PiP and issues corresponding animation if applicable.
+ * Normally, we apply series of {@link SurfaceControl.Transaction} when the animator is running
+ * and files a final {@link WindowContainerTransaction} at the end of the transition.
+ *
+ * This class is also responsible for general resize/offset PiP operations within SysUI component,
+ * see also {@link PipMotionHelper}.
+ */
+public class PipTaskOrganizer extends TaskOrganizer implements ShellTaskOrganizer.TaskListener,
+        DisplayController.OnDisplaysChangedListener {
+    private static final String TAG = PipTaskOrganizer.class.getSimpleName();
+    private static final boolean DEBUG = false;
+
+    private static final int MSG_RESIZE_IMMEDIATE = 1;
+    private static final int MSG_RESIZE_ANIMATE = 2;
+    private static final int MSG_OFFSET_ANIMATE = 3;
+    private static final int MSG_FINISH_RESIZE = 4;
+    private static final int MSG_RESIZE_USER = 5;
+
+    // Not a complete set of states but serves what we want right now.
+    private enum State {
+        UNDEFINED(0),
+        TASK_APPEARED(1),
+        ENTERING_PIP(2),
+        EXITING_PIP(3);
+
+        private final int mStateValue;
+
+        State(int value) {
+            mStateValue = value;
+        }
+
+        private boolean isInPip() {
+            return mStateValue >= TASK_APPEARED.mStateValue
+                    && mStateValue != EXITING_PIP.mStateValue;
+        }
+
+        /**
+         * Resize request can be initiated in other component, ignore if we are no longer in PIP,
+         * still waiting for animation or we're exiting from it.
+         *
+         * @return {@code true} if the resize request should be blocked/ignored.
+         */
+        private boolean shouldBlockResizeRequest() {
+            return mStateValue < ENTERING_PIP.mStateValue
+                    || mStateValue == EXITING_PIP.mStateValue;
+        }
+    }
+
+    private final Handler mMainHandler;
+    private final Handler mUpdateHandler;
+    private final PipBoundsHandler mPipBoundsHandler;
+    private final PipAnimationController mPipAnimationController;
+    private final PipUiEventLogger mPipUiEventLoggerLogger;
+    private final List<PipTransitionCallback> mPipTransitionCallbacks = new ArrayList<>();
+    private final Rect mLastReportedBounds = new Rect();
+    private final int mEnterExitAnimationDuration;
+    private final PipSurfaceTransactionHelper mSurfaceTransactionHelper;
+    private final Map<IBinder, Configuration> mInitialState = new HashMap<>();
+    private final Optional<SplitScreen> mSplitScreenOptional;
+    protected final ShellTaskOrganizer mTaskOrganizer;
+    private SurfaceControlViewHost mPipViewHost;
+    private SurfaceControl mPipMenuSurface;
+
+    // These callbacks are called on the update thread
+    private final PipAnimationController.PipAnimationCallback mPipAnimationCallback =
+            new PipAnimationController.PipAnimationCallback() {
+        @Override
+        public void onPipAnimationStart(PipAnimationController.PipTransitionAnimator animator) {
+            sendOnPipTransitionStarted(animator.getTransitionDirection());
+        }
+
+        @Override
+        public void onPipAnimationEnd(SurfaceControl.Transaction tx,
+                PipAnimationController.PipTransitionAnimator animator) {
+            finishResize(tx, animator.getDestinationBounds(), animator.getTransitionDirection(),
+                    animator.getAnimationType());
+            sendOnPipTransitionFinished(animator.getTransitionDirection());
+        }
+
+        @Override
+        public void onPipAnimationCancel(PipAnimationController.PipTransitionAnimator animator) {
+            sendOnPipTransitionCancelled(animator.getTransitionDirection());
+        }
+    };
+
+    @SuppressWarnings("unchecked")
+    private final Handler.Callback mUpdateCallbacks = (msg) -> {
+        SomeArgs args = (SomeArgs) msg.obj;
+        Consumer<Rect> updateBoundsCallback = (Consumer<Rect>) args.arg1;
+        switch (msg.what) {
+            case MSG_RESIZE_IMMEDIATE: {
+                Rect toBounds = (Rect) args.arg2;
+                resizePip(toBounds);
+                if (updateBoundsCallback != null) {
+                    updateBoundsCallback.accept(toBounds);
+                }
+                break;
+            }
+            case MSG_RESIZE_ANIMATE: {
+                Rect currentBounds = (Rect) args.arg2;
+                Rect toBounds = (Rect) args.arg3;
+                Rect sourceHintRect = (Rect) args.arg4;
+                int duration = args.argi2;
+                animateResizePip(currentBounds, toBounds, sourceHintRect,
+                        args.argi1 /* direction */, duration);
+                if (updateBoundsCallback != null) {
+                    updateBoundsCallback.accept(toBounds);
+                }
+                break;
+            }
+            case MSG_OFFSET_ANIMATE: {
+                Rect originalBounds = (Rect) args.arg2;
+                final int offset = args.argi1;
+                final int duration = args.argi2;
+                offsetPip(originalBounds, 0 /* xOffset */, offset, duration);
+                Rect toBounds = new Rect(originalBounds);
+                toBounds.offset(0, offset);
+                if (updateBoundsCallback != null) {
+                    updateBoundsCallback.accept(toBounds);
+                }
+                break;
+            }
+            case MSG_FINISH_RESIZE: {
+                SurfaceControl.Transaction tx = (SurfaceControl.Transaction) args.arg2;
+                Rect toBounds = (Rect) args.arg3;
+                finishResize(tx, toBounds, args.argi1 /* direction */, -1);
+                if (updateBoundsCallback != null) {
+                    updateBoundsCallback.accept(toBounds);
+                }
+                break;
+            }
+            case MSG_RESIZE_USER: {
+                Rect startBounds = (Rect) args.arg2;
+                Rect toBounds = (Rect) args.arg3;
+                userResizePip(startBounds, toBounds);
+                if (updateBoundsCallback != null) {
+                    updateBoundsCallback.accept(toBounds);
+                }
+                break;
+            }
+        }
+        args.recycle();
+        return true;
+    };
+
+    private ActivityManager.RunningTaskInfo mTaskInfo;
+    private WindowContainerToken mToken;
+    private SurfaceControl mLeash;
+    private State mState = State.UNDEFINED;
+    private @PipAnimationController.AnimationType int mOneShotAnimationType = ANIM_TYPE_BOUNDS;
+    private PipSurfaceTransactionHelper.SurfaceControlTransactionFactory
+            mSurfaceControlTransactionFactory;
+    private PictureInPictureParams mPictureInPictureParams;
+
+    /**
+     * If set to {@code true}, the entering animation will be skipped and we will wait for
+     * {@link #onFixedRotationFinished(int)} callback to actually enter PiP.
+     */
+    private boolean mShouldDeferEnteringPip;
+
+    public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler,
+            @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper,
+            Optional<SplitScreen> splitScreenOptional,
+            @NonNull DisplayController displayController,
+            @NonNull PipUiEventLogger pipUiEventLogger,
+            @NonNull ShellTaskOrganizer shellTaskOrganizer) {
+        mMainHandler = new Handler(Looper.getMainLooper());
+        mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks);
+        mPipBoundsHandler = boundsHandler;
+        mEnterExitAnimationDuration = context.getResources()
+                .getInteger(R.integer.config_pipResizeAnimationDuration);
+        mSurfaceTransactionHelper = surfaceTransactionHelper;
+        mPipAnimationController = new PipAnimationController(mSurfaceTransactionHelper);
+        mPipUiEventLoggerLogger = pipUiEventLogger;
+        mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new;
+        mSplitScreenOptional = splitScreenOptional;
+        mTaskOrganizer = shellTaskOrganizer;
+
+        if (!PipUtils.hasSystemFeature(context)) {
+            Log.w(TAG, "Device not support PIP feature");
+        } else {
+            mTaskOrganizer.addListener(this, WINDOWING_MODE_PINNED);
+            displayController.addDisplayWindowListener(this);
+        }
+    }
+
+    public Handler getUpdateHandler() {
+        return mUpdateHandler;
+    }
+
+    public Rect getLastReportedBounds() {
+        return new Rect(mLastReportedBounds);
+    }
+
+    public Rect getCurrentOrAnimatingBounds() {
+        PipAnimationController.PipTransitionAnimator animator =
+                mPipAnimationController.getCurrentAnimator();
+        if (animator != null && animator.isRunning()) {
+            return new Rect(animator.getDestinationBounds());
+        }
+        return getLastReportedBounds();
+    }
+
+    public boolean isInPip() {
+        return mState.isInPip();
+    }
+
+    public boolean isDeferringEnterPipAnimation() {
+        return mState.isInPip() && mShouldDeferEnteringPip;
+    }
+
+    /**
+     * Registers {@link PipTransitionCallback} to receive transition callbacks.
+     */
+    public void registerPipTransitionCallback(PipTransitionCallback callback) {
+        mPipTransitionCallbacks.add(callback);
+    }
+
+    /**
+     * Sets the preferred animation type for one time.
+     * This is typically used to set the animation type to
+     * {@link PipAnimationController#ANIM_TYPE_ALPHA}.
+     */
+    public void setOneShotAnimationType(@PipAnimationController.AnimationType int animationType) {
+        mOneShotAnimationType = animationType;
+    }
+
+    /**
+     * Expands PiP to the previous bounds, this is done in two phases using
+     * {@link WindowContainerTransaction}
+     * - setActivityWindowingMode to either fullscreen or split-secondary at beginning of the
+     *   transaction. without changing the windowing mode of the Task itself. This makes sure the
+     *   activity render it's final configuration while the Task is still in PiP.
+     * - setWindowingMode to undefined at the end of transition
+     * @param animationDurationMs duration in millisecond for the exiting PiP transition
+     */
+    public void exitPip(int animationDurationMs) {
+        if (!mState.isInPip() || mState == State.EXITING_PIP || mToken == null) {
+            Log.wtf(TAG, "Not allowed to exitPip in current state"
+                    + " mState=" + mState + " mToken=" + mToken);
+            return;
+        }
+
+        final Configuration initialConfig = mInitialState.remove(mToken.asBinder());
+        if (initialConfig == null) {
+            Log.wtf(TAG, "Token not in record, this should not happen mToken=" + mToken);
+            return;
+        }
+        mPipUiEventLoggerLogger.log(
+                PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN);
+        final boolean orientationDiffers = initialConfig.windowConfiguration.getRotation()
+                != mPipBoundsHandler.getDisplayRotation();
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        final Rect destinationBounds = initialConfig.windowConfiguration.getBounds();
+        final int direction = syncWithSplitScreenBounds(destinationBounds)
+                ? TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
+                : TRANSITION_DIRECTION_LEAVE_PIP;
+        if (orientationDiffers) {
+            mState = State.EXITING_PIP;
+            // Send started callback though animation is ignored.
+            sendOnPipTransitionStarted(direction);
+            // Don't bother doing an animation if the display rotation differs or if it's in
+            // a non-supported windowing mode
+            applyWindowingModeChangeOnExit(wct, direction);
+            mTaskOrganizer.applyTransaction(wct);
+            // Send finished callback though animation is ignored.
+            sendOnPipTransitionFinished(direction);
+        } else {
+            final SurfaceControl.Transaction tx =
+                    mSurfaceControlTransactionFactory.getTransaction();
+            mSurfaceTransactionHelper.scale(tx, mLeash, destinationBounds,
+                    mLastReportedBounds);
+            tx.setWindowCrop(mLeash, destinationBounds.width(), destinationBounds.height());
+            // We set to fullscreen here for now, but later it will be set to UNDEFINED for
+            // the proper windowing mode to take place. See #applyWindowingModeChangeOnExit.
+            wct.setActivityWindowingMode(mToken,
+                    direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN
+                    ? WINDOWING_MODE_SPLIT_SCREEN_SECONDARY
+                    : WINDOWING_MODE_FULLSCREEN);
+            wct.setBounds(mToken, destinationBounds);
+            wct.setBoundsChangeTransaction(mToken, tx);
+            mTaskOrganizer.applySyncTransaction(wct, new WindowContainerTransactionCallback() {
+                @Override
+                public void onTransactionReady(int id, SurfaceControl.Transaction t) {
+                    t.apply();
+                    scheduleAnimateResizePip(mLastReportedBounds, destinationBounds,
+                            getValidSourceHintRect(mTaskInfo, destinationBounds), direction,
+                            animationDurationMs, null /* updateBoundsCallback */);
+                    mState = State.EXITING_PIP;
+                }
+            });
+        }
+    }
+
+    private void applyWindowingModeChangeOnExit(WindowContainerTransaction wct, int direction) {
+        // Reset the final windowing mode.
+        wct.setWindowingMode(mToken, getOutPipWindowingMode());
+        // Simply reset the activity mode set prior to the animation running.
+        wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+        mSplitScreenOptional.ifPresent(splitScreen -> {
+            if (direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
+                wct.reparent(mToken, splitScreen.getSecondaryRoot(), true /* onTop */);
+            }
+        });
+    }
+
+    /**
+     * Removes PiP immediately.
+     */
+    public void removePip() {
+        if (!mState.isInPip() ||  mToken == null) {
+            Log.wtf(TAG, "Not allowed to removePip in current state"
+                    + " mState=" + mState + " mToken=" + mToken);
+            return;
+        }
+
+        // removePipImmediately is expected when the following animation finishes.
+        mUpdateHandler.post(() -> mPipAnimationController
+                .getAnimator(mLeash, mLastReportedBounds, 1f, 0f)
+                .setTransitionDirection(TRANSITION_DIRECTION_REMOVE_STACK)
+                .setPipAnimationCallback(mPipAnimationCallback)
+                .setDuration(mEnterExitAnimationDuration)
+                .start());
+        mInitialState.remove(mToken.asBinder());
+        mState = State.EXITING_PIP;
+    }
+
+    private void removePipImmediately() {
+        try {
+            // Reset the task bounds first to ensure the activity configuration is reset as well
+            final WindowContainerTransaction wct = new WindowContainerTransaction();
+            wct.setBounds(mToken, null);
+            mTaskOrganizer.applyTransaction(wct);
+
+            ActivityTaskManager.getService().removeStacksInWindowingModes(
+                    new int[]{ WINDOWING_MODE_PINNED });
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to remove PiP", e);
+        }
+    }
+
+    @Override
+    public void onTaskAppeared(ActivityManager.RunningTaskInfo info, SurfaceControl leash) {
+        Objects.requireNonNull(info, "Requires RunningTaskInfo");
+        mTaskInfo = info;
+        mToken = mTaskInfo.token;
+        mState = State.TASK_APPEARED;
+        mLeash = leash;
+        mInitialState.put(mToken.asBinder(), new Configuration(mTaskInfo.configuration));
+        mPictureInPictureParams = mTaskInfo.pictureInPictureParams;
+
+        mPipUiEventLoggerLogger.setTaskInfo(mTaskInfo);
+        mPipUiEventLoggerLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_ENTER);
+
+        if (mShouldDeferEnteringPip) {
+            if (DEBUG) Log.d(TAG, "Defer entering PiP animation, fixed rotation is ongoing");
+            // if deferred, hide the surface till fixed rotation is completed
+            final SurfaceControl.Transaction tx =
+                    mSurfaceControlTransactionFactory.getTransaction();
+            tx.setAlpha(mLeash, 0f);
+            tx.show(mLeash);
+            tx.apply();
+            return;
+        }
+
+        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
+                mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
+                null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
+        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
+        final Rect currentBounds = mTaskInfo.configuration.windowConfiguration.getBounds();
+
+        if (mOneShotAnimationType == ANIM_TYPE_BOUNDS) {
+            final Rect sourceHintRect = getValidSourceHintRect(info, currentBounds);
+            scheduleAnimateResizePip(currentBounds, destinationBounds, sourceHintRect,
+                    TRANSITION_DIRECTION_TO_PIP, mEnterExitAnimationDuration,
+                    null /* updateBoundsCallback */);
+            mState = State.ENTERING_PIP;
+        } else if (mOneShotAnimationType == ANIM_TYPE_ALPHA) {
+            enterPipWithAlphaAnimation(destinationBounds, mEnterExitAnimationDuration);
+            mOneShotAnimationType = ANIM_TYPE_BOUNDS;
+        } else {
+            throw new RuntimeException("Unrecognized animation type: " + mOneShotAnimationType);
+        }
+    }
+
+    /**
+     * Returns the source hint rect if it is valid (if provided and is contained by the current
+     * task bounds).
+     */
+    private Rect getValidSourceHintRect(ActivityManager.RunningTaskInfo info, Rect sourceBounds) {
+        final Rect sourceHintRect = info.pictureInPictureParams != null
+                && info.pictureInPictureParams.hasSourceBoundsHint()
+                ? info.pictureInPictureParams.getSourceRectHint()
+                : null;
+        if (sourceHintRect != null && sourceBounds.contains(sourceHintRect)) {
+            return sourceHintRect;
+        }
+        return null;
+    }
+
+    private void enterPipWithAlphaAnimation(Rect destinationBounds, long durationMs) {
+        // If we are fading the PIP in, then we should move the pip to the final location as
+        // soon as possible, but set the alpha immediately since the transaction can take a
+        // while to process
+        final SurfaceControl.Transaction tx =
+                mSurfaceControlTransactionFactory.getTransaction();
+        tx.setAlpha(mLeash, 0f);
+        tx.apply();
+        final WindowContainerTransaction wct = new WindowContainerTransaction();
+        wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+        wct.setBounds(mToken, destinationBounds);
+        wct.scheduleFinishEnterPip(mToken, destinationBounds);
+        mTaskOrganizer.applySyncTransaction(wct, new WindowContainerTransactionCallback() {
+            @Override
+            public void onTransactionReady(int id, SurfaceControl.Transaction t) {
+                t.apply();
+                mUpdateHandler.post(() -> mPipAnimationController
+                        .getAnimator(mLeash, destinationBounds, 0f, 1f)
+                        .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP)
+                        .setPipAnimationCallback(mPipAnimationCallback)
+                        .setDuration(durationMs)
+                        .start());
+                // mState is set right after the animation is kicked off to block any resize
+                // requests such as offsetPip that may have been called prior to the transition.
+                mState = State.ENTERING_PIP;
+            }
+        });
+    }
+
+    private void sendOnPipTransitionStarted(
+            @PipAnimationController.TransitionDirection int direction) {
+        final Rect pipBounds = new Rect(mLastReportedBounds);
+        runOnMainHandler(() -> {
+            for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
+                final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
+                callback.onPipTransitionStarted(mTaskInfo.baseActivity, direction, pipBounds);
+            }
+        });
+    }
+
+    private void sendOnPipTransitionFinished(
+            @PipAnimationController.TransitionDirection int direction) {
+        runOnMainHandler(() -> {
+            for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
+                final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
+                callback.onPipTransitionFinished(mTaskInfo.baseActivity, direction);
+            }
+        });
+    }
+
+    private void sendOnPipTransitionCancelled(
+            @PipAnimationController.TransitionDirection int direction) {
+        runOnMainHandler(() -> {
+            for (int i = mPipTransitionCallbacks.size() - 1; i >= 0; i--) {
+                final PipTransitionCallback callback = mPipTransitionCallbacks.get(i);
+                callback.onPipTransitionCanceled(mTaskInfo.baseActivity, direction);
+            }
+        });
+    }
+
+    private void runOnMainHandler(Runnable r) {
+        if (Looper.getMainLooper() == Looper.myLooper()) {
+            r.run();
+        } else {
+            mMainHandler.post(r);
+        }
+    }
+
+    /**
+     * Setup the ViewHost and attach the provided menu view to the ViewHost.
+     * @return The input token belonging to the PipMenuView.
+     */
+    public IBinder attachPipMenuViewHost(View menuView, WindowManager.LayoutParams lp) {
+        if (mPipMenuSurface != null) {
+            Log.e(TAG, "PIP Menu View already created and attached.");
+            return null;
+        }
+
+        if (mLeash == null) {
+            Log.e(TAG, "PiP Leash is not yet ready.");
+            return null;
+        }
+
+        if (Looper.getMainLooper() != Looper.myLooper()) {
+            throw new RuntimeException("PipMenuView needs to be attached on the main thread.");
+        }
+        final Context context = menuView.getContext();
+        mPipViewHost = new SurfaceControlViewHost(context, context.getDisplay(),
+                (android.os.Binder) null);
+        mPipMenuSurface = mPipViewHost.getSurfacePackage().getSurfaceControl();
+        SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+        transaction.reparent(mPipMenuSurface, mLeash);
+        transaction.show(mPipMenuSurface);
+        transaction.setRelativeLayer(mPipMenuSurface, mLeash, 1);
+        transaction.apply();
+        mPipViewHost.setView(menuView, lp);
+
+        return mPipViewHost.getSurfacePackage().getInputToken();
+    }
+
+
+    /**
+     * Releases the PIP Menu's View host, remove it from PIP task surface.
+     */
+    public void detachPipMenuViewHost() {
+        if (mPipMenuSurface != null) {
+            SurfaceControl.Transaction transaction = new SurfaceControl.Transaction();
+            transaction.remove(mPipMenuSurface);
+            transaction.apply();
+            mPipMenuSurface = null;
+            mPipViewHost = null;
+        }
+    }
+
+    /**
+     * Return whether the PiP Menu has been attached to the leash yet.
+     */
+    public boolean isPipMenuViewHostAttached() {
+        return mPipViewHost != null;
+    }
+
+
+    /**
+     * Note that dismissing PiP is now originated from SystemUI, see {@link #exitPip(int)}.
+     * Meanwhile this callback is invoked whenever the task is removed. For instance:
+     *   - as a result of removeStacksInWindowingModes from WM
+     *   - activity itself is died
+     * Nevertheless, we simply update the internal state here as all the heavy lifting should
+     * have been done in WM.
+     */
+    @Override
+    public void onTaskVanished(ActivityManager.RunningTaskInfo info) {
+        if (!mState.isInPip()) {
+            return;
+        }
+        final WindowContainerToken token = info.token;
+        Objects.requireNonNull(token, "Requires valid WindowContainerToken");
+        if (token.asBinder() != mToken.asBinder()) {
+            Log.wtf(TAG, "Unrecognized token: " + token);
+            return;
+        }
+        mShouldDeferEnteringPip = false;
+        mPictureInPictureParams = null;
+        mState = State.UNDEFINED;
+        mPipUiEventLoggerLogger.setTaskInfo(null);
+    }
+
+    @Override
+    public void onTaskInfoChanged(ActivityManager.RunningTaskInfo info) {
+        Objects.requireNonNull(mToken, "onTaskInfoChanged requires valid existing mToken");
+        final PictureInPictureParams newParams = info.pictureInPictureParams;
+        if (newParams == null || !applyPictureInPictureParams(newParams)) {
+            Log.d(TAG, "Ignored onTaskInfoChanged with PiP param: " + newParams);
+            return;
+        }
+        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
+                info.topActivity, getAspectRatioOrDefault(newParams),
+                mLastReportedBounds, getMinimalSize(info.topActivityInfo),
+                true /* userCurrentMinEdgeSize */);
+        Objects.requireNonNull(destinationBounds, "Missing destination bounds");
+        scheduleAnimateResizePip(destinationBounds, mEnterExitAnimationDuration,
+                null /* updateBoundsCallback */);
+    }
+
+    @Override
+    public void onFixedRotationStarted(int displayId, int newRotation) {
+        mShouldDeferEnteringPip = true;
+    }
+
+    @Override
+    public void onFixedRotationFinished(int displayId) {
+        if (mShouldDeferEnteringPip && mState.isInPip()) {
+            final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
+                    mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
+                    null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
+            // schedule a regular animation to ensure all the callbacks are still being sent
+            enterPipWithAlphaAnimation(destinationBounds, 0 /* durationMs */);
+        }
+        mShouldDeferEnteringPip = false;
+    }
+
+    /**
+     * Called when display size or font size of settings changed
+     */
+    public void onDensityOrFontScaleChanged(Context context) {
+        mSurfaceTransactionHelper.onDensityOrFontScaleChanged(context);
+    }
+
+    /**
+     * TODO(b/152809058): consolidate the display info handling logic in SysUI
+     *
+     * @param destinationBoundsOut the current destination bounds will be populated to this param
+     */
+    @SuppressWarnings("unchecked")
+    public void onMovementBoundsChanged(Rect destinationBoundsOut, boolean fromRotation,
+            boolean fromImeAdjustment, boolean fromShelfAdjustment,
+            WindowContainerTransaction wct) {
+        final PipAnimationController.PipTransitionAnimator animator =
+                mPipAnimationController.getCurrentAnimator();
+        if (animator == null || !animator.isRunning()
+                || animator.getTransitionDirection() != TRANSITION_DIRECTION_TO_PIP) {
+            if (mState.isInPip() && fromRotation) {
+                // If we are rotating while there is a current animation, immediately cancel the
+                // animation (remove the listeners so we don't trigger the normal finish resize
+                // call that should only happen on the update thread)
+                int direction = TRANSITION_DIRECTION_NONE;
+                if (animator != null) {
+                    direction = animator.getTransitionDirection();
+                    animator.removeAllUpdateListeners();
+                    animator.removeAllListeners();
+                    animator.cancel();
+                    // Do notify the listeners that this was canceled
+                    sendOnPipTransitionCancelled(direction);
+                    sendOnPipTransitionFinished(direction);
+                }
+                mLastReportedBounds.set(destinationBoundsOut);
+
+                // Create a reset surface transaction for the new bounds and update the window
+                // container transaction
+                final SurfaceControl.Transaction tx = createFinishResizeSurfaceTransaction(
+                        destinationBoundsOut);
+                prepareFinishResizeTransaction(destinationBoundsOut, direction, tx, wct);
+            } else  {
+                // There could be an animation on-going. If there is one on-going, last-reported
+                // bounds isn't yet updated. We'll use the animator's bounds instead.
+                if (animator != null && animator.isRunning()) {
+                    if (!animator.getDestinationBounds().isEmpty()) {
+                        destinationBoundsOut.set(animator.getDestinationBounds());
+                    }
+                } else {
+                    if (!mLastReportedBounds.isEmpty()) {
+                        destinationBoundsOut.set(mLastReportedBounds);
+                    }
+                }
+            }
+            return;
+        }
+
+        final Rect currentDestinationBounds = animator.getDestinationBounds();
+        destinationBoundsOut.set(currentDestinationBounds);
+        if (!fromImeAdjustment && !fromShelfAdjustment
+                && mPipBoundsHandler.getDisplayBounds().contains(currentDestinationBounds)) {
+            // no need to update the destination bounds, bail early
+            return;
+        }
+
+        final Rect newDestinationBounds = mPipBoundsHandler.getDestinationBounds(
+                mTaskInfo.topActivity, getAspectRatioOrDefault(mPictureInPictureParams),
+                null /* bounds */, getMinimalSize(mTaskInfo.topActivityInfo));
+        if (newDestinationBounds.equals(currentDestinationBounds)) return;
+        if (animator.getAnimationType() == ANIM_TYPE_BOUNDS) {
+            animator.updateEndValue(newDestinationBounds);
+        }
+        animator.setDestinationBounds(newDestinationBounds);
+        destinationBoundsOut.set(newDestinationBounds);
+    }
+
+    /**
+     * @return {@code true} if the aspect ratio is changed since no other parameters within
+     * {@link PictureInPictureParams} would affect the bounds.
+     */
+    private boolean applyPictureInPictureParams(@NonNull PictureInPictureParams params) {
+        final Rational currentAspectRatio =
+                mPictureInPictureParams != null ? mPictureInPictureParams.getAspectRatioRational()
+                        : null;
+        final boolean aspectRatioChanged = !Objects.equals(currentAspectRatio,
+                params.getAspectRatioRational());
+        mPictureInPictureParams = params;
+        if (aspectRatioChanged) {
+            mPipBoundsHandler.onAspectRatioChanged(params.getAspectRatio());
+        }
+        return aspectRatioChanged;
+    }
+
+    /**
+     * Animates resizing of the pinned stack given the duration.
+     */
+    public void scheduleAnimateResizePip(Rect toBounds, int duration,
+            Consumer<Rect> updateBoundsCallback) {
+        if (mShouldDeferEnteringPip) {
+            Log.d(TAG, "skip scheduleAnimateResizePip, entering pip deferred");
+            return;
+        }
+        scheduleAnimateResizePip(mLastReportedBounds, toBounds, null /* sourceHintRect */,
+                TRANSITION_DIRECTION_NONE, duration, updateBoundsCallback);
+    }
+
+    private void scheduleAnimateResizePip(Rect currentBounds, Rect destinationBounds,
+            Rect sourceHintRect, @PipAnimationController.TransitionDirection int direction,
+            int durationMs, Consumer<Rect> updateBoundsCallback) {
+        if (!mState.isInPip()) {
+            // TODO: tend to use shouldBlockResizeRequest here as well but need to consider
+            // the fact that when in exitPip, scheduleAnimateResizePip is executed in the window
+            // container transaction callback and we want to set the mState immediately.
+            return;
+        }
+
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = updateBoundsCallback;
+        args.arg2 = currentBounds;
+        args.arg3 = destinationBounds;
+        args.arg4 = sourceHintRect;
+        args.argi1 = direction;
+        args.argi2 = durationMs;
+        mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_RESIZE_ANIMATE, args));
+    }
+
+    /**
+     * Directly perform manipulation/resize on the leash. This will not perform any
+     * {@link WindowContainerTransaction} until {@link #scheduleFinishResizePip} is called.
+     */
+    public void scheduleResizePip(Rect toBounds, Consumer<Rect> updateBoundsCallback) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = updateBoundsCallback;
+        args.arg2 = toBounds;
+        mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_RESIZE_IMMEDIATE, args));
+    }
+
+    /**
+     * Directly perform a scaled matrix transformation on the leash. This will not perform any
+     * {@link WindowContainerTransaction} until {@link #scheduleFinishResizePip} is called.
+     */
+    public void scheduleUserResizePip(Rect startBounds, Rect toBounds,
+            Consumer<Rect> updateBoundsCallback) {
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = updateBoundsCallback;
+        args.arg2 = startBounds;
+        args.arg3 = toBounds;
+        mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_RESIZE_USER, args));
+    }
+
+    /**
+     * Finish an intermediate resize operation. This is expected to be called after
+     * {@link #scheduleResizePip}.
+     */
+    public void scheduleFinishResizePip(Rect destinationBounds) {
+        scheduleFinishResizePip(destinationBounds, null /* updateBoundsCallback */);
+    }
+
+    /**
+     * Same as {@link #scheduleFinishResizePip} but with a callback.
+     */
+    public void scheduleFinishResizePip(Rect destinationBounds,
+            Consumer<Rect> updateBoundsCallback) {
+        scheduleFinishResizePip(destinationBounds, TRANSITION_DIRECTION_NONE, updateBoundsCallback);
+    }
+
+    private void scheduleFinishResizePip(Rect destinationBounds,
+            @PipAnimationController.TransitionDirection int direction,
+            Consumer<Rect> updateBoundsCallback) {
+        if (mState.shouldBlockResizeRequest()) {
+            return;
+        }
+
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = updateBoundsCallback;
+        args.arg2 = createFinishResizeSurfaceTransaction(
+                destinationBounds);
+        args.arg3 = destinationBounds;
+        args.argi1 = direction;
+        mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_FINISH_RESIZE, args));
+    }
+
+    private SurfaceControl.Transaction createFinishResizeSurfaceTransaction(
+            Rect destinationBounds) {
+        final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
+        mSurfaceTransactionHelper
+                .crop(tx, mLeash, destinationBounds)
+                .resetScale(tx, mLeash, destinationBounds)
+                .round(tx, mLeash, mState.isInPip());
+        return tx;
+    }
+
+    /**
+     * Offset the PiP window by a given offset on Y-axis, triggered also from screen rotation.
+     */
+    public void scheduleOffsetPip(Rect originalBounds, int offset, int duration,
+            Consumer<Rect> updateBoundsCallback) {
+        if (mState.shouldBlockResizeRequest()) {
+            return;
+        }
+        if (mShouldDeferEnteringPip) {
+            Log.d(TAG, "skip scheduleOffsetPip, entering pip deferred");
+            return;
+        }
+        SomeArgs args = SomeArgs.obtain();
+        args.arg1 = updateBoundsCallback;
+        args.arg2 = originalBounds;
+        // offset would be zero if triggered from screen rotation.
+        args.argi1 = offset;
+        args.argi2 = duration;
+        mUpdateHandler.sendMessage(mUpdateHandler.obtainMessage(MSG_OFFSET_ANIMATE, args));
+    }
+
+    private void offsetPip(Rect originalBounds, int xOffset, int yOffset, int durationMs) {
+        if (Looper.myLooper() != mUpdateHandler.getLooper()) {
+            throw new RuntimeException("Callers should call scheduleOffsetPip() instead of this "
+                    + "directly");
+        }
+        if (mTaskInfo == null) {
+            Log.w(TAG, "mTaskInfo is not set");
+            return;
+        }
+        final Rect destinationBounds = new Rect(originalBounds);
+        destinationBounds.offset(xOffset, yOffset);
+        animateResizePip(originalBounds, destinationBounds, null /* sourceHintRect */,
+                TRANSITION_DIRECTION_SAME, durationMs);
+    }
+
+    private void resizePip(Rect destinationBounds) {
+        if (Looper.myLooper() != mUpdateHandler.getLooper()) {
+            throw new RuntimeException("Callers should call scheduleResizePip() instead of this "
+                    + "directly");
+        }
+        // Could happen when exitPip
+        if (mToken == null || mLeash == null) {
+            Log.w(TAG, "Abort animation, invalid leash");
+            return;
+        }
+        mLastReportedBounds.set(destinationBounds);
+        final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
+        mSurfaceTransactionHelper
+                .crop(tx, mLeash, destinationBounds)
+                .round(tx, mLeash, mState.isInPip());
+        tx.apply();
+    }
+
+    private void userResizePip(Rect startBounds, Rect destinationBounds) {
+        if (Looper.myLooper() != mUpdateHandler.getLooper()) {
+            throw new RuntimeException("Callers should call scheduleUserResizePip() instead of "
+                    + "this directly");
+        }
+        // Could happen when exitPip
+        if (mToken == null || mLeash == null) {
+            Log.w(TAG, "Abort animation, invalid leash");
+            return;
+        }
+
+        if (startBounds.isEmpty() || destinationBounds.isEmpty()) {
+            Log.w(TAG, "Attempted to user resize PIP to or from empty bounds, aborting.");
+            return;
+        }
+
+        final SurfaceControl.Transaction tx = mSurfaceControlTransactionFactory.getTransaction();
+        mSurfaceTransactionHelper.scale(tx, mLeash, startBounds, destinationBounds);
+        tx.apply();
+    }
+
+    private void finishResize(SurfaceControl.Transaction tx, Rect destinationBounds,
+            @PipAnimationController.TransitionDirection int direction,
+            @PipAnimationController.AnimationType int type) {
+        if (Looper.myLooper() != mUpdateHandler.getLooper()) {
+            throw new RuntimeException("Callers should call scheduleResizePip() instead of this "
+                    + "directly");
+        }
+        mLastReportedBounds.set(destinationBounds);
+        if (direction == TRANSITION_DIRECTION_REMOVE_STACK) {
+            removePipImmediately();
+            return;
+        } else if (isInPipDirection(direction) && type == ANIM_TYPE_ALPHA) {
+            return;
+        }
+
+        WindowContainerTransaction wct = new WindowContainerTransaction();
+        prepareFinishResizeTransaction(destinationBounds, direction, tx, wct);
+        applyFinishBoundsResize(wct, direction);
+        runOnMainHandler(() -> {
+            if (mPipViewHost != null) {
+                mPipViewHost.relayout(PipMenuActivityController.getPipMenuLayoutParams(
+                        destinationBounds.width(), destinationBounds.height()));
+            }
+        });
+    }
+
+    private void prepareFinishResizeTransaction(Rect destinationBounds,
+            @PipAnimationController.TransitionDirection int direction,
+            SurfaceControl.Transaction tx,
+            WindowContainerTransaction wct) {
+        final Rect taskBounds;
+        if (isInPipDirection(direction)) {
+            // If we are animating from fullscreen using a bounds animation, then reset the
+            // activity windowing mode set by WM, and set the task bounds to the final bounds
+            taskBounds = destinationBounds;
+            wct.setActivityWindowingMode(mToken, WINDOWING_MODE_UNDEFINED);
+            wct.scheduleFinishEnterPip(mToken, destinationBounds);
+        } else if (isOutPipDirection(direction)) {
+            // If we are animating to fullscreen, then we need to reset the override bounds
+            // on the task to ensure that the task "matches" the parent's bounds.
+            taskBounds = (direction == TRANSITION_DIRECTION_LEAVE_PIP)
+                    ? null : destinationBounds;
+            applyWindowingModeChangeOnExit(wct, direction);
+        } else {
+            // Just a resize in PIP
+            taskBounds = destinationBounds;
+        }
+
+        wct.setBounds(mToken, taskBounds);
+        wct.setBoundsChangeTransaction(mToken, tx);
+    }
+
+    /**
+     * Applies the window container transaction to finish a bounds resize.
+     *
+     * Called by {@link #finishResize(SurfaceControl.Transaction, Rect, int, int)}} once it has
+     * finished preparing the transaction. It allows subclasses to modify the transaction before
+     * applying it.
+     */
+    public void applyFinishBoundsResize(@NonNull WindowContainerTransaction wct,
+            @PipAnimationController.TransitionDirection int direction) {
+        mTaskOrganizer.applyTransaction(wct);
+    }
+
+    /**
+     * The windowing mode to restore to when resizing out of PIP direction. Defaults to undefined
+     * and can be overridden to restore to an alternate windowing mode.
+     */
+    public int getOutPipWindowingMode() {
+        // By default, simply reset the windowing mode to undefined.
+        return WINDOWING_MODE_UNDEFINED;
+    }
+
+
+    private void animateResizePip(Rect currentBounds, Rect destinationBounds, Rect sourceHintRect,
+            @PipAnimationController.TransitionDirection int direction, int durationMs) {
+        if (Looper.myLooper() != mUpdateHandler.getLooper()) {
+            throw new RuntimeException("Callers should call scheduleAnimateResizePip() instead of "
+                    + "this directly");
+        }
+        // Could happen when exitPip
+        if (mToken == null || mLeash == null) {
+            Log.w(TAG, "Abort animation, invalid leash");
+            return;
+        }
+        mPipAnimationController
+                .getAnimator(mLeash, currentBounds, destinationBounds, sourceHintRect, direction)
+                .setTransitionDirection(direction)
+                .setPipAnimationCallback(mPipAnimationCallback)
+                .setDuration(durationMs)
+                .start();
+    }
+
+    private Size getMinimalSize(ActivityInfo activityInfo) {
+        if (activityInfo == null || activityInfo.windowLayout == null) {
+            return null;
+        }
+        final ActivityInfo.WindowLayout windowLayout = activityInfo.windowLayout;
+        // -1 will be populated if an activity specifies defaultWidth/defaultHeight in <layout>
+        // without minWidth/minHeight
+        if (windowLayout.minWidth > 0 && windowLayout.minHeight > 0) {
+            return new Size(windowLayout.minWidth, windowLayout.minHeight);
+        }
+        return null;
+    }
+
+    private float getAspectRatioOrDefault(@Nullable PictureInPictureParams params) {
+        return params == null || !params.hasSetAspectRatio()
+                ? mPipBoundsHandler.getDefaultAspectRatio()
+                : params.getAspectRatio();
+    }
+
+    /**
+     * Sync with {@link SplitScreen} on destination bounds if PiP is going to split screen.
+     *
+     * @param destinationBoundsOut contain the updated destination bounds if applicable
+     * @return {@code true} if destinationBounds is altered for split screen
+     */
+    private boolean syncWithSplitScreenBounds(Rect destinationBoundsOut) {
+        if (!mSplitScreenOptional.isPresent()) {
+            return false;
+        }
+
+        SplitScreen splitScreen = mSplitScreenOptional.get();
+        if (!splitScreen.isDividerVisible()) {
+            // fail early if system is not in split screen mode
+            return false;
+        }
+
+        // PiP window will go to split-secondary mode instead of fullscreen, populates the
+        // split screen bounds here.
+        destinationBoundsOut.set(splitScreen.getDividerView()
+                .getNonMinimizedSplitScreenSecondaryBounds());
+        return true;
+    }
+
+    /**
+     * Dumps internal states.
+     */
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mTaskInfo=" + mTaskInfo);
+        pw.println(innerPrefix + "mToken=" + mToken
+                + " binder=" + (mToken != null ? mToken.asBinder() : null));
+        pw.println(innerPrefix + "mLeash=" + mLeash);
+        pw.println(innerPrefix + "mState=" + mState);
+        pw.println(innerPrefix + "mOneShotAnimationType=" + mOneShotAnimationType);
+        pw.println(innerPrefix + "mPictureInPictureParams=" + mPictureInPictureParams);
+        pw.println(innerPrefix + "mLastReportedBounds=" + mLastReportedBounds);
+        pw.println(innerPrefix + "mInitialState:");
+        for (Map.Entry<IBinder, Configuration> e : mInitialState.entrySet()) {
+            pw.println(innerPrefix + "  binder=" + e.getKey()
+                    + " winConfig=" + e.getValue().windowConfiguration);
+        }
+    }
+
+    /**
+     * Callback interface for PiP transitions (both from and to PiP mode)
+     */
+    public interface PipTransitionCallback {
+        /**
+         * Callback when the pip transition is started.
+         */
+        void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds);
+
+        /**
+         * Callback when the pip transition is finished.
+         */
+        void onPipTransitionFinished(ComponentName activity, int direction);
+
+        /**
+         * Callback when the pip transition is cancelled.
+         */
+        void onPipTransitionCanceled(ComponentName activity, int direction);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java
new file mode 100644
index 0000000..de3bb29
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipUiEventLogger.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip;
+
+import android.app.TaskInfo;
+import android.content.pm.PackageManager;
+
+import com.android.internal.logging.UiEvent;
+import com.android.internal.logging.UiEventLogger;
+
+/**
+ * Helper class that ends PiP log to UiEvent, see also go/uievent
+ */
+public class PipUiEventLogger {
+
+    private static final int INVALID_PACKAGE_UID = -1;
+
+    private final UiEventLogger mUiEventLogger;
+    private final PackageManager mPackageManager;
+
+    private String mPackageName;
+    private int mPackageUid = INVALID_PACKAGE_UID;
+
+    public PipUiEventLogger(UiEventLogger uiEventLogger, PackageManager packageManager) {
+        mUiEventLogger = uiEventLogger;
+        mPackageManager = packageManager;
+    }
+
+    public void setTaskInfo(TaskInfo taskInfo) {
+        if (taskInfo == null) {
+            mPackageName = null;
+            mPackageUid = INVALID_PACKAGE_UID;
+        } else {
+            mPackageName = taskInfo.topActivity.getPackageName();
+            mPackageUid = getUid(mPackageName, taskInfo.userId);
+        }
+    }
+
+    /**
+     * Sends log via UiEvent, reference go/uievent for how to debug locally
+     */
+    public void log(PipUiEventEnum event) {
+        if (mPackageName == null || mPackageUid == INVALID_PACKAGE_UID) {
+            return;
+        }
+        mUiEventLogger.log(event, mPackageUid, mPackageName);
+    }
+
+    private int getUid(String packageName, int userId) {
+        int uid = INVALID_PACKAGE_UID;
+        try {
+            uid = mPackageManager.getApplicationInfoAsUser(
+                    packageName, 0 /* ApplicationInfoFlags */, userId).uid;
+        } catch (PackageManager.NameNotFoundException e) {
+            // do nothing.
+        }
+        return uid;
+    }
+
+    /**
+     * Enums for logging the PiP events to UiEvent
+     */
+    public enum PipUiEventEnum implements UiEventLogger.UiEventEnum {
+        @UiEvent(doc = "Activity enters picture-in-picture mode")
+        PICTURE_IN_PICTURE_ENTER(603),
+
+        @UiEvent(doc = "Expands from picture-in-picture to fullscreen")
+        PICTURE_IN_PICTURE_EXPAND_TO_FULLSCREEN(604),
+
+        @UiEvent(doc = "Removes picture-in-picture by tap close button")
+        PICTURE_IN_PICTURE_TAP_TO_REMOVE(605),
+
+        @UiEvent(doc = "Removes picture-in-picture by drag to dismiss area")
+        PICTURE_IN_PICTURE_DRAG_TO_REMOVE(606),
+
+        @UiEvent(doc = "Shows picture-in-picture menu")
+        PICTURE_IN_PICTURE_SHOW_MENU(607),
+
+        @UiEvent(doc = "Hides picture-in-picture menu")
+        PICTURE_IN_PICTURE_HIDE_MENU(608),
+
+        @UiEvent(doc = "Changes the aspect ratio of picture-in-picture window. This is inherited"
+                + " from previous Tron-based logging and currently not in use.")
+        PICTURE_IN_PICTURE_CHANGE_ASPECT_RATIO(609),
+
+        @UiEvent(doc = "User resize of the picture-in-picture window")
+        PICTURE_IN_PICTURE_RESIZE(610);
+
+        private final int mId;
+
+        PipUiEventEnum(int id) {
+            mId = id;
+        }
+
+        @Override
+        public int getId() {
+            return mId;
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java
new file mode 100644
index 0000000..fddd547
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAccessibilityInteractionConnection.java
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.view.MagnificationSpec;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
+import android.view.accessibility.IAccessibilityInteractionConnection;
+import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.pip.PipSnapAlgorithm;
+import com.android.wm.shell.pip.PipTaskOrganizer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Expose the touch actions to accessibility as if this object were a window with a single view.
+ * That pseudo-view exposes all of the actions this object can perform.
+ */
+public class PipAccessibilityInteractionConnection
+        extends IAccessibilityInteractionConnection.Stub {
+
+    public interface AccessibilityCallbacks {
+        void onAccessibilityShowMenu();
+    }
+
+    private static final long ACCESSIBILITY_NODE_ID = 1;
+    private List<AccessibilityNodeInfo> mAccessibilityNodeInfoList;
+
+    private Context mContext;
+    private Handler mHandler;
+    private PipMotionHelper mMotionHelper;
+    private PipTaskOrganizer mTaskOrganizer;
+    private PipSnapAlgorithm mSnapAlgorithm;
+    private Runnable mUpdateMovementBoundCallback;
+    private AccessibilityCallbacks mCallbacks;
+
+    private final Rect mNormalBounds = new Rect();
+    private final Rect mExpandedBounds = new Rect();
+    private final Rect mNormalMovementBounds = new Rect();
+    private final Rect mExpandedMovementBounds = new Rect();
+    private Rect mTmpBounds = new Rect();
+
+    public PipAccessibilityInteractionConnection(Context context, PipMotionHelper motionHelper,
+            PipTaskOrganizer taskOrganizer, PipSnapAlgorithm snapAlgorithm,
+            AccessibilityCallbacks callbacks, Runnable updateMovementBoundCallback,
+            Handler handler) {
+        mContext = context;
+        mHandler = handler;
+        mMotionHelper = motionHelper;
+        mTaskOrganizer = taskOrganizer;
+        mSnapAlgorithm = snapAlgorithm;
+        mUpdateMovementBoundCallback = updateMovementBoundCallback;
+        mCallbacks = callbacks;
+    }
+
+    @Override
+    public void findAccessibilityNodeInfoByAccessibilityId(long accessibilityNodeId,
+            Region interactiveRegion, int interactionId,
+            IAccessibilityInteractionConnectionCallback callback, int flags,
+            int interrogatingPid, long interrogatingTid, MagnificationSpec spec, Bundle args) {
+        try {
+            callback.setFindAccessibilityNodeInfosResult(
+                    (accessibilityNodeId == AccessibilityNodeInfo.ROOT_NODE_ID)
+                            ? getNodeList() : null, interactionId);
+        } catch (RemoteException re) {
+                /* best effort - ignore */
+        }
+    }
+
+    @Override
+    public void performAccessibilityAction(long accessibilityNodeId, int action,
+            Bundle arguments, int interactionId,
+            IAccessibilityInteractionConnectionCallback callback, int flags,
+            int interrogatingPid, long interrogatingTid) {
+        // We only support one view. A request for anything else is invalid
+        boolean result = false;
+        if (accessibilityNodeId == AccessibilityNodeInfo.ROOT_NODE_ID) {
+
+            // R constants are not final so this cannot be put in the switch-case.
+            if (action == R.id.action_pip_resize) {
+                if (mMotionHelper.getBounds().width() == mNormalBounds.width()
+                        && mMotionHelper.getBounds().height() == mNormalBounds.height()) {
+                    setToExpandedBounds();
+                } else {
+                    setToNormalBounds();
+                }
+                result = true;
+            } else {
+                switch (action) {
+                    case AccessibilityNodeInfo.ACTION_CLICK:
+                        mHandler.post(() -> {
+                            mCallbacks.onAccessibilityShowMenu();
+                        });
+                        result = true;
+                        break;
+                    case AccessibilityNodeInfo.ACTION_DISMISS:
+                        mMotionHelper.dismissPip();
+                        result = true;
+                        break;
+                    case com.android.internal.R.id.accessibilityActionMoveWindow:
+                        int newX = arguments.getInt(
+                                AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_X);
+                        int newY = arguments.getInt(
+                                AccessibilityNodeInfo.ACTION_ARGUMENT_MOVE_WINDOW_Y);
+                        Rect pipBounds = new Rect();
+                        pipBounds.set(mMotionHelper.getBounds());
+                        mTmpBounds.offsetTo(newX, newY);
+                        mMotionHelper.movePip(mTmpBounds);
+                        result = true;
+                        break;
+                    case AccessibilityNodeInfo.ACTION_EXPAND:
+                        mMotionHelper.expandLeavePip();
+                        result = true;
+                        break;
+                    default:
+                        // Leave result as false
+                }
+            }
+        }
+        try {
+            callback.setPerformAccessibilityActionResult(result, interactionId);
+        } catch (RemoteException re) {
+                /* best effort - ignore */
+        }
+    }
+
+    private void setToExpandedBounds() {
+        float savedSnapFraction = mSnapAlgorithm.getSnapFraction(
+                new Rect(mTaskOrganizer.getLastReportedBounds()), mNormalMovementBounds);
+        mSnapAlgorithm.applySnapFraction(mExpandedBounds, mExpandedMovementBounds,
+                savedSnapFraction);
+        mTaskOrganizer.scheduleFinishResizePip(mExpandedBounds, (Rect bounds) -> {
+            mMotionHelper.synchronizePinnedStackBounds();
+            mUpdateMovementBoundCallback.run();
+        });
+    }
+
+    private void setToNormalBounds() {
+        float savedSnapFraction = mSnapAlgorithm.getSnapFraction(
+                new Rect(mTaskOrganizer.getLastReportedBounds()), mExpandedMovementBounds);
+        mSnapAlgorithm.applySnapFraction(mNormalBounds, mNormalMovementBounds, savedSnapFraction);
+        mTaskOrganizer.scheduleFinishResizePip(mNormalBounds, (Rect bounds) -> {
+            mMotionHelper.synchronizePinnedStackBounds();
+            mUpdateMovementBoundCallback.run();
+        });
+    }
+
+    @Override
+    public void findAccessibilityNodeInfosByViewId(long accessibilityNodeId,
+            String viewId, Region interactiveRegion, int interactionId,
+            IAccessibilityInteractionConnectionCallback callback, int flags,
+            int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+        // We have no view with a proper ID
+        try {
+            callback.setFindAccessibilityNodeInfoResult(null, interactionId);
+        } catch (RemoteException re) {
+            /* best effort - ignore */
+        }
+    }
+
+    @Override
+    public void findAccessibilityNodeInfosByText(long accessibilityNodeId, String text,
+            Region interactiveRegion, int interactionId,
+            IAccessibilityInteractionConnectionCallback callback, int flags,
+            int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+        // We have no view with text
+        try {
+            callback.setFindAccessibilityNodeInfoResult(null, interactionId);
+        } catch (RemoteException re) {
+            /* best effort - ignore */
+        }
+    }
+
+    @Override
+    public void findFocus(long accessibilityNodeId, int focusType, Region interactiveRegion,
+            int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+            int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+        // We have no view that can take focus
+        try {
+            callback.setFindAccessibilityNodeInfoResult(null, interactionId);
+        } catch (RemoteException re) {
+            /* best effort - ignore */
+        }
+    }
+
+    @Override
+    public void focusSearch(long accessibilityNodeId, int direction, Region interactiveRegion,
+            int interactionId, IAccessibilityInteractionConnectionCallback callback, int flags,
+            int interrogatingPid, long interrogatingTid, MagnificationSpec spec) {
+        // We have no view that can take focus
+        try {
+            callback.setFindAccessibilityNodeInfoResult(null, interactionId);
+        } catch (RemoteException re) {
+            /* best effort - ignore */
+        }
+    }
+
+    @Override
+    public void clearAccessibilityFocus() {
+        // We should not be here.
+    }
+
+    @Override
+    public void notifyOutsideTouch() {
+        // Do nothing.
+    }
+
+    /**
+     * Update the normal and expanded bounds so they can be used for Resize.
+     */
+    void onMovementBoundsChanged(Rect normalBounds, Rect expandedBounds, Rect normalMovementBounds,
+            Rect expandedMovementBounds) {
+        mNormalBounds.set(normalBounds);
+        mExpandedBounds.set(expandedBounds);
+        mNormalMovementBounds.set(normalMovementBounds);
+        mExpandedMovementBounds.set(expandedMovementBounds);
+    }
+
+    /**
+     * Update the Root node with PIP Accessibility action items.
+     */
+    public static AccessibilityNodeInfo obtainRootAccessibilityNodeInfo(Context context) {
+        AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain();
+        info.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID,
+                AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_MOVE_WINDOW);
+        info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
+        info.addAction(new AccessibilityNodeInfo.AccessibilityAction(R.id.action_pip_resize,
+                context.getString(R.string.accessibility_action_pip_resize)));
+        info.setImportantForAccessibility(true);
+        info.setClickable(true);
+        info.setVisibleToUser(true);
+        return info;
+    }
+
+    private List<AccessibilityNodeInfo> getNodeList() {
+        if (mAccessibilityNodeInfoList == null) {
+            mAccessibilityNodeInfoList = new ArrayList<>(1);
+        }
+        AccessibilityNodeInfo info = obtainRootAccessibilityNodeInfo(mContext);
+        mAccessibilityNodeInfoList.clear();
+        mAccessibilityNodeInfoList.add(info);
+        return mAccessibilityNodeInfoList;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java
new file mode 100644
index 0000000..6b6b521
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipAppOpsListener.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import static android.app.AppOpsManager.MODE_ALLOWED;
+import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
+
+import android.app.AppOpsManager;
+import android.app.AppOpsManager.OnOpChangedListener;
+import android.app.IActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.os.Handler;
+import android.util.Pair;
+
+public class PipAppOpsListener {
+    private static final String TAG = PipAppOpsListener.class.getSimpleName();
+
+    private Context mContext;
+    private Handler mHandler;
+    private IActivityManager mActivityManager;
+    private AppOpsManager mAppOpsManager;
+    private Callback mCallback;
+
+    private AppOpsManager.OnOpChangedListener mAppOpsChangedListener = new OnOpChangedListener() {
+        @Override
+        public void onOpChanged(String op, String packageName) {
+            try {
+                // Dismiss the PiP once the user disables the app ops setting for that package
+                final Pair<ComponentName, Integer> topPipActivityInfo =
+                        PipUtils.getTopPipActivity(mContext, mActivityManager);
+                if (topPipActivityInfo.first != null) {
+                    final ApplicationInfo appInfo = mContext.getPackageManager()
+                            .getApplicationInfoAsUser(packageName, 0, topPipActivityInfo.second);
+                    if (appInfo.packageName.equals(topPipActivityInfo.first.getPackageName()) &&
+                            mAppOpsManager.checkOpNoThrow(OP_PICTURE_IN_PICTURE, appInfo.uid,
+                                    packageName) != MODE_ALLOWED) {
+                        mHandler.post(() -> mCallback.dismissPip());
+                    }
+                }
+            } catch (NameNotFoundException e) {
+                // Unregister the listener if the package can't be found
+                unregisterAppOpsListener();
+            }
+        }
+    };
+
+    public PipAppOpsListener(Context context, IActivityManager activityManager,
+            Callback callback) {
+        mContext = context;
+        mHandler = new Handler(mContext.getMainLooper());
+        mActivityManager = activityManager;
+        mAppOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+        mCallback = callback;
+    }
+
+    public void onActivityPinned(String packageName) {
+        // Register for changes to the app ops setting for this package while it is in PiP
+        registerAppOpsListener(packageName);
+    }
+
+    public void onActivityUnpinned() {
+        // Unregister for changes to the previously PiP'ed package
+        unregisterAppOpsListener();
+    }
+
+    private void registerAppOpsListener(String packageName) {
+        mAppOpsManager.startWatchingMode(OP_PICTURE_IN_PICTURE, packageName,
+                mAppOpsChangedListener);
+    }
+
+    private void unregisterAppOpsListener() {
+        mAppOpsManager.stopWatchingMode(mAppOpsChangedListener);
+    }
+
+    /** Callback for PipAppOpsListener to request changes to the PIP window. */
+    public interface Callback {
+        /** Dismisses the PIP window. */
+        void dismissPip();
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
new file mode 100644
index 0000000..5193656
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
+import static com.android.wm.shell.pip.PipAnimationController.isOutPipDirection;
+
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.app.RemoteAction;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.graphics.Rect;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.Log;
+import android.view.DisplayInfo;
+import android.view.IPinnedStackController;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.common.DisplayChangeController;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.pip.PinnedStackListenerForwarder;
+import com.android.wm.shell.pip.Pip;
+import com.android.wm.shell.pip.PipBoundsHandler;
+import com.android.wm.shell.pip.PipTaskOrganizer;
+
+import java.io.PrintWriter;
+import java.util.function.Consumer;
+
+/**
+ * Manages the picture-in-picture (PIP) UI and states for Phones.
+ */
+public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallback {
+    private static final String TAG = "PipController";
+
+    private Context mContext;
+    private Handler mHandler = new Handler();
+
+    private final DisplayInfo mTmpDisplayInfo = new DisplayInfo();
+    private final Rect mTmpInsetBounds = new Rect();
+    private final Rect mTmpNormalBounds = new Rect();
+    protected final Rect mReentryBounds = new Rect();
+
+    private DisplayController mDisplayController;
+    private PipAppOpsListener mAppOpsListener;
+    private PipBoundsHandler mPipBoundsHandler;
+    private PipMediaController mMediaController;
+    private PipTouchHandler mTouchHandler;
+    private Consumer<Boolean> mPinnedStackAnimationRecentsCallback;
+    private WindowManagerShellWrapper mWindowManagerShellWrapper;
+
+    private boolean mIsInFixedRotation;
+
+    protected PipMenuActivityController mMenuController;
+    protected PipTaskOrganizer mPipTaskOrganizer;
+
+    /**
+     * Handler for display rotation changes.
+     */
+    private final DisplayChangeController.OnDisplayChangingListener mRotationController = (
+            int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) -> {
+        if (!mPipTaskOrganizer.isInPip() || mPipTaskOrganizer.isDeferringEnterPipAnimation()) {
+            // Skip if we aren't in PIP or haven't actually entered PIP yet. We still need to update
+            // the display layout in the bounds handler in this case.
+            mPipBoundsHandler.onDisplayRotationChangedNotInPip(mContext, toRotation);
+            return;
+        }
+        // If there is an animation running (ie. from a shelf offset), then ensure that we calculate
+        // the bounds for the next orientation using the destination bounds of the animation
+        // TODO: Techincally this should account for movement animation bounds as well
+        Rect currentBounds = mPipTaskOrganizer.getCurrentOrAnimatingBounds();
+        final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mContext,
+                mTmpNormalBounds, currentBounds, mTmpInsetBounds, displayId, fromRotation,
+                toRotation, t);
+        if (changed) {
+            // If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the
+            // movement bounds
+            mTouchHandler.adjustBoundsForRotation(mTmpNormalBounds,
+                    mPipTaskOrganizer.getLastReportedBounds(), mTmpInsetBounds);
+
+            // The bounds are being applied to a specific snap fraction, so reset any known offsets
+            // for the previous orientation before updating the movement bounds.
+            // We perform the resets if and only if this callback is due to screen rotation but
+            // not during the fixed rotation. In fixed rotation case, app is about to enter PiP
+            // and we need the offsets preserved to calculate the destination bounds.
+            if (!mIsInFixedRotation) {
+                mPipBoundsHandler.setShelfHeight(false, 0);
+                mPipBoundsHandler.onImeVisibilityChanged(false, 0);
+                mTouchHandler.onShelfVisibilityChanged(false, 0);
+                mTouchHandler.onImeVisibilityChanged(false, 0);
+            }
+
+            updateMovementBounds(mTmpNormalBounds, true /* fromRotation */,
+                    false /* fromImeAdjustment */, false /* fromShelfAdjustment */, t);
+        }
+    };
+
+    private DisplayController.OnDisplaysChangedListener mFixedRotationListener =
+            new DisplayController.OnDisplaysChangedListener() {
+                @Override
+                public void onFixedRotationStarted(int displayId, int newRotation) {
+                    mIsInFixedRotation = true;
+                }
+
+                @Override
+                public void onFixedRotationFinished(int displayId) {
+                    mIsInFixedRotation = false;
+                }
+
+                @Override
+                public void onDisplayAdded(int displayId) {
+                    mPipBoundsHandler.setDisplayLayout(
+                            mDisplayController.getDisplayLayout(displayId));
+                }
+            };
+
+    /**
+     * Handler for messages from the PIP controller.
+     */
+    private class PipControllerPinnedStackListener extends
+            PinnedStackListenerForwarder.PinnedStackListener {
+        @Override
+        public void onListenerRegistered(IPinnedStackController controller) {
+            mHandler.post(() -> mTouchHandler.setPinnedStackController(controller));
+        }
+
+        @Override
+        public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+            mHandler.post(() -> {
+                mPipBoundsHandler.onImeVisibilityChanged(imeVisible, imeHeight);
+                mTouchHandler.onImeVisibilityChanged(imeVisible, imeHeight);
+            });
+        }
+
+        @Override
+        public void onMovementBoundsChanged(boolean fromImeAdjustment) {
+            mHandler.post(() -> updateMovementBounds(null /* toBounds */,
+                    false /* fromRotation */, fromImeAdjustment, false /* fromShelfAdjustment */,
+                    null /* windowContainerTransaction */));
+        }
+
+        @Override
+        public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
+            mHandler.post(() -> mMenuController.setAppActions(actions));
+        }
+
+        @Override
+        public void onActivityHidden(ComponentName componentName) {
+            mHandler.post(() -> mPipBoundsHandler.onResetReentryBounds(componentName));
+        }
+
+        @Override
+        public void onDisplayInfoChanged(DisplayInfo displayInfo) {
+            mHandler.post(() -> mPipBoundsHandler.onDisplayInfoChanged(displayInfo));
+        }
+
+        @Override
+        public void onConfigurationChanged() {
+            mHandler.post(() -> {
+                mPipBoundsHandler.onConfigurationChanged(mContext);
+                mTouchHandler.onConfigurationChanged();
+            });
+        }
+
+        @Override
+        public void onAspectRatioChanged(float aspectRatio) {
+            mHandler.post(() -> {
+                mPipBoundsHandler.onAspectRatioChanged(aspectRatio);
+                mTouchHandler.onAspectRatioChanged();
+            });
+        }
+    }
+
+    public PipController(Context context,
+            DisplayController displayController,
+            PipAppOpsListener pipAppOpsListener,
+            PipBoundsHandler pipBoundsHandler,
+            PipMediaController pipMediaController,
+            PipMenuActivityController pipMenuActivityController,
+            PipTaskOrganizer pipTaskOrganizer,
+            PipTouchHandler pipTouchHandler,
+            WindowManagerShellWrapper windowManagerShellWrapper
+    ) {
+        mContext = context;
+
+        if (PipUtils.hasSystemFeature(mContext)) {
+            initController(context, displayController, pipAppOpsListener, pipBoundsHandler,
+                    pipMediaController, pipMenuActivityController, pipTaskOrganizer,
+                    pipTouchHandler, windowManagerShellWrapper);
+        } else {
+            Log.w(TAG, "Device not support PIP feature");
+        }
+    }
+
+    private void initController(Context context,
+            DisplayController displayController,
+            PipAppOpsListener pipAppOpsListener,
+            PipBoundsHandler pipBoundsHandler,
+            PipMediaController pipMediaController,
+            PipMenuActivityController pipMenuActivityController,
+            PipTaskOrganizer pipTaskOrganizer,
+            PipTouchHandler pipTouchHandler,
+            WindowManagerShellWrapper windowManagerShellWrapper) {
+
+        // Ensure that we are the primary user's SystemUI.
+        final int processUser = UserManager.get(context).getUserHandle();
+        if (processUser != UserHandle.USER_SYSTEM) {
+            throw new IllegalStateException("Non-primary Pip component not currently supported.");
+        }
+
+        mWindowManagerShellWrapper = windowManagerShellWrapper;
+        mDisplayController = displayController;
+        mPipBoundsHandler = pipBoundsHandler;
+        mPipTaskOrganizer = pipTaskOrganizer;
+        mPipTaskOrganizer.registerPipTransitionCallback(this);
+        mMediaController = pipMediaController;
+        mMenuController = pipMenuActivityController;
+        mTouchHandler = pipTouchHandler;
+        mAppOpsListener = pipAppOpsListener;
+        displayController.addDisplayChangingController(mRotationController);
+        displayController.addDisplayWindowListener(mFixedRotationListener);
+
+        // Ensure that we have the display info in case we get calls to update the bounds before the
+        // listener calls back
+        final DisplayInfo displayInfo = new DisplayInfo();
+        context.getDisplay().getDisplayInfo(displayInfo);
+        mPipBoundsHandler.onDisplayInfoChanged(displayInfo);
+
+        try {
+            mWindowManagerShellWrapper.addPinnedStackListener(
+                    new PipControllerPinnedStackListener());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to register pinned stack listener", e);
+        }
+    }
+
+    @Override
+    public void onDensityOrFontScaleChanged() {
+        mHandler.post(() -> {
+            mPipTaskOrganizer.onDensityOrFontScaleChanged(mContext);
+        });
+    }
+
+    @Override
+    public void onActivityPinned(String packageName) {
+        mHandler.post(() -> {
+            mTouchHandler.onActivityPinned();
+            mMediaController.onActivityPinned();
+            mMenuController.onActivityPinned();
+            mAppOpsListener.onActivityPinned(packageName);
+        });
+    }
+
+    @Override
+    public void onActivityUnpinned(ComponentName topActivity) {
+        mHandler.post(() -> {
+            mMenuController.onActivityUnpinned();
+            mTouchHandler.onActivityUnpinned(topActivity);
+            mAppOpsListener.onActivityUnpinned();
+        });
+    }
+
+    @Override
+    public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+            boolean clearedTask) {
+        if (task.configuration.windowConfiguration.getWindowingMode()
+                != WINDOWING_MODE_PINNED) {
+            return;
+        }
+        mTouchHandler.getMotionHelper().expandLeavePip(clearedTask /* skipAnimation */);
+    }
+
+    @Override
+    public void onOverlayChanged() {
+        mHandler.post(() -> {
+            mPipBoundsHandler.onOverlayChanged(mContext, mContext.getDisplay());
+            updateMovementBounds(null /* toBounds */,
+                    false /* fromRotation */, false /* fromImeAdjustment */,
+                    false /* fromShelfAdjustment */,
+                    null /* windowContainerTransaction */);
+        });
+    }
+
+    @Override
+    public void registerSessionListenerForCurrentUser() {
+        mMediaController.registerSessionListenerForCurrentUser();
+    }
+
+    @Override
+    public void onSystemUiStateChanged(boolean isValidState, int flag) {
+        mTouchHandler.onSystemUiStateChanged(isValidState);
+    }
+
+    /**
+     * Expands the PIP.
+     */
+    @Override
+    public void expandPip() {
+        mTouchHandler.getMotionHelper().expandLeavePip(false /* skipAnimation */);
+    }
+
+    @Override
+    public PipTouchHandler getPipTouchHandler() {
+        return mTouchHandler;
+    }
+
+    /**
+     * Hides the PIP menu.
+     */
+    @Override
+    public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {
+        mMenuController.hideMenu(onStartCallback, onEndCallback);
+    }
+
+    /**
+     * Sent from KEYCODE_WINDOW handler in PhoneWindowManager, to request the menu to be shown.
+     */
+    public void showPictureInPictureMenu() {
+        mTouchHandler.showPictureInPictureMenu();
+    }
+
+    /**
+     * Sets a customized touch gesture that replaces the default one.
+     */
+    public void setTouchGesture(PipTouchGesture gesture) {
+        mTouchHandler.setTouchGesture(gesture);
+    }
+
+    /**
+     * Sets both shelf visibility and its height.
+     */
+    @Override
+    public void setShelfHeight(boolean visible, int height) {
+        mHandler.post(() -> {
+            final int shelfHeight = visible ? height : 0;
+            final boolean changed = mPipBoundsHandler.setShelfHeight(visible, shelfHeight);
+            if (changed) {
+                mTouchHandler.onShelfVisibilityChanged(visible, shelfHeight);
+                updateMovementBounds(mPipTaskOrganizer.getLastReportedBounds(),
+                        false /* fromRotation */, false /* fromImeAdjustment */,
+                        true /* fromShelfAdjustment */, null /* windowContainerTransaction */);
+            }
+        });
+    }
+
+    @Override
+    public void setPinnedStackAnimationType(int animationType) {
+        mHandler.post(() -> mPipTaskOrganizer.setOneShotAnimationType(animationType));
+    }
+
+    @Override
+    public void setPinnedStackAnimationListener(Consumer<Boolean> callback) {
+        mHandler.post(() -> mPinnedStackAnimationRecentsCallback = callback);
+    }
+
+    @Override
+    public void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds) {
+        if (isOutPipDirection(direction)) {
+            // Exiting PIP, save the reentry bounds to restore to when re-entering.
+            updateReentryBounds(pipBounds);
+            mPipBoundsHandler.onSaveReentryBounds(activity, mReentryBounds);
+        }
+        // Disable touches while the animation is running
+        mTouchHandler.setTouchEnabled(false);
+        if (mPinnedStackAnimationRecentsCallback != null) {
+            mPinnedStackAnimationRecentsCallback.accept(true);
+        }
+    }
+
+    /**
+     * Update the bounds used to save the re-entry size and snap fraction when exiting PIP.
+     */
+    public void updateReentryBounds(Rect bounds) {
+        final Rect reentryBounds = mTouchHandler.getUserResizeBounds();
+        float snapFraction = mPipBoundsHandler.getSnapFraction(bounds);
+        mPipBoundsHandler.applySnapFraction(reentryBounds, snapFraction);
+        mReentryBounds.set(reentryBounds);
+    }
+
+    @Override
+    public void onPipTransitionFinished(ComponentName activity, int direction) {
+        onPipTransitionFinishedOrCanceled(direction);
+    }
+
+    @Override
+    public void onPipTransitionCanceled(ComponentName activity, int direction) {
+        onPipTransitionFinishedOrCanceled(direction);
+    }
+
+    private void onPipTransitionFinishedOrCanceled(int direction) {
+        // Re-enable touches after the animation completes
+        mTouchHandler.setTouchEnabled(true);
+        mTouchHandler.onPinnedStackAnimationEnded(direction);
+        mMenuController.onPinnedStackAnimationEnded();
+    }
+
+    private void updateMovementBounds(@Nullable Rect toBounds, boolean fromRotation,
+            boolean fromImeAdjustment, boolean fromShelfAdjustment,
+            WindowContainerTransaction wct) {
+        // Populate inset / normal bounds and DisplayInfo from mPipBoundsHandler before
+        // passing to mTouchHandler/mPipTaskOrganizer
+        final Rect outBounds = new Rect(toBounds);
+        mPipBoundsHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds,
+                outBounds, mTmpDisplayInfo);
+        // mTouchHandler would rely on the bounds populated from mPipTaskOrganizer
+        mPipTaskOrganizer.onMovementBoundsChanged(outBounds, fromRotation, fromImeAdjustment,
+                fromShelfAdjustment, wct);
+        mTouchHandler.onMovementBoundsChanged(mTmpInsetBounds, mTmpNormalBounds,
+                outBounds, fromImeAdjustment, fromShelfAdjustment,
+                mTmpDisplayInfo.rotation);
+    }
+
+    @Override
+    public void dump(PrintWriter pw) {
+        final String innerPrefix = "  ";
+        pw.println(TAG);
+        mMenuController.dump(pw, innerPrefix);
+        mTouchHandler.dump(pw, innerPrefix);
+        mPipBoundsHandler.dump(pw, innerPrefix);
+        mPipTaskOrganizer.dump(pw, innerPrefix);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java
new file mode 100644
index 0000000..4a8db6b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMediaController.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
+
+import android.app.IActivityManager;
+import android.app.PendingIntent;
+import android.app.RemoteAction;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.drawable.Icon;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
+import android.os.UserHandle;
+
+import com.android.wm.shell.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Interfaces with the {@link MediaSessionManager} to compose the right set of actions to show (only
+ * if there are no actions from the PiP activity itself). The active media controller is only set
+ * when there is a media session from the top PiP activity.
+ */
+public class PipMediaController {
+
+    private static final String ACTION_PLAY = "com.android.wm.shell.pip.phone.PLAY";
+    private static final String ACTION_PAUSE = "com.android.wm.shell.pip.phone.PAUSE";
+    private static final String ACTION_NEXT = "com.android.wm.shell.pip.phone.NEXT";
+    private static final String ACTION_PREV = "com.android.wm.shell.pip.phone.PREV";
+
+    /**
+     * A listener interface to receive notification on changes to the media actions.
+     */
+    public interface ActionListener {
+        /**
+         * Called when the media actions changes.
+         */
+        void onMediaActionsChanged(List<RemoteAction> actions);
+    }
+
+    private final Context mContext;
+    private final IActivityManager mActivityManager;
+
+    private final MediaSessionManager mMediaSessionManager;
+    private MediaController mMediaController;
+
+    private RemoteAction mPauseAction;
+    private RemoteAction mPlayAction;
+    private RemoteAction mNextAction;
+    private RemoteAction mPrevAction;
+
+    private BroadcastReceiver mPlayPauseActionReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (action.equals(ACTION_PLAY)) {
+                mMediaController.getTransportControls().play();
+            } else if (action.equals(ACTION_PAUSE)) {
+                mMediaController.getTransportControls().pause();
+            } else if (action.equals(ACTION_NEXT)) {
+                mMediaController.getTransportControls().skipToNext();
+            } else if (action.equals(ACTION_PREV)) {
+                mMediaController.getTransportControls().skipToPrevious();
+            }
+        }
+    };
+
+    private final MediaController.Callback mPlaybackChangedListener =
+            new MediaController.Callback() {
+                @Override
+                public void onPlaybackStateChanged(PlaybackState state) {
+                    notifyActionsChanged();
+                }
+            };
+
+    private final MediaSessionManager.OnActiveSessionsChangedListener mSessionsChangedListener =
+            controllers -> resolveActiveMediaController(controllers);
+
+    private ArrayList<ActionListener> mListeners = new ArrayList<>();
+
+    public PipMediaController(Context context, IActivityManager activityManager) {
+        mContext = context;
+        mActivityManager = activityManager;
+        IntentFilter mediaControlFilter = new IntentFilter();
+        mediaControlFilter.addAction(ACTION_PLAY);
+        mediaControlFilter.addAction(ACTION_PAUSE);
+        mediaControlFilter.addAction(ACTION_NEXT);
+        mediaControlFilter.addAction(ACTION_PREV);
+        mContext.registerReceiver(mPlayPauseActionReceiver, mediaControlFilter,
+                UserHandle.USER_ALL);
+
+        createMediaActions();
+        mMediaSessionManager =
+                (MediaSessionManager) context.getSystemService(Context.MEDIA_SESSION_SERVICE);
+    }
+
+    /**
+     * Handles when an activity is pinned.
+     */
+    public void onActivityPinned() {
+        // Once we enter PiP, try to find the active media controller for the top most activity
+        resolveActiveMediaController(mMediaSessionManager.getActiveSessionsForUser(null,
+                UserHandle.USER_CURRENT));
+    }
+
+    /**
+     * Adds a new media action listener.
+     */
+    public void addListener(ActionListener listener) {
+        if (!mListeners.contains(listener)) {
+            mListeners.add(listener);
+            listener.onMediaActionsChanged(getMediaActions());
+        }
+    }
+
+    /**
+     * Removes a media action listener.
+     */
+    public void removeListener(ActionListener listener) {
+        listener.onMediaActionsChanged(Collections.EMPTY_LIST);
+        mListeners.remove(listener);
+    }
+
+    /**
+     * Gets the set of media actions currently available.
+     */
+    private List<RemoteAction> getMediaActions() {
+        if (mMediaController == null || mMediaController.getPlaybackState() == null) {
+            return Collections.EMPTY_LIST;
+        }
+
+        ArrayList<RemoteAction> mediaActions = new ArrayList<>();
+        int state = mMediaController.getPlaybackState().getState();
+        boolean isPlaying = MediaSession.isActiveState(state);
+        long actions = mMediaController.getPlaybackState().getActions();
+
+        // Prev action
+        mPrevAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0);
+        mediaActions.add(mPrevAction);
+
+        // Play/pause action
+        if (!isPlaying && ((actions & PlaybackState.ACTION_PLAY) != 0)) {
+            mediaActions.add(mPlayAction);
+        } else if (isPlaying && ((actions & PlaybackState.ACTION_PAUSE) != 0)) {
+            mediaActions.add(mPauseAction);
+        }
+
+        // Next action
+        mNextAction.setEnabled((actions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0);
+        mediaActions.add(mNextAction);
+        return mediaActions;
+    }
+
+    /**
+     * Creates the standard media buttons that we may show.
+     */
+    private void createMediaActions() {
+        String pauseDescription = mContext.getString(R.string.pip_pause);
+        mPauseAction = new RemoteAction(Icon.createWithResource(mContext,
+                R.drawable.pip_ic_pause_white), pauseDescription, pauseDescription,
+                PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PAUSE),
+                        FLAG_UPDATE_CURRENT));
+
+        String playDescription = mContext.getString(R.string.pip_play);
+        mPlayAction = new RemoteAction(Icon.createWithResource(mContext,
+                R.drawable.pip_ic_play_arrow_white), playDescription, playDescription,
+                PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PLAY),
+                        FLAG_UPDATE_CURRENT));
+
+        String nextDescription = mContext.getString(R.string.pip_skip_to_next);
+        mNextAction = new RemoteAction(Icon.createWithResource(mContext,
+                R.drawable.pip_ic_skip_next_white), nextDescription, nextDescription,
+                PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_NEXT),
+                        FLAG_UPDATE_CURRENT));
+
+        String prevDescription = mContext.getString(R.string.pip_skip_to_prev);
+        mPrevAction = new RemoteAction(Icon.createWithResource(mContext,
+                R.drawable.pip_ic_skip_previous_white), prevDescription, prevDescription,
+                PendingIntent.getBroadcast(mContext, 0, new Intent(ACTION_PREV),
+                        FLAG_UPDATE_CURRENT));
+    }
+
+    /**
+     * Re-registers the session listener for the current user.
+     */
+    public void registerSessionListenerForCurrentUser() {
+        mMediaSessionManager.removeOnActiveSessionsChangedListener(mSessionsChangedListener);
+        mMediaSessionManager.addOnActiveSessionsChangedListener(mSessionsChangedListener, null,
+                UserHandle.USER_CURRENT, null);
+    }
+
+    /**
+     * Tries to find and set the active media controller for the top PiP activity.
+     */
+    private void resolveActiveMediaController(List<MediaController> controllers) {
+        if (controllers != null) {
+            final ComponentName topActivity = PipUtils.getTopPipActivity(mContext,
+                    mActivityManager).first;
+            if (topActivity != null) {
+                for (int i = 0; i < controllers.size(); i++) {
+                    final MediaController controller = controllers.get(i);
+                    if (controller.getPackageName().equals(topActivity.getPackageName())) {
+                        setActiveMediaController(controller);
+                        return;
+                    }
+                }
+            }
+        }
+        setActiveMediaController(null);
+    }
+
+    /**
+     * Sets the active media controller for the top PiP activity.
+     */
+    private void setActiveMediaController(MediaController controller) {
+        if (controller != mMediaController) {
+            if (mMediaController != null) {
+                mMediaController.unregisterCallback(mPlaybackChangedListener);
+            }
+            mMediaController = controller;
+            if (controller != null) {
+                controller.registerCallback(mPlaybackChangedListener);
+            }
+            notifyActionsChanged();
+
+            // TODO(winsonc): Consider if we want to close the PIP after a timeout (like on TV)
+        }
+    }
+
+    /**
+     * Notifies all listeners that the actions have changed.
+     */
+    private void notifyActionsChanged() {
+        if (!mListeners.isEmpty()) {
+            List<RemoteAction> actions = getMediaActions();
+            mListeners.forEach(l -> l.onMediaActionsChanged(actions));
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java
new file mode 100644
index 0000000..c53803a7
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuActivityController.java
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
+import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
+import android.app.RemoteAction;
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.os.Debug;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+import android.view.WindowManagerGlobal;
+
+import com.android.wm.shell.pip.PipTaskOrganizer;
+import com.android.wm.shell.pip.phone.PipMediaController.ActionListener;
+
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Manages the PiP menu activity which can show menu options or a scrim.
+ *
+ * The current media session provides actions whenever there are no valid actions provided by the
+ * current PiP activity. Otherwise, those actions always take precedence.
+ */
+public class PipMenuActivityController {
+
+    private static final String TAG = "PipMenuActController";
+    private static final boolean DEBUG = false;
+
+    public static final int MENU_STATE_NONE = 0;
+    public static final int MENU_STATE_CLOSE = 1;
+    public static final int MENU_STATE_FULL = 2;
+
+    /**
+     * A listener interface to receive notification on changes in PIP.
+     */
+    public interface Listener {
+        /**
+         * Called when the PIP menu visibility changes.
+         *
+         * @param menuState the current state of the menu
+         * @param resize whether or not to resize the PiP with the state change
+         */
+        void onPipMenuStateChanged(int menuState, boolean resize, Runnable callback);
+
+        /**
+         * Called when the PIP requested to be expanded.
+         */
+        void onPipExpand();
+
+        /**
+         * Called when the PIP requested to be dismissed.
+         */
+        void onPipDismiss();
+
+        /**
+         * Called when the PIP requested to show the menu.
+         */
+        void onPipShowMenu();
+    }
+
+    private Context mContext;
+    private PipTaskOrganizer mPipTaskOrganizer;
+    private PipMediaController mMediaController;
+
+    private ArrayList<Listener> mListeners = new ArrayList<>();
+    private ParceledListSlice<RemoteAction> mAppActions;
+    private ParceledListSlice<RemoteAction> mMediaActions;
+    private int mMenuState;
+
+    private PipMenuView mPipMenuView;
+    private IBinder mPipMenuInputToken;
+
+    private ActionListener mMediaActionListener = new ActionListener() {
+        @Override
+        public void onMediaActionsChanged(List<RemoteAction> mediaActions) {
+            mMediaActions = new ParceledListSlice<>(mediaActions);
+            updateMenuActions();
+        }
+    };
+
+    public PipMenuActivityController(Context context,
+            PipMediaController mediaController, PipTaskOrganizer pipTaskOrganizer) {
+        mContext = context;
+        mMediaController = mediaController;
+        mPipTaskOrganizer = pipTaskOrganizer;
+    }
+
+    public boolean isMenuVisible() {
+        return mPipMenuView != null && mMenuState != MENU_STATE_NONE;
+    }
+
+    public void onActivityPinned() {
+        attachPipMenuView();
+    }
+
+    public void onActivityUnpinned() {
+        hideMenu();
+        mPipTaskOrganizer.detachPipMenuViewHost();
+        mPipMenuView = null;
+        mPipMenuInputToken = null;
+    }
+
+    public void onPinnedStackAnimationEnded() {
+        if (isMenuVisible()) {
+            mPipMenuView.onPipAnimationEnded();
+        }
+    }
+
+    private void attachPipMenuView() {
+        if (mPipMenuView == null) {
+            mPipMenuView = new PipMenuView(mContext, this);
+
+        }
+
+        // If we haven't gotten the input toekn, that means we haven't had a success attempt
+        // yet at attaching the PipMenuView
+        if (mPipMenuInputToken == null) {
+            mPipMenuInputToken = mPipTaskOrganizer.attachPipMenuViewHost(mPipMenuView,
+                    getPipMenuLayoutParams(0, 0));
+        }
+    }
+
+    /**
+     * Adds a new menu activity listener.
+     */
+    public void addListener(Listener listener) {
+        if (!mListeners.contains(listener)) {
+            mListeners.add(listener);
+        }
+    }
+
+    /**
+     * Updates the appearance of the menu and scrim on top of the PiP while dismissing.
+     */
+    public void setDismissFraction(float fraction) {
+        final boolean isMenuVisible = isMenuVisible();
+        if (DEBUG) {
+            Log.d(TAG, "setDismissFraction() isMenuVisible=" + isMenuVisible
+                    + " fraction=" + fraction);
+        }
+        if (isMenuVisible) {
+            mPipMenuView.updateDismissFraction(fraction);
+        }
+    }
+
+    /**
+     * Similar to {@link #showMenu(int, Rect, boolean, boolean, boolean)} but only show the menu
+     * upon PiP window transition is finished.
+     */
+    public void showMenuWithDelay(int menuState, Rect stackBounds, boolean allowMenuTimeout,
+            boolean willResizeMenu, boolean showResizeHandle) {
+        // hide all visible controls including close button and etc. first, this is to ensure
+        // menu is totally invisible during the transition to eliminate unpleasant artifacts
+        fadeOutMenu();
+        showMenuInternal(menuState, stackBounds, allowMenuTimeout, willResizeMenu,
+                true /* withDelay */, showResizeHandle);
+    }
+
+    /**
+     * Shows the menu activity immediately.
+     */
+    public void showMenu(int menuState, Rect stackBounds, boolean allowMenuTimeout,
+            boolean willResizeMenu, boolean showResizeHandle) {
+        showMenuInternal(menuState, stackBounds, allowMenuTimeout, willResizeMenu,
+                false /* withDelay */, showResizeHandle);
+    }
+
+    private void showMenuInternal(int menuState, Rect stackBounds, boolean allowMenuTimeout,
+            boolean willResizeMenu, boolean withDelay, boolean showResizeHandle) {
+        if (DEBUG) {
+            Log.d(TAG, "showMenu() state=" + menuState
+                    + " isMenuVisible=" + isMenuVisible()
+                    + " allowMenuTimeout=" + allowMenuTimeout
+                    + " willResizeMenu=" + willResizeMenu
+                    + " withDelay=" + withDelay
+                    + " showResizeHandle=" + showResizeHandle
+                    + " callers=\n" + Debug.getCallers(5, "    "));
+        }
+
+        if (!mPipTaskOrganizer.isPipMenuViewHostAttached()) {
+            Log.d(TAG, "PipMenu has not been attached yet. Attaching now at showMenuInternal().");
+            attachPipMenuView();
+        }
+
+        mPipMenuView.showMenu(menuState, stackBounds, allowMenuTimeout, willResizeMenu, withDelay,
+                showResizeHandle);
+    }
+
+    /**
+     * Pokes the menu, indicating that the user is interacting with it.
+     */
+    public void pokeMenu() {
+        final boolean isMenuVisible = isMenuVisible();
+        if (DEBUG) {
+            Log.d(TAG, "pokeMenu() isMenuVisible=" + isMenuVisible);
+        }
+        if (isMenuVisible) {
+            mPipMenuView.pokeMenu();
+        }
+    }
+
+    private void fadeOutMenu() {
+        final boolean isMenuVisible = isMenuVisible();
+        if (DEBUG) {
+            Log.d(TAG, "fadeOutMenu() isMenuVisible=" + isMenuVisible);
+        }
+        if (isMenuVisible) {
+            mPipMenuView.fadeOutMenu();
+        }
+    }
+
+    /**
+     * Hides the menu activity.
+     */
+    public void hideMenu() {
+        final boolean isMenuVisible = isMenuVisible();
+        if (DEBUG) {
+            Log.d(TAG, "hideMenu() state=" + mMenuState
+                    + " isMenuVisible=" + isMenuVisible
+                    + " callers=\n" + Debug.getCallers(5, "    "));
+        }
+        if (isMenuVisible) {
+            mPipMenuView.hideMenu();
+        }
+    }
+
+    /**
+     * Hides the menu activity.
+     */
+    public void hideMenu(Runnable onStartCallback, Runnable onEndCallback) {
+        if (isMenuVisible()) {
+            // If the menu is visible in either the closed or full state, then hide the menu and
+            // trigger the animation trigger afterwards
+            if (onStartCallback != null) {
+                onStartCallback.run();
+            }
+            mPipMenuView.hideMenu(onEndCallback);
+        }
+    }
+
+    /**
+     * Preemptively mark the menu as invisible, used when we are directly manipulating the pinned
+     * stack and don't want to trigger a resize which can animate the stack in a conflicting way
+     * (ie. when manually expanding or dismissing).
+     */
+    public void hideMenuWithoutResize() {
+        onMenuStateChanged(MENU_STATE_NONE, false /* resize */, null /* callback */);
+    }
+
+    /**
+     * Sets the menu actions to the actions provided by the current PiP activity.
+     */
+    public void setAppActions(ParceledListSlice<RemoteAction> appActions) {
+        mAppActions = appActions;
+        updateMenuActions();
+    }
+
+    void onPipExpand() {
+        mListeners.forEach(Listener::onPipExpand);
+    }
+
+    void onPipDismiss() {
+        mListeners.forEach(Listener::onPipDismiss);
+    }
+
+    void onPipShowMenu() {
+        mListeners.forEach(Listener::onPipShowMenu);
+    }
+
+    /**
+     * @return the best set of actions to show in the PiP menu.
+     */
+    private ParceledListSlice<RemoteAction> resolveMenuActions() {
+        if (isValidActions(mAppActions)) {
+            return mAppActions;
+        }
+        return mMediaActions;
+    }
+
+    /**
+     * Returns a default LayoutParams for the PIP Menu.
+     * @param width the PIP stack width.
+     * @param height the PIP stack height.
+     */
+    public static WindowManager.LayoutParams getPipMenuLayoutParams(int width, int height) {
+        return new WindowManager.LayoutParams(width, height,
+                WindowManager.LayoutParams.TYPE_APPLICATION, 0, PixelFormat.TRANSLUCENT);
+    }
+
+    /**
+     * Updates the PiP menu with the best set of actions provided.
+     */
+    private void updateMenuActions() {
+        if (isMenuVisible()) {
+            // Fetch the pinned stack bounds
+            Rect stackBounds = null;
+            try {
+                RootTaskInfo pinnedTaskInfo = ActivityTaskManager.getService().getRootTaskInfo(
+                        WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+                if (pinnedTaskInfo != null) {
+                    stackBounds = pinnedTaskInfo.bounds;
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error showing PIP menu", e);
+            }
+
+            mPipMenuView.setActions(stackBounds, resolveMenuActions().getList());
+        }
+    }
+
+    /**
+     * Returns whether the set of actions are valid.
+     */
+    private static boolean isValidActions(ParceledListSlice<?> actions) {
+        return actions != null && actions.getList().size() > 0;
+    }
+
+    /**
+     * Handles changes in menu visibility.
+     */
+    void onMenuStateChanged(int menuState, boolean resize, Runnable callback) {
+        if (DEBUG) {
+            Log.d(TAG, "onMenuStateChanged() mMenuState=" + mMenuState
+                    + " menuState=" + menuState + " resize=" + resize
+                    + " callers=\n" + Debug.getCallers(5, "    "));
+        }
+
+        if (menuState != mMenuState) {
+            mListeners.forEach(l -> l.onPipMenuStateChanged(menuState, resize, callback));
+            if (menuState == MENU_STATE_FULL) {
+                // Once visible, start listening for media action changes. This call will trigger
+                // the menu actions to be updated again.
+                mMediaController.addListener(mMediaActionListener);
+            } else {
+                // Once hidden, stop listening for media action changes. This call will trigger
+                // the menu actions to be updated again.
+                mMediaController.removeListener(mMediaActionListener);
+            }
+
+            try {
+                WindowManagerGlobal.getWindowSession().grantEmbeddedWindowFocus(null /* window */,
+                        mPipMenuInputToken, menuState != MENU_STATE_NONE /* grantFocus */);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Unable to update focus as menu appears/disappears", e);
+            }
+        }
+        mMenuState = menuState;
+    }
+
+    /**
+     * Handles a pointer event sent from pip input consumer.
+     */
+    void handlePointerEvent(MotionEvent ev) {
+        if (ev.isTouchEvent()) {
+            mPipMenuView.dispatchTouchEvent(ev);
+        } else {
+            mPipMenuView.dispatchGenericMotionEvent(ev);
+        }
+    }
+
+    /**
+     * Tell the PIP Menu to recalculate its layout given its current position on the display.
+     */
+    public void updateMenuLayout(Rect bounds) {
+        final boolean isMenuVisible = isMenuVisible();
+        if (DEBUG) {
+            Log.d(TAG, "updateMenuLayout() state=" + mMenuState
+                    + " isMenuVisible=" + isMenuVisible
+                    + " callers=\n" + Debug.getCallers(5, "    "));
+        }
+        if (isMenuVisible) {
+            mPipMenuView.updateMenuLayout(bounds);
+        }
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mMenuState=" + mMenuState);
+        pw.println(innerPrefix + "mPipMenuView=" + mPipMenuView);
+        pw.println(innerPrefix + "mListeners=" + mListeners.size());
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuIconsAlgorithm.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuIconsAlgorithm.java
new file mode 100644
index 0000000..985cd0f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuIconsAlgorithm.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+/**
+ * Helper class to calculate and place the menu icons on the PIP Menu.
+ */
+public class PipMenuIconsAlgorithm {
+
+    private static final String TAG = "PipMenuIconsAlgorithm";
+
+    private boolean mFinishedLayout = false;
+    protected ViewGroup mViewRoot;
+    protected ViewGroup mTopEndContainer;
+    protected View mDragHandle;
+    protected View mSettingsButton;
+    protected View mDismissButton;
+
+    protected PipMenuIconsAlgorithm(Context context) {
+    }
+
+    /**
+     * Bind the necessary views.
+     */
+    public void bindViews(ViewGroup viewRoot, ViewGroup topEndContainer, View dragHandle,
+            View settingsButton, View dismissButton) {
+        mViewRoot = viewRoot;
+        mTopEndContainer = topEndContainer;
+        mDragHandle = dragHandle;
+        mSettingsButton = settingsButton;
+        mDismissButton = dismissButton;
+    }
+
+    /**
+     * Updates the position of the drag handle based on where the PIP window is on the screen.
+     */
+    public void onBoundsChanged(Rect bounds) {
+        if (mViewRoot == null || mTopEndContainer == null || mDragHandle == null
+                || mSettingsButton == null || mDismissButton == null) {
+            Log.e(TAG, "One if the required views is null.");
+        }
+
+        //We only need to calculate the layout once since it does not change.
+        if (!mFinishedLayout) {
+            mTopEndContainer.removeView(mSettingsButton);
+            mViewRoot.addView(mSettingsButton);
+
+            setLayoutGravity(mDragHandle, Gravity.START | Gravity.TOP);
+            setLayoutGravity(mSettingsButton, Gravity.START | Gravity.TOP);
+            mFinishedLayout = true;
+        }
+    }
+
+    /**
+     * Set the gravity on the given view.
+     */
+    protected static void setLayoutGravity(View v, int gravity) {
+        if (v.getLayoutParams() instanceof FrameLayout.LayoutParams) {
+            FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) v.getLayoutParams();
+            params.gravity = gravity;
+            v.setLayoutParams(params);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
new file mode 100644
index 0000000..24e49f8
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.provider.Settings.ACTION_PICTURE_IN_PICTURE_SETTINGS;
+import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_CONTROLS;
+import static android.view.accessibility.AccessibilityManager.FLAG_CONTENT_ICONS;
+import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
+
+import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE;
+import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_FULL;
+import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_NONE;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
+import android.app.ActivityManager;
+import android.app.PendingIntent.CanceledException;
+import android.app.RemoteAction;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.util.Log;
+import android.util.Pair;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.widget.FrameLayout;
+import android.widget.ImageButton;
+import android.widget.LinearLayout;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.animation.Interpolators;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Translucent window that gets started on top of a task in PIP to allow the user to control it.
+ */
+public class PipMenuView extends FrameLayout {
+
+    private static final String TAG = "PipMenuView";
+
+    private static final int MESSAGE_INVALID_TYPE = -1;
+    public static final int MESSAGE_MENU_EXPANDED = 8;
+
+    private static final int INITIAL_DISMISS_DELAY = 3500;
+    private static final int POST_INTERACTION_DISMISS_DELAY = 2000;
+    private static final long MENU_FADE_DURATION = 125;
+    private static final long MENU_SLOW_FADE_DURATION = 175;
+    private static final long MENU_SHOW_ON_EXPAND_START_DELAY = 30;
+
+    private static final float MENU_BACKGROUND_ALPHA = 0.3f;
+    private static final float DISMISS_BACKGROUND_ALPHA = 0.6f;
+
+    private static final float DISABLED_ACTION_ALPHA = 0.54f;
+
+    private static final boolean ENABLE_RESIZE_HANDLE = false;
+
+    private int mMenuState;
+    private boolean mResize = true;
+    private boolean mAllowMenuTimeout = true;
+    private boolean mAllowTouches = true;
+
+    private final List<RemoteAction> mActions = new ArrayList<>();
+
+    private AccessibilityManager mAccessibilityManager;
+    private Drawable mBackgroundDrawable;
+    private View mMenuContainer;
+    private LinearLayout mActionsGroup;
+    private int mBetweenActionPaddingLand;
+
+    private AnimatorSet mMenuContainerAnimator;
+    private PipMenuActivityController mController;
+
+    private ValueAnimator.AnimatorUpdateListener mMenuBgUpdateListener =
+            new ValueAnimator.AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(ValueAnimator animation) {
+                    final float alpha = (float) animation.getAnimatedValue();
+                    mBackgroundDrawable.setAlpha((int) (MENU_BACKGROUND_ALPHA * alpha * 255));
+                }
+            };
+
+    private Handler mHandler = new Handler();
+
+    private final Runnable mHideMenuRunnable = this::hideMenu;
+
+    protected View mViewRoot;
+    protected View mSettingsButton;
+    protected View mDismissButton;
+    protected View mResizeHandle;
+    protected View mTopEndContainer;
+    protected PipMenuIconsAlgorithm mPipMenuIconsAlgorithm;
+
+    public PipMenuView(Context context, PipMenuActivityController controller) {
+        super(context, null, 0);
+        mContext = context;
+        mController = controller;
+
+        mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+        inflate(context, R.layout.pip_menu, this);
+
+        mBackgroundDrawable = new ColorDrawable(Color.BLACK);
+        mBackgroundDrawable.setAlpha(0);
+        mViewRoot = findViewById(R.id.background);
+        mViewRoot.setBackground(mBackgroundDrawable);
+        mMenuContainer = findViewById(R.id.menu_container);
+        mMenuContainer.setAlpha(0);
+        mTopEndContainer = findViewById(R.id.top_end_container);
+        mSettingsButton = findViewById(R.id.settings);
+        mSettingsButton.setAlpha(0);
+        mSettingsButton.setOnClickListener((v) -> {
+            if (v.getAlpha() != 0) {
+                showSettings();
+            }
+        });
+        mDismissButton = findViewById(R.id.dismiss);
+        mDismissButton.setAlpha(0);
+        mDismissButton.setOnClickListener(v -> dismissPip());
+        findViewById(R.id.expand_button).setOnClickListener(v -> {
+            if (mMenuContainer.getAlpha() != 0) {
+                expandPip();
+            }
+        });
+
+        mResizeHandle = findViewById(R.id.resize_handle);
+        mResizeHandle.setAlpha(0);
+        mActionsGroup = findViewById(R.id.actions_group);
+        mBetweenActionPaddingLand = getResources().getDimensionPixelSize(
+                R.dimen.pip_between_action_padding_land);
+        mPipMenuIconsAlgorithm = new PipMenuIconsAlgorithm(mContext);
+        mPipMenuIconsAlgorithm.bindViews((ViewGroup) mViewRoot, (ViewGroup) mTopEndContainer,
+                mResizeHandle, mSettingsButton, mDismissButton);
+
+        initAccessibility();
+    }
+
+    private void initAccessibility() {
+        this.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+            @Override
+            public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+                super.onInitializeAccessibilityNodeInfo(host, info);
+                String label = getResources().getString(R.string.pip_menu_title);
+                info.addAction(new AccessibilityNodeInfo.AccessibilityAction(ACTION_CLICK, label));
+            }
+
+            @Override
+            public boolean performAccessibilityAction(View host, int action, Bundle args) {
+                if (action == ACTION_CLICK && mMenuState == MENU_STATE_CLOSE) {
+                    mController.onPipShowMenu();
+                }
+                return super.performAccessibilityAction(host, action, args);
+            }
+        });
+    }
+
+    @Override
+    public boolean onKeyUp(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_ESCAPE) {
+            hideMenu();
+            return true;
+        }
+        return super.onKeyUp(keyCode, event);
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        if (!mAllowTouches) {
+            return false;
+        }
+
+        if (mAllowMenuTimeout) {
+            repostDelayedHide(POST_INTERACTION_DISMISS_DELAY);
+        }
+
+        return super.dispatchTouchEvent(ev);
+    }
+
+    @Override
+    public boolean dispatchGenericMotionEvent(MotionEvent event) {
+        if (mAllowMenuTimeout) {
+            repostDelayedHide(POST_INTERACTION_DISMISS_DELAY);
+        }
+
+        return super.dispatchGenericMotionEvent(event);
+    }
+
+    void showMenu(int menuState, Rect stackBounds, boolean allowMenuTimeout,
+            boolean resizeMenuOnShow, boolean withDelay, boolean showResizeHandle) {
+        mAllowMenuTimeout = allowMenuTimeout;
+        if (mMenuState != menuState) {
+            // Disallow touches if the menu needs to resize while showing, and we are transitioning
+            // to/from a full menu state.
+            boolean disallowTouchesUntilAnimationEnd = resizeMenuOnShow
+                    && (mMenuState == MENU_STATE_FULL || menuState == MENU_STATE_FULL);
+            mAllowTouches = !disallowTouchesUntilAnimationEnd;
+            cancelDelayedHide();
+            updateActionViews(stackBounds);
+            if (mMenuContainerAnimator != null) {
+                mMenuContainerAnimator.cancel();
+            }
+            mMenuContainerAnimator = new AnimatorSet();
+            ObjectAnimator menuAnim = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
+                    mMenuContainer.getAlpha(), 1f);
+            menuAnim.addUpdateListener(mMenuBgUpdateListener);
+            ObjectAnimator settingsAnim = ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA,
+                    mSettingsButton.getAlpha(), 1f);
+            ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
+                    mDismissButton.getAlpha(), 1f);
+            ObjectAnimator resizeAnim = ObjectAnimator.ofFloat(mResizeHandle, View.ALPHA,
+                    mResizeHandle.getAlpha(),
+                    ENABLE_RESIZE_HANDLE && menuState == MENU_STATE_CLOSE && showResizeHandle
+                            ? 1f : 0f);
+            if (menuState == MENU_STATE_FULL) {
+                mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim,
+                        resizeAnim);
+            } else {
+                mMenuContainerAnimator.playTogether(dismissAnim, resizeAnim);
+            }
+            mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
+            mMenuContainerAnimator.setDuration(menuState == MENU_STATE_CLOSE
+                    ? MENU_FADE_DURATION
+                    : MENU_SLOW_FADE_DURATION);
+            if (allowMenuTimeout) {
+                mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        repostDelayedHide(INITIAL_DISMISS_DELAY);
+                    }
+                });
+            }
+            if (withDelay) {
+                // starts the menu container animation after window expansion is completed
+                notifyMenuStateChange(menuState, resizeMenuOnShow, () -> {
+                    if (mMenuContainerAnimator == null) {
+                        return;
+                    }
+                    mMenuContainerAnimator.setStartDelay(MENU_SHOW_ON_EXPAND_START_DELAY);
+                    mMenuContainerAnimator.start();
+                });
+            } else {
+                notifyMenuStateChange(menuState, resizeMenuOnShow, null);
+                mMenuContainerAnimator.start();
+            }
+        } else {
+            // If we are already visible, then just start the delayed dismiss and unregister any
+            // existing input consumers from the previous drag
+            if (allowMenuTimeout) {
+                repostDelayedHide(POST_INTERACTION_DISMISS_DELAY);
+            }
+        }
+    }
+
+    /**
+     * Different from {@link #hideMenu()}, this function does not try to finish this menu activity
+     * and instead, it fades out the controls by setting the alpha to 0 directly without menu
+     * visibility callbacks invoked.
+     */
+    void fadeOutMenu() {
+        mMenuContainer.setAlpha(0f);
+        mSettingsButton.setAlpha(0f);
+        mDismissButton.setAlpha(0f);
+        mResizeHandle.setAlpha(0f);
+    }
+
+    void pokeMenu() {
+        cancelDelayedHide();
+    }
+
+    void onPipAnimationEnded() {
+        mAllowTouches = true;
+    }
+
+    void updateMenuLayout(Rect bounds) {
+        mPipMenuIconsAlgorithm.onBoundsChanged(bounds);
+    }
+
+    void hideMenu() {
+        hideMenu(null);
+    }
+
+    void hideMenu(Runnable animationEndCallback) {
+        hideMenu(animationEndCallback, true /* notifyMenuVisibility */, true /* animate */);
+    }
+
+    private void hideMenu(final Runnable animationFinishedRunnable, boolean notifyMenuVisibility,
+            boolean animate) {
+        if (mMenuState != MENU_STATE_NONE) {
+            cancelDelayedHide();
+            if (notifyMenuVisibility) {
+                notifyMenuStateChange(MENU_STATE_NONE, mResize, null);
+            }
+            mMenuContainerAnimator = new AnimatorSet();
+            ObjectAnimator menuAnim = ObjectAnimator.ofFloat(mMenuContainer, View.ALPHA,
+                    mMenuContainer.getAlpha(), 0f);
+            menuAnim.addUpdateListener(mMenuBgUpdateListener);
+            ObjectAnimator settingsAnim = ObjectAnimator.ofFloat(mSettingsButton, View.ALPHA,
+                    mSettingsButton.getAlpha(), 0f);
+            ObjectAnimator dismissAnim = ObjectAnimator.ofFloat(mDismissButton, View.ALPHA,
+                    mDismissButton.getAlpha(), 0f);
+            ObjectAnimator resizeAnim = ObjectAnimator.ofFloat(mResizeHandle, View.ALPHA,
+                    mResizeHandle.getAlpha(), 0f);
+            mMenuContainerAnimator.playTogether(menuAnim, settingsAnim, dismissAnim, resizeAnim);
+            mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_OUT);
+            mMenuContainerAnimator.setDuration(animate ? MENU_FADE_DURATION : 0);
+            mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (animationFinishedRunnable != null) {
+                        animationFinishedRunnable.run();
+                    }
+                }
+            });
+            mMenuContainerAnimator.start();
+        }
+    }
+
+    void setActions(Rect stackBounds, List<RemoteAction> actions) {
+        mActions.clear();
+        mActions.addAll(actions);
+        updateActionViews(stackBounds);
+    }
+
+    private void updateActionViews(Rect stackBounds) {
+        ViewGroup expandContainer = findViewById(R.id.expand_container);
+        ViewGroup actionsContainer = findViewById(R.id.actions_container);
+        actionsContainer.setOnTouchListener((v, ev) -> {
+            // Do nothing, prevent click through to parent
+            return true;
+        });
+
+        if (mActions.isEmpty() || mMenuState == MENU_STATE_CLOSE) {
+            actionsContainer.setVisibility(View.INVISIBLE);
+        } else {
+            actionsContainer.setVisibility(View.VISIBLE);
+            if (mActionsGroup != null) {
+                // Ensure we have as many buttons as actions
+                final LayoutInflater inflater = LayoutInflater.from(mContext);
+                while (mActionsGroup.getChildCount() < mActions.size()) {
+                    final ImageButton actionView = (ImageButton) inflater.inflate(
+                            R.layout.pip_menu_action, mActionsGroup, false);
+                    mActionsGroup.addView(actionView);
+                }
+
+                // Update the visibility of all views
+                for (int i = 0; i < mActionsGroup.getChildCount(); i++) {
+                    mActionsGroup.getChildAt(i).setVisibility(i < mActions.size()
+                            ? View.VISIBLE
+                            : View.GONE);
+                }
+
+                // Recreate the layout
+                final boolean isLandscapePip = stackBounds != null
+                        && (stackBounds.width() > stackBounds.height());
+                for (int i = 0; i < mActions.size(); i++) {
+                    final RemoteAction action = mActions.get(i);
+                    final ImageButton actionView = (ImageButton) mActionsGroup.getChildAt(i);
+
+                    // TODO: Check if the action drawable has changed before we reload it
+                    action.getIcon().loadDrawableAsync(mContext, d -> {
+                        if (d != null) {
+                            d.setTint(Color.WHITE);
+                            actionView.setImageDrawable(d);
+                        }
+                    }, mHandler);
+                    actionView.setContentDescription(action.getContentDescription());
+                    if (action.isEnabled()) {
+                        actionView.setOnClickListener(v -> {
+                            mHandler.post(() -> {
+                                try {
+                                    action.getActionIntent().send();
+                                } catch (CanceledException e) {
+                                    Log.w(TAG, "Failed to send action", e);
+                                }
+                            });
+                        });
+                    }
+                    actionView.setEnabled(action.isEnabled());
+                    actionView.setAlpha(action.isEnabled() ? 1f : DISABLED_ACTION_ALPHA);
+
+                    // Update the margin between actions
+                    LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)
+                            actionView.getLayoutParams();
+                    lp.leftMargin = (isLandscapePip && i > 0) ? mBetweenActionPaddingLand : 0;
+                }
+            }
+
+            // Update the expand container margin to adjust the center of the expand button to
+            // account for the existence of the action container
+            FrameLayout.LayoutParams expandedLp =
+                    (FrameLayout.LayoutParams) expandContainer.getLayoutParams();
+            expandedLp.topMargin = getResources().getDimensionPixelSize(
+                    R.dimen.pip_action_padding);
+            expandedLp.bottomMargin = getResources().getDimensionPixelSize(
+                    R.dimen.pip_expand_container_edge_margin);
+            expandContainer.requestLayout();
+        }
+    }
+
+    void updateDismissFraction(float fraction) {
+        int alpha;
+        final float menuAlpha = 1 - fraction;
+        if (mMenuState == MENU_STATE_FULL) {
+            mMenuContainer.setAlpha(menuAlpha);
+            mSettingsButton.setAlpha(menuAlpha);
+            mDismissButton.setAlpha(menuAlpha);
+            final float interpolatedAlpha =
+                    MENU_BACKGROUND_ALPHA * menuAlpha + DISMISS_BACKGROUND_ALPHA * fraction;
+            alpha = (int) (interpolatedAlpha * 255);
+        } else {
+            if (mMenuState == MENU_STATE_CLOSE) {
+                mDismissButton.setAlpha(menuAlpha);
+            }
+            alpha = (int) (fraction * DISMISS_BACKGROUND_ALPHA * 255);
+        }
+        mBackgroundDrawable.setAlpha(alpha);
+    }
+
+    private void notifyMenuStateChange(int menuState, boolean resize, Runnable callback) {
+        mMenuState = menuState;
+        mController.onMenuStateChanged(menuState, resize, callback);
+    }
+
+    private void expandPip() {
+        // Do not notify menu visibility when hiding the menu, the controller will do this when it
+        // handles the message
+        hideMenu(mController::onPipExpand, false /* notifyMenuVisibility */, true /* animate */);
+    }
+
+    private void dismissPip() {
+        // Since tapping on the close-button invokes a double-tap wait callback in PipTouchHandler,
+        // we want to disable animating the fadeout animation of the buttons in order to call on
+        // PipTouchHandler#onPipDismiss fast enough.
+        final boolean animate = mMenuState != MENU_STATE_CLOSE;
+        // Do not notify menu visibility when hiding the menu, the controller will do this when it
+        // handles the message
+        hideMenu(mController::onPipDismiss, false /* notifyMenuVisibility */, animate);
+    }
+
+    private void showSettings() {
+        final Pair<ComponentName, Integer> topPipActivityInfo =
+                PipUtils.getTopPipActivity(mContext, ActivityManager.getService());
+        if (topPipActivityInfo.first != null) {
+            final Intent settingsIntent = new Intent(ACTION_PICTURE_IN_PICTURE_SETTINGS,
+                    Uri.fromParts("package", topPipActivityInfo.first.getPackageName(), null));
+            settingsIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
+            mContext.startActivityAsUser(settingsIntent, UserHandle.CURRENT);
+        }
+    }
+
+    private void cancelDelayedHide() {
+        mHandler.removeCallbacks(mHideMenuRunnable);
+    }
+
+    private void repostDelayedHide(int delay) {
+        int recommendedTimeout = mAccessibilityManager.getRecommendedTimeoutMillis(delay,
+                FLAG_CONTENT_ICONS | FLAG_CONTENT_CONTROLS);
+        mHandler.removeCallbacks(mHideMenuRunnable);
+        mHandler.postDelayed(mHideMenuRunnable, recommendedTimeout);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
new file mode 100644
index 0000000..cc86cf9
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMotionHelper.java
@@ -0,0 +1,667 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.Log;
+import android.view.Choreographer;
+
+import androidx.annotation.VisibleForTesting;
+import androidx.dynamicanimation.animation.AnimationHandler;
+import androidx.dynamicanimation.animation.AnimationHandler.FrameCallbackScheduler;
+import androidx.dynamicanimation.animation.SpringForce;
+
+import com.android.wm.shell.animation.FloatProperties;
+import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
+import com.android.wm.shell.pip.PipSnapAlgorithm;
+import com.android.wm.shell.pip.PipTaskOrganizer;
+
+import java.io.PrintWriter;
+import java.util.function.Consumer;
+
+import kotlin.Unit;
+import kotlin.jvm.functions.Function0;
+
+/**
+ * A helper to animate and manipulate the PiP.
+ */
+public class PipMotionHelper implements PipAppOpsListener.Callback,
+        FloatingContentCoordinator.FloatingContent {
+
+    private static final String TAG = "PipMotionHelper";
+    private static final boolean DEBUG = false;
+
+    private static final int SHRINK_STACK_FROM_MENU_DURATION = 250;
+    private static final int EXPAND_STACK_TO_MENU_DURATION = 250;
+    private static final int LEAVE_PIP_DURATION = 300;
+    private static final int SHIFT_DURATION = 300;
+    private static final float STASH_RATIO = 0.25f;
+
+    /** Friction to use for PIP when it moves via physics fling animations. */
+    private static final float DEFAULT_FRICTION = 2f;
+
+    private final Context mContext;
+    private final PipTaskOrganizer mPipTaskOrganizer;
+
+    private PipMenuActivityController mMenuController;
+    private PipSnapAlgorithm mSnapAlgorithm;
+
+    private final Handler mMainHandler = new Handler(Looper.getMainLooper());
+
+    /** PIP's current bounds on the screen. */
+    private final Rect mBounds = new Rect();
+
+    /** The bounds within which PIP's top-left coordinate is allowed to move. */
+    private final Rect mMovementBounds = new Rect();
+
+    /** The region that all of PIP must stay within. */
+    private final Rect mFloatingAllowedArea = new Rect();
+
+    /**
+     * Temporary bounds used when PIP is being dragged or animated. These bounds are applied to PIP
+     * using {@link PipTaskOrganizer#scheduleUserResizePip}, so that we can animate shrinking into
+     * and expanding out of the magnetic dismiss target.
+     *
+     * Once PIP is done being dragged or animated, we set {@link #mBounds} equal to these temporary
+     * bounds, and call {@link PipTaskOrganizer#scheduleFinishResizePip} to 'officially' move PIP to
+     * its new bounds.
+     */
+    private final Rect mTemporaryBounds = new Rect();
+
+    /** The destination bounds to which PIP is animating. */
+    private final Rect mAnimatingToBounds = new Rect();
+
+    /** Coordinator instance for resolving conflicts with other floating content. */
+    private FloatingContentCoordinator mFloatingContentCoordinator;
+
+    private ThreadLocal<AnimationHandler> mSfAnimationHandlerThreadLocal =
+            ThreadLocal.withInitial(() -> {
+                FrameCallbackScheduler scheduler = runnable ->
+                        Choreographer.getSfInstance().postFrameCallback(t -> runnable.run());
+                AnimationHandler handler = new AnimationHandler(scheduler);
+                return handler;
+            });
+
+    /**
+     * PhysicsAnimator instance for animating {@link #mTemporaryBounds} using physics animations.
+     */
+    private PhysicsAnimator<Rect> mTemporaryBoundsPhysicsAnimator = PhysicsAnimator.getInstance(
+            mTemporaryBounds);
+
+    private MagnetizedObject<Rect> mMagnetizedPip;
+
+    /**
+     * Update listener that resizes the PIP to {@link #mTemporaryBounds}.
+     */
+    private final PhysicsAnimator.UpdateListener<Rect> mResizePipUpdateListener;
+
+    /** FlingConfig instances provided to PhysicsAnimator for fling gestures. */
+    private PhysicsAnimator.FlingConfig mFlingConfigX;
+    private PhysicsAnimator.FlingConfig mFlingConfigY;
+    /** FlingConfig instances proviced to PhysicsAnimator for stashing. */
+    private PhysicsAnimator.FlingConfig mStashConfigX;
+
+    /** SpringConfig to use for fling-then-spring animations. */
+    private final PhysicsAnimator.SpringConfig mSpringConfig =
+            new PhysicsAnimator.SpringConfig(
+                    SpringForce.STIFFNESS_MEDIUM, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
+
+    /** SpringConfig to use for springing PIP away from conflicting floating content. */
+    private final PhysicsAnimator.SpringConfig mConflictResolutionSpringConfig =
+                new PhysicsAnimator.SpringConfig(
+                        SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
+
+    private final Consumer<Rect> mUpdateBoundsCallback = (Rect newBounds) -> {
+        mMainHandler.post(() -> {
+            mMenuController.updateMenuLayout(newBounds);
+            mBounds.set(newBounds);
+        });
+    };
+
+    /**
+     * Whether we're springing to the touch event location (vs. moving it to that position
+     * instantly). We spring-to-touch after PIP is dragged out of the magnetic target, since it was
+     * 'stuck' in the target and needs to catch up to the touch location.
+     */
+    private boolean mSpringingToTouch = false;
+
+    /**
+     * Whether PIP was released in the dismiss target, and will be animated out and dismissed
+     * shortly.
+     */
+    private boolean mDismissalPending = false;
+
+    /**
+     * Gets set in {@link #animateToExpandedState(Rect, Rect, Rect, Runnable)}, this callback is
+     * used to show menu activity when the expand animation is completed.
+     */
+    private Runnable mPostPipTransitionCallback;
+
+    private final PipTaskOrganizer.PipTransitionCallback mPipTransitionCallback =
+            new PipTaskOrganizer.PipTransitionCallback() {
+        @Override
+        public void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds) {}
+
+        @Override
+        public void onPipTransitionFinished(ComponentName activity, int direction) {
+            if (mPostPipTransitionCallback != null) {
+                mPostPipTransitionCallback.run();
+                mPostPipTransitionCallback = null;
+            }
+        }
+
+        @Override
+        public void onPipTransitionCanceled(ComponentName activity, int direction) {}
+    };
+
+    public PipMotionHelper(Context context, PipTaskOrganizer pipTaskOrganizer,
+            PipMenuActivityController menuController, PipSnapAlgorithm snapAlgorithm,
+            FloatingContentCoordinator floatingContentCoordinator) {
+        mContext = context;
+        mPipTaskOrganizer = pipTaskOrganizer;
+        mMenuController = menuController;
+        mSnapAlgorithm = snapAlgorithm;
+        mFloatingContentCoordinator = floatingContentCoordinator;
+        mPipTaskOrganizer.registerPipTransitionCallback(mPipTransitionCallback);
+        mTemporaryBoundsPhysicsAnimator.setCustomAnimationHandler(
+                mSfAnimationHandlerThreadLocal.get());
+
+        mResizePipUpdateListener = (target, values) -> {
+            if (!mTemporaryBounds.isEmpty()) {
+                mPipTaskOrganizer.scheduleUserResizePip(
+                        mBounds, mTemporaryBounds, null);
+            }
+        };
+    }
+
+    @NonNull
+    @Override
+    public Rect getFloatingBoundsOnScreen() {
+        return !mAnimatingToBounds.isEmpty() ? mAnimatingToBounds : mBounds;
+    }
+
+    @NonNull
+    @Override
+    public Rect getAllowedFloatingBoundsRegion() {
+        return mFloatingAllowedArea;
+    }
+
+    @Override
+    public void moveToBounds(@NonNull Rect bounds) {
+        animateToBounds(bounds, mConflictResolutionSpringConfig);
+    }
+
+    /**
+     * Synchronizes the current bounds with the pinned stack, cancelling any ongoing animations.
+     */
+    void synchronizePinnedStackBounds() {
+        cancelAnimations();
+        mBounds.set(mPipTaskOrganizer.getLastReportedBounds());
+        mTemporaryBounds.setEmpty();
+
+        if (mPipTaskOrganizer.isInPip()) {
+            mFloatingContentCoordinator.onContentMoved(this);
+        }
+    }
+
+    boolean isAnimating() {
+        return mTemporaryBoundsPhysicsAnimator.isRunning();
+    }
+
+    /**
+     * Tries to move the pinned stack to the given {@param bounds}.
+     */
+    void movePip(Rect toBounds) {
+        movePip(toBounds, false /* isDragging */);
+    }
+
+    /**
+     * Tries to move the pinned stack to the given {@param bounds}.
+     *
+     * @param isDragging Whether this movement is the result of a drag touch gesture. If so, we
+     *                   won't notify the floating content coordinator of this move, since that will
+     *                   happen when the gesture ends.
+     */
+    void movePip(Rect toBounds, boolean isDragging) {
+        if (!isDragging) {
+            mFloatingContentCoordinator.onContentMoved(this);
+        }
+
+        if (!mSpringingToTouch) {
+            // If we are moving PIP directly to the touch event locations, cancel any animations and
+            // move PIP to the given bounds.
+            cancelAnimations();
+
+            if (!isDragging) {
+                resizePipUnchecked(toBounds);
+                mBounds.set(toBounds);
+            } else {
+                mTemporaryBounds.set(toBounds);
+                mPipTaskOrganizer.scheduleUserResizePip(mBounds, mTemporaryBounds,
+                        (Rect newBounds) -> {
+                            mMainHandler.post(() -> {
+                                mMenuController.updateMenuLayout(newBounds);
+                            });
+                    });
+            }
+        } else {
+            // If PIP is 'catching up' after being stuck in the dismiss target, update the animation
+            // to spring towards the new touch location.
+            mTemporaryBoundsPhysicsAnimator
+                    .spring(FloatProperties.RECT_WIDTH, mBounds.width(), mSpringConfig)
+                    .spring(FloatProperties.RECT_HEIGHT, mBounds.height(), mSpringConfig)
+                    .spring(FloatProperties.RECT_X, toBounds.left, mSpringConfig)
+                    .spring(FloatProperties.RECT_Y, toBounds.top, mSpringConfig);
+
+            startBoundsAnimator(toBounds.left /* toX */, toBounds.top /* toY */,
+                    false /* dismiss */);
+        }
+    }
+
+    /** Animates the PIP into the dismiss target, scaling it down. */
+    void animateIntoDismissTarget(
+            MagnetizedObject.MagneticTarget target,
+            float velX, float velY,
+            boolean flung, Function0<Unit> after) {
+        final PointF targetCenter = target.getCenterOnScreen();
+
+        final float desiredWidth = mBounds.width() / 2;
+        final float desiredHeight = mBounds.height() / 2;
+
+        final float destinationX = targetCenter.x - (desiredWidth / 2f);
+        final float destinationY = targetCenter.y - (desiredHeight / 2f);
+
+        // If we're already in the dismiss target area, then there won't be a move to set the
+        // temporary bounds, so just initialize it to the current bounds
+        if (mTemporaryBounds.isEmpty()) {
+            mTemporaryBounds.set(mBounds);
+        }
+        mTemporaryBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_X, destinationX, velX, mSpringConfig)
+                .spring(FloatProperties.RECT_Y, destinationY, velY, mSpringConfig)
+                .spring(FloatProperties.RECT_WIDTH, desiredWidth, mSpringConfig)
+                .spring(FloatProperties.RECT_HEIGHT, desiredHeight, mSpringConfig)
+                .withEndActions(after);
+
+        startBoundsAnimator(destinationX, destinationY, false);
+    }
+
+    /** Set whether we're springing-to-touch to catch up after being stuck in the dismiss target. */
+    void setSpringingToTouch(boolean springingToTouch) {
+        mSpringingToTouch = springingToTouch;
+    }
+
+    /**
+     * Resizes the pinned stack back to unknown windowing mode, which could be freeform or
+     *      * fullscreen depending on the display area's windowing mode.
+     */
+    void expandLeavePip() {
+        expandLeavePip(false /* skipAnimation */);
+    }
+
+    /**
+     * Resizes the pinned stack back to unknown windowing mode, which could be freeform or
+     * fullscreen depending on the display area's windowing mode.
+     */
+    void expandLeavePip(boolean skipAnimation) {
+        if (DEBUG) {
+            Log.d(TAG, "exitPip: skipAnimation=" + skipAnimation
+                    + " callers=\n" + Debug.getCallers(5, "    "));
+        }
+        cancelAnimations();
+        mMenuController.hideMenuWithoutResize();
+        mPipTaskOrganizer.getUpdateHandler().post(() -> {
+            mPipTaskOrganizer.exitPip(skipAnimation
+                    ? 0
+                    : LEAVE_PIP_DURATION);
+        });
+    }
+
+    /**
+     * Dismisses the pinned stack.
+     */
+    @Override
+    public void dismissPip() {
+        if (DEBUG) {
+            Log.d(TAG, "removePip: callers=\n" + Debug.getCallers(5, "    "));
+        }
+        cancelAnimations();
+        mMenuController.hideMenuWithoutResize();
+        mPipTaskOrganizer.removePip();
+    }
+
+    /** Sets the movement bounds to use to constrain PIP position animations. */
+    void setCurrentMovementBounds(Rect movementBounds) {
+        mMovementBounds.set(movementBounds);
+        rebuildFlingConfigs();
+
+        // The movement bounds represent the area within which we can move PIP's top-left position.
+        // The allowed area for all of PIP is those bounds plus PIP's width and height.
+        mFloatingAllowedArea.set(mMovementBounds);
+        mFloatingAllowedArea.right += mBounds.width();
+        mFloatingAllowedArea.bottom += mBounds.height();
+    }
+
+    /**
+     * @return the PiP bounds.
+     */
+    Rect getBounds() {
+        return mBounds;
+    }
+
+    /**
+     * Returns the PIP bounds if we're not animating, or the current, temporary animating bounds
+     * otherwise.
+     */
+    Rect getPossiblyAnimatingBounds() {
+        return mTemporaryBounds.isEmpty() ? mBounds : mTemporaryBounds;
+    }
+
+    /**
+     * Flings the PiP to the closest snap target.
+     */
+    void flingToSnapTarget(
+            float velocityX, float velocityY,
+            @Nullable Runnable updateAction, @Nullable Runnable endAction) {
+        movetoTarget(velocityX, velocityY, updateAction, endAction, false /* isStash */);
+    }
+
+    /**
+     * Stash PiP to the closest edge.
+     */
+    void stashToEdge(
+            float velocityX, float velocityY,
+            @Nullable Runnable updateAction, @Nullable Runnable endAction) {
+        movetoTarget(velocityX, velocityY, updateAction, endAction, true /* isStash */);
+    }
+
+    private void movetoTarget(
+            float velocityX, float velocityY,
+            @Nullable Runnable updateAction, @Nullable Runnable endAction, boolean isStash) {
+        // If we're flinging to a snap target now, we're not springing to catch up to the touch
+        // location now.
+        mSpringingToTouch = false;
+
+        mTemporaryBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_WIDTH, mBounds.width(), mSpringConfig)
+                .spring(FloatProperties.RECT_HEIGHT, mBounds.height(), mSpringConfig)
+                .flingThenSpring(
+                        FloatProperties.RECT_X, velocityX, isStash ? mStashConfigX : mFlingConfigX,
+                        mSpringConfig, true /* flingMustReachMinOrMax */)
+                .flingThenSpring(
+                        FloatProperties.RECT_Y, velocityY, mFlingConfigY, mSpringConfig)
+                .withEndActions(endAction);
+
+        if (updateAction != null) {
+            mTemporaryBoundsPhysicsAnimator.addUpdateListener(
+                    (target, values) -> updateAction.run());
+        }
+
+        final float offset = ((float) mBounds.width()) * (1.0f - STASH_RATIO);
+        final float leftEdge = isStash ? mMovementBounds.left - offset : mMovementBounds.left;
+        final float rightEdge = isStash ?  mMovementBounds.right + offset : mMovementBounds.right;
+
+        final float xEndValue = velocityX < 0 ? leftEdge : rightEdge;
+        final float estimatedFlingYEndValue =
+                PhysicsAnimator.estimateFlingEndValue(
+                        mTemporaryBounds.top, velocityY, mFlingConfigY);
+
+        startBoundsAnimator(xEndValue /* toX */, estimatedFlingYEndValue /* toY */,
+                false /* dismiss */);
+    }
+
+    /**
+     * Animates PIP to the provided bounds, using physics animations and the given spring
+     * configuration
+     */
+    void animateToBounds(Rect bounds, PhysicsAnimator.SpringConfig springConfig) {
+        if (!mTemporaryBoundsPhysicsAnimator.isRunning()) {
+            // Animate from the current bounds if we're not already animating.
+            mTemporaryBounds.set(mBounds);
+        }
+
+        mTemporaryBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_X, bounds.left, springConfig)
+                .spring(FloatProperties.RECT_Y, bounds.top, springConfig);
+        startBoundsAnimator(bounds.left /* toX */, bounds.top /* toY */,
+                false /* dismiss */);
+    }
+
+    /**
+     * Animates the dismissal of the PiP off the edge of the screen.
+     */
+    void animateDismiss() {
+        // Animate off the bottom of the screen, then dismiss PIP.
+        mTemporaryBoundsPhysicsAnimator
+                .spring(FloatProperties.RECT_Y,
+                        mMovementBounds.bottom + mBounds.height() * 2,
+                        0,
+                        mSpringConfig)
+                .withEndActions(this::dismissPip);
+
+        startBoundsAnimator(
+                mBounds.left /* toX */, mBounds.bottom + mBounds.height() /* toY */,
+                true /* dismiss */);
+
+        mDismissalPending = false;
+    }
+
+    /**
+     * Animates the PiP to the expanded state to show the menu.
+     */
+    float animateToExpandedState(Rect expandedBounds, Rect movementBounds,
+            Rect expandedMovementBounds, Runnable callback) {
+        float savedSnapFraction = mSnapAlgorithm.getSnapFraction(new Rect(mBounds), movementBounds);
+        mSnapAlgorithm.applySnapFraction(expandedBounds, expandedMovementBounds, savedSnapFraction);
+        mPostPipTransitionCallback = callback;
+        resizeAndAnimatePipUnchecked(expandedBounds, EXPAND_STACK_TO_MENU_DURATION);
+        return savedSnapFraction;
+    }
+
+    /**
+     * Animates the PiP from the expanded state to the normal state after the menu is hidden.
+     */
+    void animateToUnexpandedState(Rect normalBounds, float savedSnapFraction,
+            Rect normalMovementBounds, Rect currentMovementBounds, boolean immediate) {
+        if (savedSnapFraction < 0f) {
+            // If there are no saved snap fractions, then just use the current bounds
+            savedSnapFraction = mSnapAlgorithm.getSnapFraction(new Rect(mBounds),
+                    currentMovementBounds);
+        }
+        mSnapAlgorithm.applySnapFraction(normalBounds, normalMovementBounds, savedSnapFraction);
+
+        if (immediate) {
+            movePip(normalBounds);
+        } else {
+            resizeAndAnimatePipUnchecked(normalBounds, SHRINK_STACK_FROM_MENU_DURATION);
+        }
+    }
+
+    /**
+     * Animates the PiP to offset it from the IME or shelf.
+     */
+    @VisibleForTesting
+    public void animateToOffset(Rect originalBounds, int offset) {
+        if (DEBUG) {
+            Log.d(TAG, "animateToOffset: originalBounds=" + originalBounds + " offset=" + offset
+                    + " callers=\n" + Debug.getCallers(5, "    "));
+        }
+        cancelAnimations();
+        mPipTaskOrganizer.scheduleOffsetPip(originalBounds, offset, SHIFT_DURATION,
+                mUpdateBoundsCallback);
+    }
+
+    /**
+     * Cancels all existing animations.
+     */
+    private void cancelAnimations() {
+        mTemporaryBoundsPhysicsAnimator.cancel();
+        mAnimatingToBounds.setEmpty();
+        mSpringingToTouch = false;
+    }
+
+    /** Set new fling configs whose min/max values respect the given movement bounds. */
+    private void rebuildFlingConfigs() {
+        mFlingConfigX = new PhysicsAnimator.FlingConfig(
+                DEFAULT_FRICTION, mMovementBounds.left, mMovementBounds.right);
+        mFlingConfigY = new PhysicsAnimator.FlingConfig(
+                DEFAULT_FRICTION, mMovementBounds.top, mMovementBounds.bottom);
+        final float offset = ((float) mBounds.width()) * (1.0f - STASH_RATIO);
+        mStashConfigX = new PhysicsAnimator.FlingConfig(
+                DEFAULT_FRICTION, mMovementBounds.left - offset, mMovementBounds.right + offset);
+    }
+
+    /**
+     * Starts the physics animator which will update the animated PIP bounds using physics
+     * animations, as well as the TimeAnimator which will apply those bounds to PIP.
+     *
+     * This will also add end actions to the bounds animator that cancel the TimeAnimator and update
+     * the 'real' bounds to equal the final animated bounds.
+     */
+    private void startBoundsAnimator(float toX, float toY, boolean dismiss) {
+        if (!mSpringingToTouch) {
+            cancelAnimations();
+        }
+
+        // Set animatingToBounds directly to avoid allocating a new Rect, but then call
+        // setAnimatingToBounds to run the normal logic for changing animatingToBounds.
+        mAnimatingToBounds.set(
+                (int) toX,
+                (int) toY,
+                (int) toX + mBounds.width(),
+                (int) toY + mBounds.height());
+        setAnimatingToBounds(mAnimatingToBounds);
+
+        if (!mTemporaryBoundsPhysicsAnimator.isRunning()) {
+            mTemporaryBoundsPhysicsAnimator
+                    .addUpdateListener(mResizePipUpdateListener)
+                    .withEndActions(this::onBoundsAnimationEnd);
+        }
+
+        mTemporaryBoundsPhysicsAnimator.start();
+    }
+
+    /**
+     * Notify that PIP was released in the dismiss target and will be animated out and dismissed
+     * shortly.
+     */
+    void notifyDismissalPending() {
+        mDismissalPending = true;
+    }
+
+    private void onBoundsAnimationEnd() {
+        if (!mDismissalPending
+                && !mSpringingToTouch
+                && !mMagnetizedPip.getObjectStuckToTarget()) {
+            mBounds.set(mTemporaryBounds);
+            if (!mDismissalPending) {
+                // do not schedule resize if PiP is dismissing, which may cause app re-open to
+                // mBounds instead of it's normal bounds.
+                mPipTaskOrganizer.scheduleFinishResizePip(mBounds);
+            }
+            mTemporaryBounds.setEmpty();
+        }
+
+        mAnimatingToBounds.setEmpty();
+        mSpringingToTouch = false;
+        mDismissalPending = false;
+    }
+
+    /**
+     * Notifies the floating coordinator that we're moving, and sets {@link #mAnimatingToBounds} so
+     * we return these bounds from
+     * {@link FloatingContentCoordinator.FloatingContent#getFloatingBoundsOnScreen()}.
+     */
+    private void setAnimatingToBounds(Rect bounds) {
+        mAnimatingToBounds.set(bounds);
+        mFloatingContentCoordinator.onContentMoved(this);
+    }
+
+    /**
+     * Directly resizes the PiP to the given {@param bounds}.
+     */
+    private void resizePipUnchecked(Rect toBounds) {
+        if (DEBUG) {
+            Log.d(TAG, "resizePipUnchecked: toBounds=" + toBounds
+                    + " callers=\n" + Debug.getCallers(5, "    "));
+        }
+        if (!toBounds.equals(mBounds)) {
+            mPipTaskOrganizer.scheduleResizePip(toBounds, mUpdateBoundsCallback);
+        }
+    }
+
+    /**
+     * Directly resizes the PiP to the given {@param bounds}.
+     */
+    private void resizeAndAnimatePipUnchecked(Rect toBounds, int duration) {
+        if (DEBUG) {
+            Log.d(TAG, "resizeAndAnimatePipUnchecked: toBounds=" + toBounds
+                    + " duration=" + duration + " callers=\n" + Debug.getCallers(5, "    "));
+        }
+
+        // Intentionally resize here even if the current bounds match the destination bounds.
+        // This is so all the proper callbacks are performed.
+        mPipTaskOrganizer.scheduleAnimateResizePip(toBounds, duration, mUpdateBoundsCallback);
+        setAnimatingToBounds(toBounds);
+    }
+
+    /**
+     * Returns a MagnetizedObject wrapper for PIP's animated bounds. This is provided to the
+     * magnetic dismiss target so it can calculate PIP's size and position.
+     */
+    MagnetizedObject<Rect> getMagnetizedPip() {
+        if (mMagnetizedPip == null) {
+            mMagnetizedPip = new MagnetizedObject<Rect>(
+                    mContext, mTemporaryBounds, FloatProperties.RECT_X, FloatProperties.RECT_Y) {
+                @Override
+                public float getWidth(@NonNull Rect animatedPipBounds) {
+                    return animatedPipBounds.width();
+                }
+
+                @Override
+                public float getHeight(@NonNull Rect animatedPipBounds) {
+                    return animatedPipBounds.height();
+                }
+
+                @Override
+                public void getLocationOnScreen(
+                        @NonNull Rect animatedPipBounds, @NonNull int[] loc) {
+                    loc[0] = animatedPipBounds.left;
+                    loc[1] = animatedPipBounds.top;
+                }
+            };
+        }
+
+        return mMagnetizedPip;
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mBounds=" + mBounds);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
new file mode 100644
index 0000000..ef38755
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipResizeGestureHandler.java
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_PINCH_RESIZE;
+import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_BOTTOM;
+import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_LEFT;
+import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_NONE;
+import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_RIGHT;
+import static com.android.internal.policy.TaskResizingAlgorithm.CTRL_TOP;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.hardware.input.InputManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.provider.DeviceConfig;
+import android.view.BatchedInputEventReceiver;
+import android.view.Choreographer;
+import android.view.InputChannel;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
+import android.view.InputMonitor;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.view.ViewConfiguration;
+
+import androidx.annotation.VisibleForTesting;
+
+import com.android.internal.policy.TaskResizingAlgorithm;
+import com.android.wm.shell.R;
+import com.android.wm.shell.pip.PipBoundsHandler;
+import com.android.wm.shell.pip.PipTaskOrganizer;
+import com.android.wm.shell.pip.PipUiEventLogger;
+
+import java.io.PrintWriter;
+import java.util.concurrent.Executor;
+import java.util.function.Function;
+
+/**
+ * Helper on top of PipTouchHandler that handles inputs OUTSIDE of the PIP window, which is used to
+ * trigger dynamic resize.
+ */
+public class PipResizeGestureHandler {
+
+    private static final String TAG = "PipResizeGestureHandler";
+    private static final float PINCH_THRESHOLD = 0.05f;
+    private static final float STARTING_SCALE_FACTOR = 1.0f;
+
+    private final Context mContext;
+    private final PipBoundsHandler mPipBoundsHandler;
+    private final PipMotionHelper mMotionHelper;
+    private final int mDisplayId;
+    private final Executor mMainExecutor;
+    private final ScaleGestureDetector mScaleGestureDetector;
+    private final Region mTmpRegion = new Region();
+
+    private final PointF mDownPoint = new PointF();
+    private final Point mMaxSize = new Point();
+    private final Point mMinSize = new Point();
+    private final Rect mLastResizeBounds = new Rect();
+    private final Rect mUserResizeBounds = new Rect();
+    private final Rect mLastDownBounds = new Rect();
+    private final Rect mDragCornerSize = new Rect();
+    private final Rect mTmpTopLeftCorner = new Rect();
+    private final Rect mTmpTopRightCorner = new Rect();
+    private final Rect mTmpBottomLeftCorner = new Rect();
+    private final Rect mTmpBottomRightCorner = new Rect();
+    private final Rect mDisplayBounds = new Rect();
+    private final Function<Rect, Rect> mMovementBoundsSupplier;
+    private final Runnable mUpdateMovementBoundsRunnable;
+
+    private int mDelta;
+    private float mTouchSlop;
+    private boolean mAllowGesture;
+    private boolean mIsAttached;
+    private boolean mIsEnabled;
+    private boolean mEnablePinchResize;
+    private boolean mIsSysUiStateValid;
+    private boolean mThresholdCrossed;
+    private boolean mUsingPinchToZoom = false;
+    private float mScaleFactor = STARTING_SCALE_FACTOR;
+
+    private InputMonitor mInputMonitor;
+    private InputEventReceiver mInputEventReceiver;
+    private PipTaskOrganizer mPipTaskOrganizer;
+    private PipMenuActivityController mPipMenuActivityController;
+    private PipUiEventLogger mPipUiEventLogger;
+
+    private int mCtrlType;
+
+    public PipResizeGestureHandler(Context context, PipBoundsHandler pipBoundsHandler,
+            PipMotionHelper motionHelper, PipTaskOrganizer pipTaskOrganizer,
+            Function<Rect, Rect> movementBoundsSupplier, Runnable updateMovementBoundsRunnable,
+            PipUiEventLogger pipUiEventLogger, PipMenuActivityController menuActivityController) {
+        mContext = context;
+        mDisplayId = context.getDisplayId();
+        mMainExecutor = context.getMainExecutor();
+        mPipBoundsHandler = pipBoundsHandler;
+        mMotionHelper = motionHelper;
+        mPipTaskOrganizer = pipTaskOrganizer;
+        mMovementBoundsSupplier = movementBoundsSupplier;
+        mUpdateMovementBoundsRunnable = updateMovementBoundsRunnable;
+        mPipMenuActivityController = menuActivityController;
+        mPipUiEventLogger = pipUiEventLogger;
+
+        context.getDisplay().getRealSize(mMaxSize);
+        reloadResources();
+
+        mScaleGestureDetector = new ScaleGestureDetector(context,
+                new ScaleGestureDetector.OnScaleGestureListener() {
+                    @Override
+                    public boolean onScale(ScaleGestureDetector detector) {
+                        mScaleFactor *= detector.getScaleFactor();
+
+                        if (!mThresholdCrossed
+                                && (mScaleFactor > (STARTING_SCALE_FACTOR + PINCH_THRESHOLD)
+                                || mScaleFactor < (STARTING_SCALE_FACTOR - PINCH_THRESHOLD))) {
+                            mThresholdCrossed = true;
+                            mInputMonitor.pilferPointers();
+                        }
+                        if (mThresholdCrossed) {
+                            int height = Math.min(mMaxSize.y, Math.max(mMinSize.y,
+                                    (int) (mScaleFactor * mLastDownBounds.height())));
+                            int width = Math.min(mMaxSize.x, Math.max(mMinSize.x,
+                                    (int) (mScaleFactor * mLastDownBounds.width())));
+                            int top, bottom, left, right;
+
+                            if ((mCtrlType & CTRL_TOP) != 0) {
+                                top = mLastDownBounds.bottom - height;
+                                bottom = mLastDownBounds.bottom;
+                            } else {
+                                top = mLastDownBounds.top;
+                                bottom = mLastDownBounds.top + height;
+                            }
+
+                            if ((mCtrlType & CTRL_LEFT) != 0) {
+                                left = mLastDownBounds.right - width;
+                                right = mLastDownBounds.right;
+                            } else {
+                                left = mLastDownBounds.left;
+                                right = mLastDownBounds.left + width;
+                            }
+
+                            mLastResizeBounds.set(left, top, right, bottom);
+                            mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds,
+                                    mLastResizeBounds,
+                                    null);
+                        }
+                        return true;
+                    }
+
+                    @Override
+                    public boolean onScaleBegin(ScaleGestureDetector detector) {
+                        setCtrlTypeForPinchToZoom();
+                        return true;
+                    }
+
+                    @Override
+                    public void onScaleEnd(ScaleGestureDetector detector) {
+                        mScaleFactor = STARTING_SCALE_FACTOR;
+                        finishResize();
+                    }
+                });
+
+        mEnablePinchResize = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                PIP_PINCH_RESIZE,
+                /* defaultValue = */ false);
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI, mMainExecutor,
+                new DeviceConfig.OnPropertiesChangedListener() {
+                    @Override
+                    public void onPropertiesChanged(DeviceConfig.Properties properties) {
+                        if (properties.getKeyset().contains(PIP_PINCH_RESIZE)) {
+                            mEnablePinchResize = properties.getBoolean(
+                                    PIP_PINCH_RESIZE, /* defaultValue = */ false);
+                        }
+                    }
+                });
+    }
+
+    public void onConfigurationChanged() {
+        reloadResources();
+    }
+
+    /**
+     * Called when SysUI state changed.
+     *
+     * @param isSysUiStateValid Is SysUI valid or not.
+     */
+    public void onSystemUiStateChanged(boolean isSysUiStateValid) {
+        mIsSysUiStateValid = isSysUiStateValid;
+    }
+
+    private void reloadResources() {
+        final Resources res = mContext.getResources();
+        mDelta = res.getDimensionPixelSize(R.dimen.pip_resize_edge_size);
+        mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+    }
+
+    private void resetDragCorners() {
+        mDragCornerSize.set(0, 0, mDelta, mDelta);
+        mTmpTopLeftCorner.set(mDragCornerSize);
+        mTmpTopRightCorner.set(mDragCornerSize);
+        mTmpBottomLeftCorner.set(mDragCornerSize);
+        mTmpBottomRightCorner.set(mDragCornerSize);
+    }
+
+    private void disposeInputChannel() {
+        if (mInputEventReceiver != null) {
+            mInputEventReceiver.dispose();
+            mInputEventReceiver = null;
+        }
+        if (mInputMonitor != null) {
+            mInputMonitor.dispose();
+            mInputMonitor = null;
+        }
+    }
+
+    void onActivityPinned() {
+        mIsAttached = true;
+        updateIsEnabled();
+    }
+
+    void onActivityUnpinned() {
+        mIsAttached = false;
+        mUserResizeBounds.setEmpty();
+        updateIsEnabled();
+    }
+
+    private void updateIsEnabled() {
+        boolean isEnabled = mIsAttached;
+        if (isEnabled == mIsEnabled) {
+            return;
+        }
+        mIsEnabled = isEnabled;
+        disposeInputChannel();
+
+        if (mIsEnabled) {
+            // Register input event receiver
+            mInputMonitor = InputManager.getInstance().monitorGestureInput(
+                    "pip-resize", mDisplayId);
+            mInputEventReceiver = new SysUiInputEventReceiver(
+                    mInputMonitor.getInputChannel(), Looper.getMainLooper());
+        }
+    }
+
+    private void onInputEvent(InputEvent ev) {
+        if (ev instanceof MotionEvent) {
+            if (mUsingPinchToZoom) {
+                mScaleGestureDetector.onTouchEvent((MotionEvent) ev);
+            } else {
+                onDragCornerResize((MotionEvent) ev);
+            }
+        }
+    }
+
+    /**
+     * Check whether the current x,y coordinate is within the region in which drag-resize should
+     * start.
+     * This consists of 4 small squares on the 4 corners of the PIP window, a quarter of which
+     * overlaps with the PIP window while the rest goes outside of the PIP window.
+     *  _ _           _ _
+     * |_|_|_________|_|_|
+     * |_|_|         |_|_|
+     *   |     PIP     |
+     *   |   WINDOW    |
+     *  _|_           _|_
+     * |_|_|_________|_|_|
+     * |_|_|         |_|_|
+     */
+    public boolean isWithinTouchRegion(int x, int y) {
+        final Rect currentPipBounds = mMotionHelper.getBounds();
+        if (currentPipBounds == null) {
+            return false;
+        }
+        resetDragCorners();
+        mTmpTopLeftCorner.offset(currentPipBounds.left - mDelta / 2,
+                currentPipBounds.top - mDelta /  2);
+        mTmpTopRightCorner.offset(currentPipBounds.right - mDelta / 2,
+                currentPipBounds.top - mDelta /  2);
+        mTmpBottomLeftCorner.offset(currentPipBounds.left - mDelta / 2,
+                currentPipBounds.bottom - mDelta /  2);
+        mTmpBottomRightCorner.offset(currentPipBounds.right - mDelta / 2,
+                currentPipBounds.bottom - mDelta /  2);
+
+        mTmpRegion.setEmpty();
+        mTmpRegion.op(mTmpTopLeftCorner, Region.Op.UNION);
+        mTmpRegion.op(mTmpTopRightCorner, Region.Op.UNION);
+        mTmpRegion.op(mTmpBottomLeftCorner, Region.Op.UNION);
+        mTmpRegion.op(mTmpBottomRightCorner, Region.Op.UNION);
+
+        return mTmpRegion.contains(x, y);
+    }
+
+    public boolean isUsingPinchToZoom() {
+        return mEnablePinchResize;
+    }
+
+    public boolean willStartResizeGesture(MotionEvent ev) {
+        if (isInValidSysUiState()) {
+            switch (ev.getActionMasked()) {
+                case MotionEvent.ACTION_DOWN:
+                    // Always pass the DOWN event to the ScaleGestureDetector
+                    mScaleGestureDetector.onTouchEvent(ev);
+                    if (isWithinTouchRegion((int) ev.getRawX(), (int) ev.getRawY())) {
+                        return true;
+                    }
+                    break;
+
+                case MotionEvent.ACTION_POINTER_DOWN:
+                    if (mEnablePinchResize && ev.getPointerCount() == 2) {
+                        mUsingPinchToZoom = true;
+                        return true;
+                    }
+                    break;
+
+                default:
+                    break;
+            }
+        }
+        return false;
+    }
+
+    private void setCtrlTypeForPinchToZoom() {
+        final Rect currentPipBounds = mMotionHelper.getBounds();
+        mLastDownBounds.set(mMotionHelper.getBounds());
+
+        Rect movementBounds = mMovementBoundsSupplier.apply(currentPipBounds);
+        mDisplayBounds.set(movementBounds.left,
+                movementBounds.top,
+                movementBounds.right + currentPipBounds.width(),
+                movementBounds.bottom + currentPipBounds.height());
+
+        if (currentPipBounds.left == mDisplayBounds.left) {
+            mCtrlType |= CTRL_RIGHT;
+        } else {
+            mCtrlType |= CTRL_LEFT;
+        }
+
+        if (currentPipBounds.top > mDisplayBounds.top + mDisplayBounds.height()) {
+            mCtrlType |= CTRL_TOP;
+        } else {
+            mCtrlType |= CTRL_BOTTOM;
+        }
+    }
+
+    private void setCtrlType(int x, int y) {
+        final Rect currentPipBounds = mMotionHelper.getBounds();
+
+        Rect movementBounds = mMovementBoundsSupplier.apply(currentPipBounds);
+        mDisplayBounds.set(movementBounds.left,
+                movementBounds.top,
+                movementBounds.right + currentPipBounds.width(),
+                movementBounds.bottom + currentPipBounds.height());
+
+        if (mTmpTopLeftCorner.contains(x, y) && currentPipBounds.top != mDisplayBounds.top
+                && currentPipBounds.left != mDisplayBounds.left) {
+            mCtrlType |= CTRL_LEFT;
+            mCtrlType |= CTRL_TOP;
+        }
+        if (mTmpTopRightCorner.contains(x, y) && currentPipBounds.top != mDisplayBounds.top
+                && currentPipBounds.right != mDisplayBounds.right) {
+            mCtrlType |= CTRL_RIGHT;
+            mCtrlType |= CTRL_TOP;
+        }
+        if (mTmpBottomRightCorner.contains(x, y)
+                && currentPipBounds.bottom != mDisplayBounds.bottom
+                && currentPipBounds.right != mDisplayBounds.right) {
+            mCtrlType |= CTRL_RIGHT;
+            mCtrlType |= CTRL_BOTTOM;
+        }
+        if (mTmpBottomLeftCorner.contains(x, y)
+                && currentPipBounds.bottom != mDisplayBounds.bottom
+                && currentPipBounds.left != mDisplayBounds.left) {
+            mCtrlType |= CTRL_LEFT;
+            mCtrlType |= CTRL_BOTTOM;
+        }
+    }
+
+    private boolean isInValidSysUiState() {
+        return mIsSysUiStateValid;
+    }
+
+    private void onDragCornerResize(MotionEvent ev) {
+        int action = ev.getActionMasked();
+        float x = ev.getX();
+        float y = ev.getY();
+        if (action == MotionEvent.ACTION_DOWN) {
+            final Rect currentPipBounds = mMotionHelper.getBounds();
+            mLastResizeBounds.setEmpty();
+            mAllowGesture = isInValidSysUiState() && isWithinTouchRegion((int) x, (int) y);
+            if (mAllowGesture) {
+                setCtrlType((int) x, (int) y);
+                mDownPoint.set(x, y);
+                mLastDownBounds.set(mMotionHelper.getBounds());
+            }
+            if (!currentPipBounds.contains((int) ev.getX(), (int) ev.getY())
+                    && mPipMenuActivityController.isMenuVisible()) {
+                mPipMenuActivityController.hideMenu();
+            }
+
+        } else if (mAllowGesture) {
+            switch (action) {
+                case MotionEvent.ACTION_POINTER_DOWN:
+                    // We do not support multi touch for resizing via drag
+                    mAllowGesture = false;
+                    break;
+                case MotionEvent.ACTION_MOVE:
+                    // Capture inputs
+                    if (!mThresholdCrossed
+                            && Math.hypot(x - mDownPoint.x, y - mDownPoint.y) > mTouchSlop) {
+                        mThresholdCrossed = true;
+                        // Reset the down to begin resizing from this point
+                        mDownPoint.set(x, y);
+                        mInputMonitor.pilferPointers();
+                    }
+                    if (mThresholdCrossed) {
+                        if (mPipMenuActivityController.isMenuVisible()) {
+                            mPipMenuActivityController.hideMenuWithoutResize();
+                            mPipMenuActivityController.hideMenu();
+                        }
+                        final Rect currentPipBounds = mMotionHelper.getBounds();
+                        mLastResizeBounds.set(TaskResizingAlgorithm.resizeDrag(x, y,
+                                mDownPoint.x, mDownPoint.y, currentPipBounds, mCtrlType, mMinSize.x,
+                                mMinSize.y, mMaxSize, true,
+                                mLastDownBounds.width() > mLastDownBounds.height()));
+                        mPipBoundsHandler.transformBoundsToAspectRatio(mLastResizeBounds);
+                        mPipTaskOrganizer.scheduleUserResizePip(mLastDownBounds, mLastResizeBounds,
+                                null);
+                    }
+                    break;
+                case MotionEvent.ACTION_UP:
+                case MotionEvent.ACTION_CANCEL:
+                    finishResize();
+                    break;
+            }
+        }
+    }
+
+    private void finishResize() {
+        if (!mLastResizeBounds.isEmpty()) {
+            mUserResizeBounds.set(mLastResizeBounds);
+            mPipTaskOrganizer.scheduleFinishResizePip(mLastResizeBounds,
+                    (Rect bounds) -> {
+                        new Handler(Looper.getMainLooper()).post(() -> {
+                            mMotionHelper.synchronizePinnedStackBounds();
+                            mUpdateMovementBoundsRunnable.run();
+                            resetState();
+                        });
+                    });
+            mPipUiEventLogger.log(
+                    PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_RESIZE);
+        } else {
+            resetState();
+        }
+    }
+
+    private void resetState() {
+        mCtrlType = CTRL_NONE;
+        mUsingPinchToZoom = false;
+        mAllowGesture = false;
+        mThresholdCrossed = false;
+    }
+
+    void setUserResizeBounds(Rect bounds) {
+        mUserResizeBounds.set(bounds);
+    }
+
+    void invalidateUserResizeBounds() {
+        mUserResizeBounds.setEmpty();
+    }
+
+    Rect getUserResizeBounds() {
+        return mUserResizeBounds;
+    }
+
+    @VisibleForTesting public void updateMaxSize(int maxX, int maxY) {
+        mMaxSize.set(maxX, maxY);
+    }
+
+    @VisibleForTesting public void updateMinSize(int minX, int minY) {
+        mMinSize.set(minX, minY);
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mAllowGesture=" + mAllowGesture);
+        pw.println(innerPrefix + "mIsAttached=" + mIsAttached);
+        pw.println(innerPrefix + "mIsEnabled=" + mIsEnabled);
+        pw.println(innerPrefix + "mEnablePinchResize=" + mEnablePinchResize);
+        pw.println(innerPrefix + "mThresholdCrossed=" + mThresholdCrossed);
+    }
+
+    class SysUiInputEventReceiver extends BatchedInputEventReceiver {
+        SysUiInputEventReceiver(InputChannel channel, Looper looper) {
+            super(channel, looper, Choreographer.getSfInstance());
+        }
+
+        public void onInputEvent(InputEvent event) {
+            PipResizeGestureHandler.this.onInputEvent(event);
+            finishInputEvent(event, true);
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchGesture.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchGesture.java
new file mode 100644
index 0000000..1a3cc8b
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchGesture.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+/**
+ * A generic interface for a touch gesture.
+ */
+public abstract class PipTouchGesture {
+
+    /**
+     * Handle the touch down.
+     */
+    public void onDown(PipTouchState touchState) {}
+
+    /**
+     * Handle the touch move, and return whether the event was consumed.
+     */
+    public boolean onMove(PipTouchState touchState) {
+        return false;
+    }
+
+    /**
+     * Handle the touch up, and return whether the gesture was consumed.
+     */
+    public boolean onUp(PipTouchState touchState) {
+        return false;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
new file mode 100644
index 0000000..6b31772
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -0,0 +1,1135 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import static com.android.internal.config.sysui.SystemUiDeviceConfigFlags.PIP_STASHING;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
+import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_CLOSE;
+import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_FULL;
+import static com.android.wm.shell.pip.phone.PipMenuActivityController.MENU_STATE_NONE;
+
+import android.annotation.SuppressLint;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.graphics.drawable.TransitionDrawable;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.provider.DeviceConfig;
+import android.util.Log;
+import android.util.Size;
+import android.view.Gravity;
+import android.view.IPinnedStackController;
+import android.view.InputEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityWindowInfo;
+import android.widget.FrameLayout;
+
+import androidx.annotation.NonNull;
+import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.wm.shell.R;
+import com.android.wm.shell.animation.PhysicsAnimator;
+import com.android.wm.shell.common.DismissCircleView;
+import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.common.magnetictarget.MagnetizedObject;
+import com.android.wm.shell.pip.PipAnimationController;
+import com.android.wm.shell.pip.PipBoundsHandler;
+import com.android.wm.shell.pip.PipTaskOrganizer;
+import com.android.wm.shell.pip.PipUiEventLogger;
+
+import java.io.PrintWriter;
+
+import kotlin.Unit;
+
+/**
+ * Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding
+ * the PIP.
+ */
+public class PipTouchHandler {
+    private static final String TAG = "PipTouchHandler";
+
+    /** Duration of the dismiss scrim fading in/out. */
+    private static final int DISMISS_TRANSITION_DURATION_MS = 200;
+
+    /* The multiplier to apply scale the target size by when applying the magnetic field radius */
+    private static final float MAGNETIC_FIELD_RADIUS_MULTIPLIER = 1.25f;
+
+    // Allow dragging the PIP to a location to close it
+    private final boolean mEnableDismissDragToEdge;
+    // Allow PIP to resize to a slightly bigger state upon touch
+    private final boolean mEnableResize;
+    private final Context mContext;
+    private final WindowManager mWindowManager;
+    private final PipBoundsHandler mPipBoundsHandler;
+    private final PipUiEventLogger mPipUiEventLogger;
+
+    private PipResizeGestureHandler mPipResizeGestureHandler;
+    private IPinnedStackController mPinnedStackController;
+
+    private final PipMenuActivityController mMenuController;
+    private final AccessibilityManager mAccessibilityManager;
+    private boolean mShowPipMenuOnAnimationEnd = false;
+
+    /**
+     * Whether PIP stash is enabled or not. When enabled, if at the time of fling-release the
+     * PIP bounds is outside the left/right edge of the screen, it will be shown in "stashed" mode,
+     * where PIP will only show partially.
+     */
+    private boolean mEnableStash = false;
+
+    /**
+     * MagnetizedObject wrapper for PIP. This allows the magnetic target library to locate and move
+     * PIP.
+     */
+    private MagnetizedObject<Rect> mMagnetizedPip;
+
+    /**
+     * Container for the dismiss circle, so that it can be animated within the container via
+     * translation rather than within the WindowManager via slow layout animations.
+     */
+    private ViewGroup mTargetViewContainer;
+
+    /** Circle view used to render the dismiss target. */
+    private DismissCircleView mTargetView;
+
+    /**
+     * MagneticTarget instance wrapping the target view and allowing us to set its magnetic radius.
+     */
+    private MagnetizedObject.MagneticTarget mMagneticTarget;
+
+    /** PhysicsAnimator instance for animating the dismiss target in/out. */
+    private PhysicsAnimator<View> mMagneticTargetAnimator;
+
+    /** Default configuration to use for springing the dismiss target in/out. */
+    private final PhysicsAnimator.SpringConfig mTargetSpringConfig =
+            new PhysicsAnimator.SpringConfig(
+                    SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_LOW_BOUNCY);
+
+    // The current movement bounds
+    private Rect mMovementBounds = new Rect();
+
+    // The reference inset bounds, used to determine the dismiss fraction
+    private Rect mInsetBounds = new Rect();
+    // The reference bounds used to calculate the normal/expanded target bounds
+    private Rect mNormalBounds = new Rect();
+    @VisibleForTesting public Rect mNormalMovementBounds = new Rect();
+    private Rect mExpandedBounds = new Rect();
+    @VisibleForTesting public Rect mExpandedMovementBounds = new Rect();
+    private int mExpandedShortestEdgeSize;
+
+    // Used to workaround an issue where the WM rotation happens before we are notified, allowing
+    // us to send stale bounds
+    private int mDeferResizeToNormalBoundsUntilRotation = -1;
+    private int mDisplayRotation;
+
+    /**
+     * Runnable that can be posted delayed to show the target. This needs to be saved as a member
+     * variable so we can pass it to removeCallbacks.
+     */
+    private Runnable mShowTargetAction = this::showDismissTargetMaybe;
+
+    private Handler mHandler = new Handler();
+
+    // Behaviour states
+    private int mMenuState = MENU_STATE_NONE;
+    private boolean mIsImeShowing;
+    private int mImeHeight;
+    private int mImeOffset;
+    private int mDismissAreaHeight;
+    private boolean mIsShelfShowing;
+    private int mShelfHeight;
+    private int mMovementBoundsExtraOffsets;
+    private int mBottomOffsetBufferPx;
+    private float mSavedSnapFraction = -1f;
+    private boolean mSendingHoverAccessibilityEvents;
+    private boolean mMovementWithinDismiss;
+    private PipAccessibilityInteractionConnection mConnection;
+
+    // Touch state
+    private final PipTouchState mTouchState;
+    private final FloatingContentCoordinator mFloatingContentCoordinator;
+    private PipMotionHelper mMotionHelper;
+    private PipTouchGesture mGesture;
+
+    // Temp vars
+    private final Rect mTmpBounds = new Rect();
+
+    /**
+     * A listener for the PIP menu activity.
+     */
+    private class PipMenuListener implements PipMenuActivityController.Listener {
+        @Override
+        public void onPipMenuStateChanged(int menuState, boolean resize, Runnable callback) {
+            setMenuState(menuState, resize, callback);
+        }
+
+        @Override
+        public void onPipExpand() {
+            mMotionHelper.expandLeavePip();
+        }
+
+        @Override
+        public void onPipDismiss() {
+            mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_TAP_TO_REMOVE);
+            mTouchState.removeDoubleTapTimeoutCallback();
+            mMotionHelper.dismissPip();
+        }
+
+        @Override
+        public void onPipShowMenu() {
+            mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
+                    true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle());
+        }
+    }
+
+    @SuppressLint("InflateParams")
+    public PipTouchHandler(Context context,
+            PipMenuActivityController menuController,
+            PipBoundsHandler pipBoundsHandler,
+            PipTaskOrganizer pipTaskOrganizer,
+            FloatingContentCoordinator floatingContentCoordinator,
+            PipUiEventLogger pipUiEventLogger) {
+        // Initialize the Pip input consumer
+        mContext = context;
+        mAccessibilityManager = context.getSystemService(AccessibilityManager.class);
+        mPipBoundsHandler = pipBoundsHandler;
+        mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
+        mMenuController = menuController;
+        mMenuController.addListener(new PipMenuListener());
+        mGesture = new DefaultPipTouchGesture();
+        mMotionHelper = new PipMotionHelper(mContext, pipTaskOrganizer, mMenuController,
+                mPipBoundsHandler.getSnapAlgorithm(), floatingContentCoordinator);
+        mPipResizeGestureHandler =
+                new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper,
+                        pipTaskOrganizer, this::getMovementBounds,
+                        this::updateMovementBounds, pipUiEventLogger, menuController);
+        mTouchState = new PipTouchState(ViewConfiguration.get(context), mHandler,
+                () -> mMenuController.showMenuWithDelay(MENU_STATE_FULL, mMotionHelper.getBounds(),
+                        true /* allowMenuTimeout */, willResizeMenu(), shouldShowResizeHandle()),
+                menuController::hideMenu);
+
+        Resources res = context.getResources();
+        mEnableDismissDragToEdge = res.getBoolean(R.bool.config_pipEnableDismissDragToEdge);
+        mEnableResize = res.getBoolean(R.bool.config_pipEnableResizeForMenu);
+        reloadResources();
+
+        mFloatingContentCoordinator = floatingContentCoordinator;
+        mConnection = new PipAccessibilityInteractionConnection(mContext, mMotionHelper,
+                pipTaskOrganizer, mPipBoundsHandler.getSnapAlgorithm(),
+                this::onAccessibilityShowMenu, this::updateMovementBounds, mHandler);
+
+        mPipUiEventLogger = pipUiEventLogger;
+
+        mTargetView = new DismissCircleView(context);
+        mTargetViewContainer = new FrameLayout(context);
+        mTargetViewContainer.setBackgroundDrawable(
+                context.getDrawable(R.drawable.floating_dismiss_gradient_transition));
+        mTargetViewContainer.setClipChildren(false);
+        mTargetViewContainer.addView(mTargetView);
+
+        mMagnetizedPip = mMotionHelper.getMagnetizedPip();
+        mMagneticTarget = mMagnetizedPip.addTarget(mTargetView, 0);
+        updateMagneticTargetSize();
+
+        mMagnetizedPip.setAnimateStuckToTarget(
+                (target, velX, velY, flung, after) -> {
+                    if (mEnableDismissDragToEdge) {
+                        mMotionHelper.animateIntoDismissTarget(target, velX, velY, flung, after);
+                    }
+                    return Unit.INSTANCE;
+                });
+        mMagnetizedPip.setMagnetListener(new MagnetizedObject.MagnetListener() {
+            @Override
+            public void onStuckToTarget(@NonNull MagnetizedObject.MagneticTarget target) {
+                // Show the dismiss target, in case the initial touch event occurred within the
+                // magnetic field radius.
+                if (mEnableDismissDragToEdge) {
+                    showDismissTargetMaybe();
+                }
+            }
+
+            @Override
+            public void onUnstuckFromTarget(@NonNull MagnetizedObject.MagneticTarget target,
+                    float velX, float velY, boolean wasFlungOut) {
+                if (wasFlungOut) {
+                    mMotionHelper.flingToSnapTarget(velX, velY, null, null);
+                    hideDismissTarget();
+                } else {
+                    mMotionHelper.setSpringingToTouch(true);
+                }
+            }
+
+            @Override
+            public void onReleasedInTarget(@NonNull MagnetizedObject.MagneticTarget target) {
+                mMotionHelper.notifyDismissalPending();
+
+                mHandler.post(() -> {
+                    mMotionHelper.animateDismiss();
+                    hideDismissTarget();
+                });
+
+                mPipUiEventLogger.log(
+                        PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_DRAG_TO_REMOVE);
+            }
+        });
+
+        mMagneticTargetAnimator = PhysicsAnimator.getInstance(mTargetView);
+
+        mEnableStash = DeviceConfig.getBoolean(
+                DeviceConfig.NAMESPACE_SYSTEMUI,
+                PIP_STASHING,
+                /* defaultValue = */ false);
+        DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_SYSTEMUI,
+                context.getMainExecutor(),
+                properties -> {
+                    if (properties.getKeyset().contains(PIP_STASHING)) {
+                        mEnableStash = properties.getBoolean(
+                                PIP_STASHING, /* defaultValue = */ false);
+                    }
+                });
+    }
+
+    private void reloadResources() {
+        final Resources res = mContext.getResources();
+        mBottomOffsetBufferPx = res.getDimensionPixelSize(R.dimen.pip_bottom_offset_buffer);
+        mExpandedShortestEdgeSize = res.getDimensionPixelSize(
+                R.dimen.pip_expanded_shortest_edge_size);
+        mImeOffset = res.getDimensionPixelSize(R.dimen.pip_ime_offset);
+        mDismissAreaHeight = res.getDimensionPixelSize(R.dimen.floating_dismiss_gradient_height);
+        updateMagneticTargetSize();
+    }
+
+    private void updateMagneticTargetSize() {
+        if (mTargetView == null) {
+            return;
+        }
+
+        final Resources res = mContext.getResources();
+        final int targetSize = res.getDimensionPixelSize(R.dimen.dismiss_circle_size);
+        final FrameLayout.LayoutParams newParams =
+                new FrameLayout.LayoutParams(targetSize, targetSize);
+        newParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+        newParams.bottomMargin = mContext.getResources().getDimensionPixelSize(
+                R.dimen.floating_dismiss_bottom_margin);
+        mTargetView.setLayoutParams(newParams);
+
+        // Set the magnetic field radius equal to the target size from the center of the target
+        mMagneticTarget.setMagneticFieldRadiusPx(
+                (int) (targetSize * MAGNETIC_FIELD_RADIUS_MULTIPLIER));
+    }
+
+    private boolean shouldShowResizeHandle() {
+        return false;
+    }
+
+    public void setTouchGesture(PipTouchGesture gesture) {
+        mGesture = gesture;
+    }
+
+    public void setTouchEnabled(boolean enabled) {
+        mTouchState.setAllowTouches(enabled);
+    }
+
+    public void showPictureInPictureMenu() {
+        // Only show the menu if the user isn't currently interacting with the PiP
+        if (!mTouchState.isUserInteracting()) {
+            mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
+                    false /* allowMenuTimeout */, willResizeMenu(),
+                    shouldShowResizeHandle());
+        }
+    }
+
+    public void onActivityPinned() {
+        createOrUpdateDismissTarget();
+
+        mShowPipMenuOnAnimationEnd = true;
+        mPipResizeGestureHandler.onActivityPinned();
+        mFloatingContentCoordinator.onContentAdded(mMotionHelper);
+    }
+
+    public void onActivityUnpinned(ComponentName topPipActivity) {
+        if (topPipActivity == null) {
+            // Clean up state after the last PiP activity is removed
+            cleanUpDismissTarget();
+
+            mFloatingContentCoordinator.onContentRemoved(mMotionHelper);
+        }
+        mPipResizeGestureHandler.onActivityUnpinned();
+    }
+
+    public void onPinnedStackAnimationEnded(
+            @PipAnimationController.TransitionDirection int direction) {
+        // Always synchronize the motion helper bounds once PiP animations finish
+        mMotionHelper.synchronizePinnedStackBounds();
+        updateMovementBounds();
+        if (direction == TRANSITION_DIRECTION_TO_PIP) {
+            // Set the initial bounds as the user resize bounds.
+            mPipResizeGestureHandler.setUserResizeBounds(mMotionHelper.getBounds());
+        }
+
+        if (mShowPipMenuOnAnimationEnd) {
+            mMenuController.showMenu(MENU_STATE_CLOSE, mMotionHelper.getBounds(),
+                    true /* allowMenuTimeout */, false /* willResizeMenu */,
+                    shouldShowResizeHandle());
+            mShowPipMenuOnAnimationEnd = false;
+        }
+    }
+
+    public void onConfigurationChanged() {
+        mPipResizeGestureHandler.onConfigurationChanged();
+        mMotionHelper.synchronizePinnedStackBounds();
+        reloadResources();
+
+        // Recreate the dismiss target for the new orientation.
+        createOrUpdateDismissTarget();
+    }
+
+    public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+        mIsImeShowing = imeVisible;
+        mImeHeight = imeHeight;
+    }
+
+    public void onShelfVisibilityChanged(boolean shelfVisible, int shelfHeight) {
+        mIsShelfShowing = shelfVisible;
+        mShelfHeight = shelfHeight;
+    }
+
+    /**
+     * Called when SysUI state changed.
+     *
+     * @param isSysUiStateValid Is SysUI valid or not.
+     */
+    public void onSystemUiStateChanged(boolean isSysUiStateValid) {
+        mPipResizeGestureHandler.onSystemUiStateChanged(isSysUiStateValid);
+    }
+
+    public void adjustBoundsForRotation(Rect outBounds, Rect curBounds, Rect insetBounds) {
+        final Rect toMovementBounds = new Rect();
+        mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(outBounds, insetBounds,
+                toMovementBounds, 0);
+        final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets;
+        if ((prevBottom - mBottomOffsetBufferPx) <= curBounds.top) {
+            outBounds.offsetTo(outBounds.left, toMovementBounds.bottom);
+        }
+    }
+
+    /**
+     * Responds to IPinnedStackListener on resetting aspect ratio for the pinned window.
+     */
+    public void onAspectRatioChanged() {
+        mPipResizeGestureHandler.invalidateUserResizeBounds();
+    }
+
+    public void onMovementBoundsChanged(Rect insetBounds, Rect normalBounds, Rect curBounds,
+            boolean fromImeAdjustment, boolean fromShelfAdjustment, int displayRotation) {
+        // Set the user resized bounds equal to the new normal bounds in case they were
+        // invalidated (e.g. by an aspect ratio change).
+        if (mPipResizeGestureHandler.getUserResizeBounds().isEmpty()) {
+            mPipResizeGestureHandler.setUserResizeBounds(normalBounds);
+        }
+
+        final int bottomOffset = mIsImeShowing ? mImeHeight : 0;
+        final boolean fromDisplayRotationChanged = (mDisplayRotation != displayRotation);
+        if (fromDisplayRotationChanged) {
+            mTouchState.reset();
+        }
+
+        // Re-calculate the expanded bounds
+        mNormalBounds.set(normalBounds);
+        Rect normalMovementBounds = new Rect();
+        mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(mNormalBounds, insetBounds,
+                normalMovementBounds, bottomOffset);
+
+        if (mMovementBounds.isEmpty()) {
+            // mMovementBounds is not initialized yet and a clean movement bounds without
+            // bottom offset shall be used later in this function.
+            mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds,
+                    mMovementBounds, 0 /* bottomOffset */);
+        }
+
+        // Calculate the expanded size
+        float aspectRatio = (float) normalBounds.width() / normalBounds.height();
+        Point displaySize = new Point();
+        mContext.getDisplay().getRealSize(displaySize);
+        Size expandedSize = mPipBoundsHandler.getSnapAlgorithm().getSizeForAspectRatio(aspectRatio,
+                mExpandedShortestEdgeSize, displaySize.x, displaySize.y);
+        mExpandedBounds.set(0, 0, expandedSize.getWidth(), expandedSize.getHeight());
+        Rect expandedMovementBounds = new Rect();
+        mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(mExpandedBounds, insetBounds,
+                expandedMovementBounds, bottomOffset);
+
+        mPipResizeGestureHandler.updateMinSize(mNormalBounds.width(), mNormalBounds.height());
+        mPipResizeGestureHandler.updateMaxSize(mExpandedBounds.width(), mExpandedBounds.height());
+
+        // The extra offset does not really affect the movement bounds, but are applied based on the
+        // current state (ime showing, or shelf offset) when we need to actually shift
+        int extraOffset = Math.max(
+                mIsImeShowing ? mImeOffset : 0,
+                !mIsImeShowing && mIsShelfShowing ? mShelfHeight : 0);
+
+        // If this is from an IME or shelf adjustment, then we should move the PiP so that it is not
+        // occluded by the IME or shelf.
+        if (fromImeAdjustment || fromShelfAdjustment) {
+            if (mTouchState.isUserInteracting()) {
+                // Defer the update of the current movement bounds until after the user finishes
+                // touching the screen
+            } else {
+                final boolean isExpanded = mMenuState == MENU_STATE_FULL && willResizeMenu();
+                final Rect toMovementBounds = new Rect();
+                mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds,
+                        toMovementBounds, mIsImeShowing ? mImeHeight : 0);
+                final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets;
+                // This is to handle landscape fullscreen IMEs, don't apply the extra offset in this
+                // case
+                final int toBottom = toMovementBounds.bottom < toMovementBounds.top
+                        ? toMovementBounds.bottom
+                        : toMovementBounds.bottom - extraOffset;
+
+                if (isExpanded) {
+                    curBounds.set(mExpandedBounds);
+                    mPipBoundsHandler.getSnapAlgorithm().applySnapFraction(curBounds,
+                            toMovementBounds, mSavedSnapFraction);
+                }
+
+                if (prevBottom < toBottom) {
+                    // The movement bounds are expanding
+                    if (curBounds.top > prevBottom - mBottomOffsetBufferPx) {
+                        mMotionHelper.animateToOffset(curBounds, toBottom - curBounds.top);
+                    }
+                } else if (prevBottom > toBottom) {
+                    // The movement bounds are shrinking
+                    if (curBounds.top > toBottom - mBottomOffsetBufferPx) {
+                        mMotionHelper.animateToOffset(curBounds, toBottom - curBounds.top);
+                    }
+                }
+            }
+        }
+
+        // Update the movement bounds after doing the calculations based on the old movement bounds
+        // above
+        mNormalMovementBounds.set(normalMovementBounds);
+        mExpandedMovementBounds.set(expandedMovementBounds);
+        mDisplayRotation = displayRotation;
+        mInsetBounds.set(insetBounds);
+        updateMovementBounds();
+        mMovementBoundsExtraOffsets = extraOffset;
+        mConnection.onMovementBoundsChanged(mNormalBounds, mExpandedBounds, mNormalMovementBounds,
+                mExpandedMovementBounds);
+
+        // If we have a deferred resize, apply it now
+        if (mDeferResizeToNormalBoundsUntilRotation == displayRotation) {
+            mMotionHelper.animateToUnexpandedState(normalBounds, mSavedSnapFraction,
+                    mNormalMovementBounds, mMovementBounds, true /* immediate */);
+            mSavedSnapFraction = -1f;
+            mDeferResizeToNormalBoundsUntilRotation = -1;
+        }
+    }
+
+    /** Adds the magnetic target view to the WindowManager so it's ready to be animated in. */
+    private void createOrUpdateDismissTarget() {
+        if (!mTargetViewContainer.isAttachedToWindow()) {
+            mHandler.removeCallbacks(mShowTargetAction);
+            mMagneticTargetAnimator.cancel();
+
+            mTargetViewContainer.setVisibility(View.INVISIBLE);
+
+            try {
+                mWindowManager.addView(mTargetViewContainer, getDismissTargetLayoutParams());
+            } catch (IllegalStateException e) {
+                // This shouldn't happen, but if the target is already added, just update its layout
+                // params.
+                mWindowManager.updateViewLayout(
+                        mTargetViewContainer, getDismissTargetLayoutParams());
+            }
+        } else {
+            mWindowManager.updateViewLayout(mTargetViewContainer, getDismissTargetLayoutParams());
+        }
+    }
+
+    /** Returns layout params for the dismiss target, using the latest display metrics. */
+    private WindowManager.LayoutParams getDismissTargetLayoutParams() {
+        final Point windowSize = new Point();
+        mWindowManager.getDefaultDisplay().getRealSize(windowSize);
+
+        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
+                WindowManager.LayoutParams.MATCH_PARENT,
+                mDismissAreaHeight,
+                0, windowSize.y - mDismissAreaHeight,
+                WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                        | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                        | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
+                PixelFormat.TRANSLUCENT);
+
+        lp.setTitle("pip-dismiss-overlay");
+        lp.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
+        lp.setFitInsetsTypes(0 /* types */);
+
+        return lp;
+    }
+
+    /** Makes the dismiss target visible and animates it in, if it isn't already visible. */
+    private void showDismissTargetMaybe() {
+        createOrUpdateDismissTarget();
+
+        if (mTargetViewContainer.getVisibility() != View.VISIBLE) {
+
+            mTargetView.setTranslationY(mTargetViewContainer.getHeight());
+            mTargetViewContainer.setVisibility(View.VISIBLE);
+
+            // Cancel in case we were in the middle of animating it out.
+            mMagneticTargetAnimator.cancel();
+            mMagneticTargetAnimator
+                    .spring(DynamicAnimation.TRANSLATION_Y, 0f, mTargetSpringConfig)
+                    .start();
+
+            ((TransitionDrawable) mTargetViewContainer.getBackground()).startTransition(
+                    DISMISS_TRANSITION_DURATION_MS);
+        }
+    }
+
+    /** Animates the magnetic dismiss target out and then sets it to GONE. */
+    private void hideDismissTarget() {
+        mHandler.removeCallbacks(mShowTargetAction);
+        mMagneticTargetAnimator
+                .spring(DynamicAnimation.TRANSLATION_Y,
+                        mTargetViewContainer.getHeight(),
+                        mTargetSpringConfig)
+                .withEndActions(() -> mTargetViewContainer.setVisibility(View.GONE))
+                .start();
+
+        ((TransitionDrawable) mTargetViewContainer.getBackground()).reverseTransition(
+                DISMISS_TRANSITION_DURATION_MS);
+    }
+
+    /**
+     * Removes the dismiss target and cancels any pending callbacks to show it.
+     */
+    private void cleanUpDismissTarget() {
+        mHandler.removeCallbacks(mShowTargetAction);
+
+        if (mTargetViewContainer.isAttachedToWindow()) {
+            mWindowManager.removeViewImmediate(mTargetViewContainer);
+        }
+    }
+
+    /**
+     * TODO Add appropriate description
+     */
+    public void onRegistrationChanged(boolean isRegistered) {
+        mAccessibilityManager.setPictureInPictureActionReplacingConnection(isRegistered
+                ? mConnection : null);
+        if (!isRegistered && mTouchState.isUserInteracting()) {
+            // If the input consumer is unregistered while the user is interacting, then we may not
+            // get the final TOUCH_UP event, so clean up the dismiss target as well
+            cleanUpDismissTarget();
+        }
+    }
+
+    private void onAccessibilityShowMenu() {
+        mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
+                true /* allowMenuTimeout */, willResizeMenu(),
+                shouldShowResizeHandle());
+    }
+
+    /**
+     * TODO Add appropriate description
+     */
+    public boolean handleTouchEvent(InputEvent inputEvent) {
+        // Skip any non motion events
+        if (!(inputEvent instanceof MotionEvent)) {
+            return true;
+        }
+        // Skip touch handling until we are bound to the controller
+        if (mPinnedStackController == null) {
+            return true;
+        }
+
+        MotionEvent ev = (MotionEvent) inputEvent;
+        if (mPipResizeGestureHandler.willStartResizeGesture(ev)) {
+            // Initialize the touch state for the gesture, but immediately reset to invalidate the
+            // gesture
+            mTouchState.onTouchEvent(ev);
+            mTouchState.reset();
+            return true;
+        }
+
+        if ((ev.getAction() == MotionEvent.ACTION_DOWN || mTouchState.isUserInteracting())
+                && mMagnetizedPip.maybeConsumeMotionEvent(ev)) {
+            // If the first touch event occurs within the magnetic field, pass the ACTION_DOWN event
+            // to the touch state. Touch state needs a DOWN event in order to later process MOVE
+            // events it'll receive if the object is dragged out of the magnetic field.
+            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+                mTouchState.onTouchEvent(ev);
+            }
+
+            // Continue tracking velocity when the object is in the magnetic field, since we want to
+            // respect touch input velocity if the object is dragged out and then flung.
+            mTouchState.addMovementToVelocityTracker(ev);
+
+            return true;
+        }
+
+        // Update the touch state
+        mTouchState.onTouchEvent(ev);
+
+        boolean shouldDeliverToMenu = mMenuState != MENU_STATE_NONE;
+
+        switch (ev.getAction()) {
+            case MotionEvent.ACTION_DOWN: {
+                mGesture.onDown(mTouchState);
+                break;
+            }
+            case MotionEvent.ACTION_MOVE: {
+                if (mGesture.onMove(mTouchState)) {
+                    break;
+                }
+
+                shouldDeliverToMenu = !mTouchState.isDragging();
+                break;
+            }
+            case MotionEvent.ACTION_UP: {
+                // Update the movement bounds again if the state has changed since the user started
+                // dragging (ie. when the IME shows)
+                updateMovementBounds();
+
+                if (mGesture.onUp(mTouchState)) {
+                    break;
+                }
+
+                // Fall through to clean up
+            }
+            case MotionEvent.ACTION_CANCEL: {
+                shouldDeliverToMenu = !mTouchState.startedDragging() && !mTouchState.isDragging();
+                mTouchState.reset();
+                break;
+            }
+            case MotionEvent.ACTION_HOVER_ENTER:
+                // If Touch Exploration is enabled, some a11y services (e.g. Talkback) is probably
+                // on and changing MotionEvents into HoverEvents.
+                // Let's not enable menu show/hide for a11y services.
+                if (!mAccessibilityManager.isTouchExplorationEnabled()) {
+                    mTouchState.removeHoverExitTimeoutCallback();
+                    mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
+                            false /* allowMenuTimeout */, false /* willResizeMenu */,
+                            shouldShowResizeHandle());
+                }
+            case MotionEvent.ACTION_HOVER_MOVE: {
+                if (!shouldDeliverToMenu && !mSendingHoverAccessibilityEvents) {
+                    sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_ENTER);
+                    mSendingHoverAccessibilityEvents = true;
+                }
+                break;
+            }
+            case MotionEvent.ACTION_HOVER_EXIT: {
+                // If Touch Exploration is enabled, some a11y services (e.g. Talkback) is probably
+                // on and changing MotionEvents into HoverEvents.
+                // Let's not enable menu show/hide for a11y services.
+                if (!mAccessibilityManager.isTouchExplorationEnabled()) {
+                    mTouchState.scheduleHoverExitTimeoutCallback();
+                }
+                if (!shouldDeliverToMenu && mSendingHoverAccessibilityEvents) {
+                    sendAccessibilityHoverEvent(AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+                    mSendingHoverAccessibilityEvents = false;
+                }
+                break;
+            }
+        }
+
+        // Deliver the event to PipMenuActivity to handle button click if the menu has shown.
+        if (shouldDeliverToMenu) {
+            final MotionEvent cloneEvent = MotionEvent.obtain(ev);
+            // Send the cancel event and cancel menu timeout if it starts to drag.
+            if (mTouchState.startedDragging()) {
+                cloneEvent.setAction(MotionEvent.ACTION_CANCEL);
+                mMenuController.pokeMenu();
+            }
+
+            mMenuController.handlePointerEvent(cloneEvent);
+        }
+
+        return true;
+    }
+
+    private void sendAccessibilityHoverEvent(int type) {
+        if (!mAccessibilityManager.isEnabled()) {
+            return;
+        }
+
+        AccessibilityEvent event = AccessibilityEvent.obtain(type);
+        event.setImportantForAccessibility(true);
+        event.setSourceNodeId(AccessibilityNodeInfo.ROOT_NODE_ID);
+        event.setWindowId(
+                AccessibilityWindowInfo.PICTURE_IN_PICTURE_ACTION_REPLACER_WINDOW_ID);
+        mAccessibilityManager.sendAccessibilityEvent(event);
+    }
+
+    /**
+     * Updates the appearance of the menu and scrim on top of the PiP while dismissing.
+     */
+    private void updateDismissFraction() {
+        if (mMenuController != null) {
+            Rect bounds = mMotionHelper.getBounds();
+            final float target = mInsetBounds.bottom;
+            float fraction = 0f;
+            if (bounds.bottom > target) {
+                final float distance = bounds.bottom - target;
+                fraction = Math.min(distance / bounds.height(), 1f);
+            }
+            if (Float.compare(fraction, 0f) != 0 || mMenuController.isMenuVisible()) {
+                // Update if the fraction > 0, or if fraction == 0 and the menu was already visible
+                mMenuController.setDismissFraction(fraction);
+            }
+        }
+    }
+
+    /**
+     * Sets the controller to update the system of changes from user interaction.
+     */
+    void setPinnedStackController(IPinnedStackController controller) {
+        mPinnedStackController = controller;
+    }
+
+    /**
+     * Sets the menu visibility.
+     */
+    private void setMenuState(int menuState, boolean resize, Runnable callback) {
+        if (mMenuState == menuState && !resize) {
+            return;
+        }
+
+        if (menuState == MENU_STATE_FULL && mMenuState != MENU_STATE_FULL) {
+            // Save the current snap fraction and if we do not drag or move the PiP, then
+            // we store back to this snap fraction.  Otherwise, we'll reset the snap
+            // fraction and snap to the closest edge.
+            if (resize) {
+                animateToExpandedState(callback);
+            }
+        } else if (menuState == MENU_STATE_NONE && mMenuState == MENU_STATE_FULL) {
+            // Try and restore the PiP to the closest edge, using the saved snap fraction
+            // if possible
+            if (resize) {
+                if (mDeferResizeToNormalBoundsUntilRotation == -1) {
+                    // This is a very special case: when the menu is expanded and visible,
+                    // navigating to another activity can trigger auto-enter PiP, and if the
+                    // revealed activity has a forced rotation set, then the controller will get
+                    // updated with the new rotation of the display. However, at the same time,
+                    // SystemUI will try to hide the menu by creating an animation to the normal
+                    // bounds which are now stale.  In such a case we defer the animation to the
+                    // normal bounds until after the next onMovementBoundsChanged() call to get the
+                    // bounds in the new orientation
+                    try {
+                        int displayRotation = mPinnedStackController.getDisplayRotation();
+                        if (mDisplayRotation != displayRotation) {
+                            mDeferResizeToNormalBoundsUntilRotation = displayRotation;
+                        }
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "Could not get display rotation from controller");
+                    }
+                }
+
+                if (mDeferResizeToNormalBoundsUntilRotation == -1) {
+                    animateToUnexpandedState(getUserResizeBounds());
+                }
+            } else {
+                mSavedSnapFraction = -1f;
+            }
+        }
+        mMenuState = menuState;
+        updateMovementBounds();
+        // If pip menu has dismissed, we should register the A11y ActionReplacingConnection for pip
+        // as well, or it can't handle a11y focus and pip menu can't perform any action.
+        onRegistrationChanged(menuState == MENU_STATE_NONE);
+        if (menuState == MENU_STATE_NONE) {
+            mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_HIDE_MENU);
+        } else if (menuState == MENU_STATE_FULL) {
+            mPipUiEventLogger.log(PipUiEventLogger.PipUiEventEnum.PICTURE_IN_PICTURE_SHOW_MENU);
+        }
+    }
+
+    private void animateToExpandedState(Runnable callback) {
+        Rect expandedBounds = new Rect(mExpandedBounds);
+        mSavedSnapFraction = mMotionHelper.animateToExpandedState(expandedBounds,
+                mMovementBounds, mExpandedMovementBounds, callback);
+    }
+
+    private void animateToUnexpandedState(Rect restoreBounds) {
+        Rect restoredMovementBounds = new Rect();
+        mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(restoreBounds,
+                mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0);
+        mMotionHelper.animateToUnexpandedState(restoreBounds, mSavedSnapFraction,
+                restoredMovementBounds, mMovementBounds, false /* immediate */);
+        mSavedSnapFraction = -1f;
+    }
+
+    /**
+     * @return the motion helper.
+     */
+    public PipMotionHelper getMotionHelper() {
+        return mMotionHelper;
+    }
+
+    @VisibleForTesting
+    public PipResizeGestureHandler getPipResizeGestureHandler() {
+        return mPipResizeGestureHandler;
+    }
+
+    @VisibleForTesting
+    public void setPipResizeGestureHandler(PipResizeGestureHandler pipResizeGestureHandler) {
+        mPipResizeGestureHandler = pipResizeGestureHandler;
+    }
+
+    @VisibleForTesting
+    public void setPipMotionHelper(PipMotionHelper pipMotionHelper) {
+        mMotionHelper = pipMotionHelper;
+    }
+
+    /**
+     * @return the unexpanded bounds.
+     */
+    public Rect getNormalBounds() {
+        return mNormalBounds;
+    }
+
+    Rect getUserResizeBounds() {
+        return mPipResizeGestureHandler.getUserResizeBounds();
+    }
+
+    /**
+     * Gesture controlling normal movement of the PIP.
+     */
+    private class DefaultPipTouchGesture extends PipTouchGesture {
+        private final Point mStartPosition = new Point();
+        private final PointF mDelta = new PointF();
+        private boolean mShouldHideMenuAfterFling;
+
+        @Override
+        public void onDown(PipTouchState touchState) {
+            if (!touchState.isUserInteracting()) {
+                return;
+            }
+
+            Rect bounds = mMotionHelper.getPossiblyAnimatingBounds();
+            mDelta.set(0f, 0f);
+            mStartPosition.set(bounds.left, bounds.top);
+            mMovementWithinDismiss = touchState.getDownTouchPosition().y >= mMovementBounds.bottom;
+            mMotionHelper.setSpringingToTouch(false);
+
+            // If the menu is still visible then just poke the menu
+            // so that it will timeout after the user stops touching it
+            if (mMenuState != MENU_STATE_NONE) {
+                mMenuController.pokeMenu();
+            }
+        }
+
+        @Override
+        public boolean onMove(PipTouchState touchState) {
+            if (!touchState.isUserInteracting()) {
+                return false;
+            }
+
+            if (touchState.startedDragging()) {
+                mSavedSnapFraction = -1f;
+
+                if (mEnableDismissDragToEdge) {
+                    if (mTargetViewContainer.getVisibility() != View.VISIBLE) {
+                        mHandler.removeCallbacks(mShowTargetAction);
+                        showDismissTargetMaybe();
+                    }
+                }
+            }
+
+            if (touchState.isDragging()) {
+                // Move the pinned stack freely
+                final PointF lastDelta = touchState.getLastTouchDelta();
+                float lastX = mStartPosition.x + mDelta.x;
+                float lastY = mStartPosition.y + mDelta.y;
+                float left = lastX + lastDelta.x;
+                float top = lastY + lastDelta.y;
+
+                // Add to the cumulative delta after bounding the position
+                mDelta.x += left - lastX;
+                mDelta.y += top - lastY;
+
+                mTmpBounds.set(mMotionHelper.getPossiblyAnimatingBounds());
+                mTmpBounds.offsetTo((int) left, (int) top);
+                mMotionHelper.movePip(mTmpBounds, true /* isDragging */);
+
+                final PointF curPos = touchState.getLastTouchPosition();
+                if (mMovementWithinDismiss) {
+                    // Track if movement remains near the bottom edge to identify swipe to dismiss
+                    mMovementWithinDismiss = curPos.y >= mMovementBounds.bottom;
+                }
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public boolean onUp(PipTouchState touchState) {
+            if (mEnableDismissDragToEdge) {
+                hideDismissTarget();
+            }
+
+            if (!touchState.isUserInteracting()) {
+                return false;
+            }
+
+            final PointF vel = touchState.getVelocity();
+
+            if (touchState.isDragging()) {
+                if (mMenuState != MENU_STATE_NONE) {
+                    // If the menu is still visible, then just poke the menu so that
+                    // it will timeout after the user stops touching it
+                    mMenuController.showMenu(mMenuState, mMotionHelper.getBounds(),
+                            true /* allowMenuTimeout */, willResizeMenu(),
+                            shouldShowResizeHandle());
+                }
+                mShouldHideMenuAfterFling = mMenuState == MENU_STATE_NONE;
+
+                // Reset the touch state on up before the fling settles
+                mTouchState.reset();
+                final Rect animatingBounds = mMotionHelper.getPossiblyAnimatingBounds();
+                // If User releases the PIP window while it's out of the display bounds, put
+                // PIP into stashed mode.
+                if (mEnableStash
+                        && (animatingBounds.right > mPipBoundsHandler.getDisplayBounds().right
+                        || animatingBounds.left < mPipBoundsHandler.getDisplayBounds().left)) {
+                    mMotionHelper.stashToEdge(vel.x, vel.y,
+                            PipTouchHandler.this::updateDismissFraction /* updateAction */,
+                            this::flingEndAction /* endAction */);
+                } else {
+                    mMotionHelper.flingToSnapTarget(vel.x, vel.y,
+                            PipTouchHandler.this::updateDismissFraction /* updateAction */,
+                            this::flingEndAction /* endAction */);
+                }
+            } else if (mTouchState.isDoubleTap()) {
+                // If using pinch to zoom, double-tap functions as resizing between max/min size
+                if (mPipResizeGestureHandler.isUsingPinchToZoom()) {
+                    final boolean toExpand =
+                            mMotionHelper.getBounds().width() < mExpandedBounds.width()
+                            && mMotionHelper.getBounds().height() < mExpandedBounds.height();
+                    mPipResizeGestureHandler.setUserResizeBounds(toExpand ? mExpandedBounds
+                            : mNormalBounds);
+                    if (toExpand) {
+                        animateToExpandedState(null);
+                    } else {
+                        animateToUnexpandedState(mNormalBounds);
+                    }
+                } else {
+                    // Expand to fullscreen if this is a double tap
+                    // the PiP should be frozen until the transition ends
+                    setTouchEnabled(false);
+                    mMotionHelper.expandLeavePip();
+                }
+            } else if (mMenuState != MENU_STATE_FULL) {
+                if (!mTouchState.isWaitingForDoubleTap()) {
+                    // User has stalled long enough for this not to be a drag or a double tap, just
+                    // expand the menu
+                    mMenuController.showMenu(MENU_STATE_FULL, mMotionHelper.getBounds(),
+                            true /* allowMenuTimeout */, willResizeMenu(),
+                            shouldShowResizeHandle());
+                } else {
+                    // Next touch event _may_ be the second tap for the double-tap, schedule a
+                    // fallback runnable to trigger the menu if no touch event occurs before the
+                    // next tap
+                    mTouchState.scheduleDoubleTapTimeoutCallback();
+                }
+            }
+            return true;
+        }
+
+        private void flingEndAction() {
+            if (mShouldHideMenuAfterFling) {
+                // If the menu is not visible, then we can still be showing the activity for the
+                // dismiss overlay, so just finish it after the animation completes
+                mMenuController.hideMenu();
+            }
+        }
+    }
+
+    /**
+     * Updates the current movement bounds based on whether the menu is currently visible and
+     * resized.
+     */
+    private void updateMovementBounds() {
+        mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(mMotionHelper.getBounds(),
+                mInsetBounds, mMovementBounds, mIsImeShowing ? mImeHeight : 0);
+        mMotionHelper.setCurrentMovementBounds(mMovementBounds);
+
+        boolean isMenuExpanded = mMenuState == MENU_STATE_FULL;
+        mPipBoundsHandler.setMinEdgeSize(
+                isMenuExpanded && willResizeMenu() ? mExpandedShortestEdgeSize : 0);
+    }
+
+    private Rect getMovementBounds(Rect curBounds) {
+        Rect movementBounds = new Rect();
+        mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(curBounds, mInsetBounds,
+                movementBounds, mIsImeShowing ? mImeHeight : 0);
+        return movementBounds;
+    }
+
+    /**
+     * @return whether the menu will resize as a part of showing the full menu.
+     */
+    private boolean willResizeMenu() {
+        if (!mEnableResize) {
+            return false;
+        }
+        return mExpandedBounds.width() != mNormalBounds.width()
+                || mExpandedBounds.height() != mNormalBounds.height();
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mMovementBounds=" + mMovementBounds);
+        pw.println(innerPrefix + "mNormalBounds=" + mNormalBounds);
+        pw.println(innerPrefix + "mNormalMovementBounds=" + mNormalMovementBounds);
+        pw.println(innerPrefix + "mExpandedBounds=" + mExpandedBounds);
+        pw.println(innerPrefix + "mExpandedMovementBounds=" + mExpandedMovementBounds);
+        pw.println(innerPrefix + "mMenuState=" + mMenuState);
+        pw.println(innerPrefix + "mIsImeShowing=" + mIsImeShowing);
+        pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
+        pw.println(innerPrefix + "mIsShelfShowing=" + mIsShelfShowing);
+        pw.println(innerPrefix + "mShelfHeight=" + mShelfHeight);
+        pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction);
+        pw.println(innerPrefix + "mEnableDragToEdgeDismiss=" + mEnableDismissDragToEdge);
+        pw.println(innerPrefix + "mMovementBoundsExtraOffsets=" + mMovementBoundsExtraOffsets);
+        mPipBoundsHandler.dump(pw, innerPrefix);
+        mTouchState.dump(pw, innerPrefix);
+        mMotionHelper.dump(pw, innerPrefix);
+        if (mPipResizeGestureHandler != null) {
+            mPipResizeGestureHandler.dump(pw, innerPrefix);
+        }
+    }
+
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
new file mode 100644
index 0000000..21715077
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchState.java
@@ -0,0 +1,391 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import android.graphics.PointF;
+import android.os.Handler;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.ViewConfiguration;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+
+/**
+ * This keeps track of the touch state throughout the current touch gesture.
+ */
+public class PipTouchState {
+    private static final String TAG = "PipTouchState";
+    private static final boolean DEBUG = false;
+
+    @VisibleForTesting
+    public static final long DOUBLE_TAP_TIMEOUT = 200;
+    static final long HOVER_EXIT_TIMEOUT = 50;
+
+    private final Handler mHandler;
+    private final ViewConfiguration mViewConfig;
+    private final Runnable mDoubleTapTimeoutCallback;
+    private final Runnable mHoverExitTimeoutCallback;
+
+    private VelocityTracker mVelocityTracker;
+    private long mDownTouchTime = 0;
+    private long mLastDownTouchTime = 0;
+    private long mUpTouchTime = 0;
+    private final PointF mDownTouch = new PointF();
+    private final PointF mDownDelta = new PointF();
+    private final PointF mLastTouch = new PointF();
+    private final PointF mLastDelta = new PointF();
+    private final PointF mVelocity = new PointF();
+    private boolean mAllowTouches = true;
+    private boolean mIsUserInteracting = false;
+    // Set to true only if the multiple taps occur within the double tap timeout
+    private boolean mIsDoubleTap = false;
+    // Set to true only if a gesture
+    private boolean mIsWaitingForDoubleTap = false;
+    private boolean mIsDragging = false;
+    // The previous gesture was a drag
+    private boolean mPreviouslyDragging = false;
+    private boolean mStartedDragging = false;
+    private boolean mAllowDraggingOffscreen = false;
+    private int mActivePointerId;
+
+    public PipTouchState(ViewConfiguration viewConfig, Handler handler,
+            Runnable doubleTapTimeoutCallback, Runnable hoverExitTimeoutCallback) {
+        mViewConfig = viewConfig;
+        mHandler = handler;
+        mDoubleTapTimeoutCallback = doubleTapTimeoutCallback;
+        mHoverExitTimeoutCallback = hoverExitTimeoutCallback;
+    }
+
+    /**
+     * Resets this state.
+     */
+    public void reset() {
+        mAllowDraggingOffscreen = false;
+        mIsDragging = false;
+        mStartedDragging = false;
+        mIsUserInteracting = false;
+    }
+
+    /**
+     * Processes a given touch event and updates the state.
+     */
+    public void onTouchEvent(MotionEvent ev) {
+        switch (ev.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN: {
+                if (!mAllowTouches) {
+                    return;
+                }
+
+                // Initialize the velocity tracker
+                initOrResetVelocityTracker();
+                addMovementToVelocityTracker(ev);
+
+                mActivePointerId = ev.getPointerId(0);
+                if (DEBUG) {
+                    Log.e(TAG, "Setting active pointer id on DOWN: " + mActivePointerId);
+                }
+                mLastTouch.set(ev.getRawX(), ev.getRawY());
+                mDownTouch.set(mLastTouch);
+                mAllowDraggingOffscreen = true;
+                mIsUserInteracting = true;
+                mDownTouchTime = ev.getEventTime();
+                mIsDoubleTap = !mPreviouslyDragging
+                        && (mDownTouchTime - mLastDownTouchTime) < DOUBLE_TAP_TIMEOUT;
+                mIsWaitingForDoubleTap = false;
+                mIsDragging = false;
+                mLastDownTouchTime = mDownTouchTime;
+                if (mDoubleTapTimeoutCallback != null) {
+                    mHandler.removeCallbacks(mDoubleTapTimeoutCallback);
+                }
+                break;
+            }
+            case MotionEvent.ACTION_MOVE: {
+                // Skip event if we did not start processing this touch gesture
+                if (!mIsUserInteracting) {
+                    break;
+                }
+
+                // Update the velocity tracker
+                addMovementToVelocityTracker(ev);
+                int pointerIndex = ev.findPointerIndex(mActivePointerId);
+                if (pointerIndex == -1) {
+                    Log.e(TAG, "Invalid active pointer id on MOVE: " + mActivePointerId);
+                    break;
+                }
+
+                float x = ev.getRawX(pointerIndex);
+                float y = ev.getRawY(pointerIndex);
+                mLastDelta.set(x - mLastTouch.x, y - mLastTouch.y);
+                mDownDelta.set(x - mDownTouch.x, y - mDownTouch.y);
+
+                boolean hasMovedBeyondTap = mDownDelta.length() > mViewConfig.getScaledTouchSlop();
+                if (!mIsDragging) {
+                    if (hasMovedBeyondTap) {
+                        mIsDragging = true;
+                        mStartedDragging = true;
+                    }
+                } else {
+                    mStartedDragging = false;
+                }
+                mLastTouch.set(x, y);
+                break;
+            }
+            case MotionEvent.ACTION_POINTER_UP: {
+                // Skip event if we did not start processing this touch gesture
+                if (!mIsUserInteracting) {
+                    break;
+                }
+
+                // Update the velocity tracker
+                addMovementToVelocityTracker(ev);
+
+                int pointerIndex = ev.getActionIndex();
+                int pointerId = ev.getPointerId(pointerIndex);
+                if (pointerId == mActivePointerId) {
+                    // Select a new active pointer id and reset the movement state
+                    final int newPointerIndex = (pointerIndex == 0) ? 1 : 0;
+                    mActivePointerId = ev.getPointerId(newPointerIndex);
+                    if (DEBUG) {
+                        Log.e(TAG,
+                                "Relinquish active pointer id on POINTER_UP: " + mActivePointerId);
+                    }
+                    mLastTouch.set(ev.getRawX(newPointerIndex), ev.getRawY(newPointerIndex));
+                }
+                break;
+            }
+            case MotionEvent.ACTION_UP: {
+                // Skip event if we did not start processing this touch gesture
+                if (!mIsUserInteracting) {
+                    break;
+                }
+
+                // Update the velocity tracker
+                addMovementToVelocityTracker(ev);
+                mVelocityTracker.computeCurrentVelocity(1000,
+                        mViewConfig.getScaledMaximumFlingVelocity());
+                mVelocity.set(mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity());
+
+                int pointerIndex = ev.findPointerIndex(mActivePointerId);
+                if (pointerIndex == -1) {
+                    Log.e(TAG, "Invalid active pointer id on UP: " + mActivePointerId);
+                    break;
+                }
+
+                mUpTouchTime = ev.getEventTime();
+                mLastTouch.set(ev.getRawX(pointerIndex), ev.getRawY(pointerIndex));
+                mPreviouslyDragging = mIsDragging;
+                mIsWaitingForDoubleTap = !mIsDoubleTap && !mIsDragging
+                        && (mUpTouchTime - mDownTouchTime) < DOUBLE_TAP_TIMEOUT;
+
+                // Fall through to clean up
+            }
+            case MotionEvent.ACTION_CANCEL: {
+                recycleVelocityTracker();
+                break;
+            }
+            case MotionEvent.ACTION_BUTTON_PRESS: {
+                removeHoverExitTimeoutCallback();
+                break;
+            }
+        }
+    }
+
+    /**
+     * @return the velocity of the active touch pointer at the point it is lifted off the screen.
+     */
+    public PointF getVelocity() {
+        return mVelocity;
+    }
+
+    /**
+     * @return the last touch position of the active pointer.
+     */
+    public PointF getLastTouchPosition() {
+        return mLastTouch;
+    }
+
+    /**
+     * @return the movement delta between the last handled touch event and the previous touch
+     * position.
+     */
+    public PointF getLastTouchDelta() {
+        return mLastDelta;
+    }
+
+    /**
+     * @return the down touch position.
+     */
+    public PointF getDownTouchPosition() {
+        return mDownTouch;
+    }
+
+    /**
+     * @return the movement delta between the last handled touch event and the down touch
+     * position.
+     */
+    public PointF getDownTouchDelta() {
+        return mDownDelta;
+    }
+
+    /**
+     * @return whether the user has started dragging.
+     */
+    public boolean isDragging() {
+        return mIsDragging;
+    }
+
+    /**
+     * @return whether the user is currently interacting with the PiP.
+     */
+    public boolean isUserInteracting() {
+        return mIsUserInteracting;
+    }
+
+    /**
+     * @return whether the user has started dragging just in the last handled touch event.
+     */
+    public boolean startedDragging() {
+        return mStartedDragging;
+    }
+
+    /**
+     * Sets whether touching is currently allowed.
+     */
+    public void setAllowTouches(boolean allowTouches) {
+        mAllowTouches = allowTouches;
+
+        // If the user happens to touch down before this is sent from the system during a transition
+        // then block any additional handling by resetting the state now
+        if (mIsUserInteracting) {
+            reset();
+        }
+    }
+
+    /**
+     * Disallows dragging offscreen for the duration of the current gesture.
+     */
+    public void setDisallowDraggingOffscreen() {
+        mAllowDraggingOffscreen = false;
+    }
+
+    /**
+     * @return whether dragging offscreen is allowed during this gesture.
+     */
+    public boolean allowDraggingOffscreen() {
+        return mAllowDraggingOffscreen;
+    }
+
+    /**
+     * @return whether this gesture is a double-tap.
+     */
+    public boolean isDoubleTap() {
+        return mIsDoubleTap;
+    }
+
+    /**
+     * @return whether this gesture will potentially lead to a following double-tap.
+     */
+    public boolean isWaitingForDoubleTap() {
+        return mIsWaitingForDoubleTap;
+    }
+
+    /**
+     * Schedules the callback to run if the next double tap does not occur.  Only runs if
+     * isWaitingForDoubleTap() is true.
+     */
+    public void scheduleDoubleTapTimeoutCallback() {
+        if (mIsWaitingForDoubleTap) {
+            long delay = getDoubleTapTimeoutCallbackDelay();
+            mHandler.removeCallbacks(mDoubleTapTimeoutCallback);
+            mHandler.postDelayed(mDoubleTapTimeoutCallback, delay);
+        }
+    }
+
+    @VisibleForTesting
+    public long getDoubleTapTimeoutCallbackDelay() {
+        if (mIsWaitingForDoubleTap) {
+            return Math.max(0, DOUBLE_TAP_TIMEOUT - (mUpTouchTime - mDownTouchTime));
+        }
+        return -1;
+    }
+
+    /**
+     * Removes the timeout callback if it's in queue.
+     */
+    public void removeDoubleTapTimeoutCallback() {
+        mIsWaitingForDoubleTap = false;
+        mHandler.removeCallbacks(mDoubleTapTimeoutCallback);
+    }
+
+    @VisibleForTesting
+    public void scheduleHoverExitTimeoutCallback() {
+        mHandler.removeCallbacks(mHoverExitTimeoutCallback);
+        mHandler.postDelayed(mHoverExitTimeoutCallback, HOVER_EXIT_TIMEOUT);
+    }
+
+    void removeHoverExitTimeoutCallback() {
+        mHandler.removeCallbacks(mHoverExitTimeoutCallback);
+    }
+
+    void addMovementToVelocityTracker(MotionEvent event) {
+        if (mVelocityTracker == null) {
+            return;
+        }
+
+        // Add movement to velocity tracker using raw screen X and Y coordinates instead
+        // of window coordinates because the window frame may be moving at the same time.
+        float deltaX = event.getRawX() - event.getX();
+        float deltaY = event.getRawY() - event.getY();
+        event.offsetLocation(deltaX, deltaY);
+        mVelocityTracker.addMovement(event);
+        event.offsetLocation(-deltaX, -deltaY);
+    }
+
+    private void initOrResetVelocityTracker() {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        } else {
+            mVelocityTracker.clear();
+        }
+    }
+
+    private void recycleVelocityTracker() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+    }
+
+    public void dump(PrintWriter pw, String prefix) {
+        final String innerPrefix = prefix + "  ";
+        pw.println(prefix + TAG);
+        pw.println(innerPrefix + "mAllowTouches=" + mAllowTouches);
+        pw.println(innerPrefix + "mActivePointerId=" + mActivePointerId);
+        pw.println(innerPrefix + "mDownTouch=" + mDownTouch);
+        pw.println(innerPrefix + "mDownDelta=" + mDownDelta);
+        pw.println(innerPrefix + "mLastTouch=" + mLastTouch);
+        pw.println(innerPrefix + "mLastDelta=" + mLastDelta);
+        pw.println(innerPrefix + "mVelocity=" + mVelocity);
+        pw.println(innerPrefix + "mIsUserInteracting=" + mIsUserInteracting);
+        pw.println(innerPrefix + "mIsDragging=" + mIsDragging);
+        pw.println(innerPrefix + "mStartedDragging=" + mStartedDragging);
+        pw.println(innerPrefix + "mAllowDraggingOffscreen=" + mAllowDraggingOffscreen);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipUpdateThread.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipUpdateThread.java
new file mode 100644
index 0000000..d686cac
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipUpdateThread.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+
+/**
+ * Similar to {@link com.android.internal.os.BackgroundThread}, this is a shared singleton
+ * foreground thread for each process for updating PIP.
+ */
+public final class PipUpdateThread extends HandlerThread {
+    private static PipUpdateThread sInstance;
+    private static Handler sHandler;
+
+    private PipUpdateThread() {
+        super("pip");
+    }
+
+    private static void ensureThreadLocked() {
+        if (sInstance == null) {
+            sInstance = new PipUpdateThread();
+            sInstance.start();
+            sHandler = new Handler(sInstance.getLooper());
+        }
+    }
+
+    /**
+     * @return the static update thread instance
+     */
+    public static PipUpdateThread get() {
+        synchronized (PipUpdateThread.class) {
+            ensureThreadLocked();
+            return sInstance;
+        }
+    }
+    /**
+     * @return the static update thread handler instance
+     */
+    public static Handler getHandler() {
+        synchronized (PipUpdateThread.class) {
+            ensureThreadLocked();
+            return sHandler;
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipUtils.java
new file mode 100644
index 0000000..6a58ce0
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipUtils.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.phone;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+
+import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
+import android.app.IActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Pair;
+
+public class PipUtils {
+
+    private static final String TAG = "PipUtils";
+
+    /**
+     * @return the ComponentName and user id of the top non-SystemUI activity in the pinned stack.
+     * The component name may be null if no such activity exists.
+     */
+    public static Pair<ComponentName, Integer> getTopPipActivity(Context context,
+            IActivityManager activityManager) {
+        try {
+            final String sysUiPackageName = context.getPackageName();
+            final RootTaskInfo pinnedTaskInfo = ActivityTaskManager.getService().getRootTaskInfo(
+                    WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+            if (pinnedTaskInfo != null && pinnedTaskInfo.childTaskIds != null
+                    && pinnedTaskInfo.childTaskIds.length > 0) {
+                for (int i = pinnedTaskInfo.childTaskNames.length - 1; i >= 0; i--) {
+                    ComponentName cn = ComponentName.unflattenFromString(
+                            pinnedTaskInfo.childTaskNames[i]);
+                    if (cn != null && !cn.getPackageName().equals(sysUiPackageName)) {
+                        return new Pair<>(cn, pinnedTaskInfo.childTaskUserIds[i]);
+                    }
+                }
+            }
+        } catch (RemoteException e) {
+            Log.w(TAG, "Unable to get pinned stack.");
+        }
+        return new Pair<>(null, 0);
+    }
+
+    /**
+     * The util to check if device has PIP feature
+     *
+     * @param context application context
+     * @return true if device has PIP feature, false otherwise.
+     */
+    public static boolean hasSystemFeature(Context context) {
+        return context.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlButtonView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlButtonView.java
new file mode 100644
index 0000000..4e82bb5
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlButtonView.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.tv;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.android.wm.shell.R;
+
+/**
+ * A view containing PIP controls including fullscreen, close, and media controls.
+ */
+public class PipControlButtonView extends RelativeLayout {
+
+    private OnFocusChangeListener mFocusChangeListener;
+    private ImageView mIconImageView;
+    ImageView mButtonImageView;
+    private TextView mDescriptionTextView;
+    private Animator mTextFocusGainAnimator;
+    private Animator mButtonFocusGainAnimator;
+    private Animator mTextFocusLossAnimator;
+    private Animator mButtonFocusLossAnimator;
+
+    private final OnFocusChangeListener mInternalFocusChangeListener =
+            new OnFocusChangeListener() {
+                @Override
+                public void onFocusChange(View v, boolean hasFocus) {
+                    if (hasFocus) {
+                        startFocusGainAnimation();
+                    } else {
+                        startFocusLossAnimation();
+                    }
+
+                    if (mFocusChangeListener != null) {
+                        mFocusChangeListener.onFocusChange(PipControlButtonView.this, hasFocus);
+                    }
+                }
+            };
+
+    public PipControlButtonView(Context context) {
+        this(context, null, 0, 0);
+    }
+
+    public PipControlButtonView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0, 0);
+    }
+
+    public PipControlButtonView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public PipControlButtonView(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        LayoutInflater inflater = (LayoutInflater) getContext()
+                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        inflater.inflate(R.layout.tv_pip_control_button, this);
+
+        mIconImageView = findViewById(R.id.icon);
+        mButtonImageView = findViewById(R.id.button);
+        mDescriptionTextView = findViewById(R.id.desc);
+
+        int[] values = new int[]{android.R.attr.src, android.R.attr.text};
+        TypedArray typedArray = context.obtainStyledAttributes(attrs, values, defStyleAttr,
+                defStyleRes);
+
+        setImageResource(typedArray.getResourceId(0, 0));
+        setText(typedArray.getResourceId(1, 0));
+
+        typedArray.recycle();
+    }
+
+    @Override
+    public void onFinishInflate() {
+        super.onFinishInflate();
+        mButtonImageView.setOnFocusChangeListener(mInternalFocusChangeListener);
+
+        mTextFocusGainAnimator = AnimatorInflater.loadAnimator(getContext(),
+                R.anim.tv_pip_controls_focus_gain_animation);
+        mTextFocusGainAnimator.setTarget(mDescriptionTextView);
+        mButtonFocusGainAnimator = AnimatorInflater.loadAnimator(getContext(),
+                R.anim.tv_pip_controls_focus_gain_animation);
+        mButtonFocusGainAnimator.setTarget(mButtonImageView);
+
+        mTextFocusLossAnimator = AnimatorInflater.loadAnimator(getContext(),
+                R.anim.tv_pip_controls_focus_loss_animation);
+        mTextFocusLossAnimator.setTarget(mDescriptionTextView);
+        mButtonFocusLossAnimator = AnimatorInflater.loadAnimator(getContext(),
+                R.anim.tv_pip_controls_focus_loss_animation);
+        mButtonFocusLossAnimator.setTarget(mButtonImageView);
+    }
+
+    @Override
+    public void setOnClickListener(OnClickListener listener) {
+        mButtonImageView.setOnClickListener(listener);
+    }
+
+    @Override
+    public void setOnFocusChangeListener(OnFocusChangeListener listener) {
+        mFocusChangeListener = listener;
+    }
+
+    /**
+     * Sets the drawable for the button with the given drawable.
+     */
+    public void setImageDrawable(Drawable d) {
+        mIconImageView.setImageDrawable(d);
+    }
+
+    /**
+     * Sets the drawable for the button with the given resource id.
+     */
+    public void setImageResource(int resId) {
+        if (resId != 0) {
+            mIconImageView.setImageResource(resId);
+        }
+    }
+
+    /**
+     * Sets the text for description the with the given string.
+     */
+    public void setText(CharSequence text) {
+        mButtonImageView.setContentDescription(text);
+        mDescriptionTextView.setText(text);
+    }
+
+    /**
+     * Sets the text for description the with the given resource id.
+     */
+    public void setText(int resId) {
+        if (resId != 0) {
+            mButtonImageView.setContentDescription(getContext().getString(resId));
+            mDescriptionTextView.setText(resId);
+        }
+    }
+
+    private static void cancelAnimator(Animator animator) {
+        if (animator.isStarted()) {
+            animator.cancel();
+        }
+    }
+
+    /**
+     * Starts the focus gain animation.
+     */
+    public void startFocusGainAnimation() {
+        cancelAnimator(mButtonFocusLossAnimator);
+        cancelAnimator(mTextFocusLossAnimator);
+        mTextFocusGainAnimator.start();
+        if (mButtonImageView.getAlpha() < 1f) {
+            // If we had faded out the ripple drawable, run our manual focus change animation.
+            // See the comment at {@link #startFocusLossAnimation()} for the reason of manual
+            // animator.
+            mButtonFocusGainAnimator.start();
+        }
+    }
+
+    /**
+     * Starts the focus loss animation.
+     */
+    public void startFocusLossAnimation() {
+        cancelAnimator(mButtonFocusGainAnimator);
+        cancelAnimator(mTextFocusGainAnimator);
+        mTextFocusLossAnimator.start();
+        if (mButtonImageView.hasFocus()) {
+            // Button uses ripple that has the default animation for the focus changes.
+            // Howevever, it doesn't expose the API to fade out while it is focused,
+            // so we should manually run the fade out animation when PIP controls row loses focus.
+            mButtonFocusLossAnimator.start();
+        }
+    }
+
+    /**
+     * Resets to initial state.
+     */
+    public void reset() {
+        cancelAnimator(mButtonFocusGainAnimator);
+        cancelAnimator(mTextFocusGainAnimator);
+        cancelAnimator(mButtonFocusLossAnimator);
+        cancelAnimator(mTextFocusLossAnimator);
+        mButtonImageView.setAlpha(1f);
+        mDescriptionTextView.setAlpha(mButtonImageView.hasFocus() ? 1f : 0f);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
new file mode 100644
index 0000000..3eec20f
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipController.java
@@ -0,0 +1,733 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.tv;
+
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
+
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.ActivityTaskManager.RootTaskInfo;
+import android.app.IActivityTaskManager;
+import android.app.RemoteAction;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ParceledListSlice;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.media.session.MediaController;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
+import android.os.Debug;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.DisplayInfo;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.pip.PinnedStackListenerForwarder;
+import com.android.wm.shell.pip.Pip;
+import com.android.wm.shell.pip.PipBoundsHandler;
+import com.android.wm.shell.pip.PipTaskOrganizer;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Manages the picture-in-picture (PIP) UI and states.
+ */
+public class PipController implements Pip, PipTaskOrganizer.PipTransitionCallback {
+    private static final String TAG = "PipController";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    /**
+     * Unknown or invalid state
+     */
+    public static final int STATE_UNKNOWN = -1;
+    /**
+     * State when there's no PIP.
+     */
+    public static final int STATE_NO_PIP = 0;
+    /**
+     * State when PIP is shown. This is used as default PIP state.
+     */
+    public static final int STATE_PIP = 1;
+    /**
+     * State when PIP menu dialog is shown.
+     */
+    public static final int STATE_PIP_MENU = 2;
+
+    private static final int TASK_ID_NO_PIP = -1;
+    private static final int INVALID_RESOURCE_TYPE = -1;
+
+    public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH = 0x1;
+
+    /**
+     * PIPed activity is playing a media and it can be paused.
+     */
+    static final int PLAYBACK_STATE_PLAYING = 0;
+    /**
+     * PIPed activity has a paused media and it can be played.
+     */
+    static final int PLAYBACK_STATE_PAUSED = 1;
+    /**
+     * Users are unable to control PIPed activity's media playback.
+     */
+    static final int PLAYBACK_STATE_UNAVAILABLE = 2;
+
+    private static final int CLOSE_PIP_WHEN_MEDIA_SESSION_GONE_TIMEOUT_MS = 3000;
+
+    private int mSuspendPipResizingReason;
+
+    private Context mContext;
+    private PipBoundsHandler mPipBoundsHandler;
+    private PipTaskOrganizer mPipTaskOrganizer;
+    private IActivityTaskManager mActivityTaskManager;
+    private MediaSessionManager mMediaSessionManager;
+    private int mState = STATE_NO_PIP;
+    private int mResumeResizePinnedStackRunnableState = STATE_NO_PIP;
+    private final Handler mHandler = new Handler();
+    private List<Listener> mListeners = new ArrayList<>();
+    private List<MediaListener> mMediaListeners = new ArrayList<>();
+    private Rect mPipBounds;
+    private Rect mDefaultPipBounds = new Rect();
+    private Rect mMenuModePipBounds;
+    private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED;
+    private boolean mInitialized;
+    private int mPipTaskId = TASK_ID_NO_PIP;
+    private int mPinnedStackId = INVALID_STACK_ID;
+    private ComponentName mPipComponentName;
+    private MediaController mPipMediaController;
+    private String[] mLastPackagesResourceGranted;
+    private PipNotification mPipNotification;
+    private ParceledListSlice<RemoteAction> mCustomActions;
+    private WindowManagerShellWrapper mWindowManagerShellWrapper;
+    private int mResizeAnimationDuration;
+
+    // Used to calculate the movement bounds
+    private final DisplayInfo mTmpDisplayInfo = new DisplayInfo();
+    private final Rect mTmpInsetBounds = new Rect();
+
+    // Keeps track of the IME visibility to adjust the PiP when the IME is visible
+    private boolean mImeVisible;
+    private int mImeHeightAdjustment;
+
+    private final Runnable mResizePinnedStackRunnable =
+            () -> resizePinnedStack(mResumeResizePinnedStackRunnableState);
+    private final Runnable mClosePipRunnable = () -> closePip();
+    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_MEDIA_RESOURCE_GRANTED.equals(action)) {
+                String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
+                int resourceType = intent.getIntExtra(Intent.EXTRA_MEDIA_RESOURCE_TYPE,
+                        INVALID_RESOURCE_TYPE);
+                if (packageNames != null && packageNames.length > 0
+                        && resourceType == Intent.EXTRA_MEDIA_RESOURCE_TYPE_VIDEO_CODEC) {
+                    handleMediaResourceGranted(packageNames);
+                }
+            }
+
+        }
+    };
+    private final MediaSessionManager.OnActiveSessionsChangedListener mActiveMediaSessionListener =
+            controllers -> updateMediaController(controllers);
+    private final PinnedStackListenerForwarder.PinnedStackListener mPinnedStackListener =
+            new PipControllerPinnedStackListener();
+
+    @Override
+    public void registerSessionListenerForCurrentUser() {
+        // TODO Need confirm if TV have to re-registers when switch user
+        mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveMediaSessionListener);
+        mMediaSessionManager.addOnActiveSessionsChangedListener(mActiveMediaSessionListener, null,
+                UserHandle.USER_CURRENT, null);
+    }
+
+    /**
+     * Handler for messages from the PIP controller.
+     */
+    private class PipControllerPinnedStackListener extends
+            PinnedStackListenerForwarder.PinnedStackListener {
+        @Override
+        public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+            mHandler.post(() -> {
+                mPipBoundsHandler.onImeVisibilityChanged(imeVisible, imeHeight);
+                if (mState == STATE_PIP) {
+                    if (mImeVisible != imeVisible) {
+                        if (imeVisible) {
+                            // Save the IME height adjustment, and offset to not occlude the IME
+                            mPipBounds.offset(0, -imeHeight);
+                            mImeHeightAdjustment = imeHeight;
+                        } else {
+                            // Apply the inverse adjustment when the IME is hidden
+                            mPipBounds.offset(0, mImeHeightAdjustment);
+                        }
+                        mImeVisible = imeVisible;
+                        resizePinnedStack(STATE_PIP);
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void onMovementBoundsChanged(boolean fromImeAdjustment) {
+            mHandler.post(() -> {
+                // Populate the inset / normal bounds and DisplayInfo from mPipBoundsHandler first.
+                mPipBoundsHandler.onMovementBoundsChanged(mTmpInsetBounds, mPipBounds,
+                        mDefaultPipBounds, mTmpDisplayInfo);
+            });
+        }
+
+        @Override
+        public void onActionsChanged(ParceledListSlice<RemoteAction> actions) {
+            mCustomActions = actions;
+            mHandler.post(() -> {
+                for (int i = mListeners.size() - 1; i >= 0; --i) {
+                    mListeners.get(i).onPipMenuActionsChanged(mCustomActions);
+                }
+            });
+        }
+    }
+
+    public PipController(Context context,
+            PipBoundsHandler pipBoundsHandler,
+            PipTaskOrganizer pipTaskOrganizer,
+            WindowManagerShellWrapper windowManagerShellWrapper
+    ) {
+        if (!mInitialized) {
+            mInitialized = true;
+            mContext = context;
+            mPipNotification = new PipNotification(context, this);
+            mPipBoundsHandler = pipBoundsHandler;
+            // Ensure that we have the display info in case we get calls to update the bounds
+            // before the listener calls back
+            final DisplayInfo displayInfo = new DisplayInfo();
+            context.getDisplay().getDisplayInfo(displayInfo);
+            mPipBoundsHandler.onDisplayInfoChanged(displayInfo);
+
+            mResizeAnimationDuration = context.getResources()
+                    .getInteger(R.integer.config_pipResizeAnimationDuration);
+            mPipTaskOrganizer = pipTaskOrganizer;
+            mPipTaskOrganizer.registerPipTransitionCallback(this);
+            mActivityTaskManager = ActivityTaskManager.getService();
+            IntentFilter intentFilter = new IntentFilter();
+            intentFilter.addAction(Intent.ACTION_MEDIA_RESOURCE_GRANTED);
+            mContext.registerReceiver(mBroadcastReceiver, intentFilter, UserHandle.USER_ALL);
+
+            // Initialize the last orientation and apply the current configuration
+            Configuration initialConfig = mContext.getResources().getConfiguration();
+            mLastOrientation = initialConfig.orientation;
+            loadConfigurationsAndApply(initialConfig);
+
+            mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class);
+            mWindowManagerShellWrapper = windowManagerShellWrapper;
+            try {
+                mWindowManagerShellWrapper.addPinnedStackListener(mPinnedStackListener);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to register pinned stack listener", e);
+            }
+        }
+
+        // TODO(b/169395392) Refactor PipMenuActivity to PipMenuView
+        PipMenuActivity.setPipController(this);
+    }
+
+    private void loadConfigurationsAndApply(Configuration newConfig) {
+        if (mLastOrientation != newConfig.orientation) {
+            // Don't resize the pinned stack on orientation change. TV does not care about this case
+            // and this could clobber the existing animation to the new bounds calculated by WM.
+            mLastOrientation = newConfig.orientation;
+            return;
+        }
+
+        Resources res = mContext.getResources();
+        mMenuModePipBounds = Rect.unflattenFromString(res.getString(
+                R.string.pip_menu_bounds));
+
+        // Reset the PIP bounds and apply. PIP bounds can be changed by two reasons.
+        //   1. Configuration changed due to the language change (RTL <-> RTL)
+        //   2. SystemUI restarts after the crash
+        mPipBounds = mDefaultPipBounds;
+        resizePinnedStack(getPinnedTaskInfo() == null ? STATE_NO_PIP : STATE_PIP);
+    }
+
+    /**
+     * Updates the PIP per configuration changed.
+     */
+    public void onConfigurationChanged(Configuration newConfig) {
+        loadConfigurationsAndApply(newConfig);
+        mPipNotification.onConfigurationChanged(mContext);
+    }
+
+    /**
+     * Shows the picture-in-picture menu if an activity is in picture-in-picture mode.
+     */
+    public void showPictureInPictureMenu() {
+        if (DEBUG) Log.d(TAG, "showPictureInPictureMenu(), current state=" + getStateDescription());
+
+        if (getState() == STATE_PIP) {
+            resizePinnedStack(STATE_PIP_MENU);
+        }
+    }
+
+    /**
+     * Closes PIP (PIPed activity and PIP system UI).
+     */
+    public void closePip() {
+        if (DEBUG) Log.d(TAG, "closePip(), current state=" + getStateDescription());
+
+        closePipInternal(true);
+    }
+
+    private void closePipInternal(boolean removePipStack) {
+        if (DEBUG) {
+            Log.d(TAG,
+                    "closePipInternal() removePipStack=" + removePipStack + ", current state="
+                            + getStateDescription());
+        }
+
+        mState = STATE_NO_PIP;
+        mPipTaskId = TASK_ID_NO_PIP;
+        mPipMediaController = null;
+        mMediaSessionManager.removeOnActiveSessionsChangedListener(mActiveMediaSessionListener);
+        if (removePipStack) {
+            try {
+                mActivityTaskManager.removeStack(mPinnedStackId);
+            } catch (RemoteException e) {
+                Log.e(TAG, "removeStack failed", e);
+            } finally {
+                mPinnedStackId = INVALID_STACK_ID;
+            }
+        }
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onPipActivityClosed();
+        }
+        mHandler.removeCallbacks(mClosePipRunnable);
+    }
+
+    /**
+     * Moves the PIPed activity to the fullscreen and closes PIP system UI.
+     */
+    public void movePipToFullscreen() {
+        if (DEBUG) Log.d(TAG, "movePipToFullscreen(), current state=" + getStateDescription());
+
+        mPipTaskId = TASK_ID_NO_PIP;
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onMoveToFullscreen();
+        }
+        resizePinnedStack(STATE_NO_PIP);
+    }
+
+    @Override
+    public void onActivityPinned(String packageName) {
+        if (DEBUG) Log.d(TAG, "onActivityPinned()");
+
+        RootTaskInfo taskInfo = getPinnedTaskInfo();
+        if (taskInfo == null) {
+            Log.w(TAG, "Cannot find pinned stack");
+            return;
+        }
+        if (DEBUG) Log.d(TAG, "PINNED_STACK:" + taskInfo);
+        mPinnedStackId = taskInfo.taskId;
+        mPipTaskId = taskInfo.childTaskIds[taskInfo.childTaskIds.length - 1];
+        mPipComponentName = ComponentName.unflattenFromString(
+                taskInfo.childTaskNames[taskInfo.childTaskNames.length - 1]);
+        // Set state to STATE_PIP so we show it when the pinned stack animation ends.
+        mState = STATE_PIP;
+        mMediaSessionManager.addOnActiveSessionsChangedListener(
+                mActiveMediaSessionListener, null);
+        updateMediaController(mMediaSessionManager.getActiveSessions(null));
+        for (int i = mListeners.size() - 1; i >= 0; i--) {
+            mListeners.get(i).onPipEntered(packageName);
+        }
+    }
+
+    @Override
+    public void onActivityRestartAttempt(ActivityManager.RunningTaskInfo task,
+            boolean clearedTask) {
+        if (task.configuration.windowConfiguration.getWindowingMode()
+                != WINDOWING_MODE_PINNED) {
+            return;
+        }
+        if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
+
+        // If PIPed activity is launched again by Launcher or intent, make it fullscreen.
+        movePipToFullscreen();
+    }
+
+    @Override
+    public void onTaskStackChanged() {
+        if (DEBUG) Log.d(TAG, "onTaskStackChanged()");
+
+        if (getState() != STATE_NO_PIP) {
+            boolean hasPip = false;
+
+            RootTaskInfo taskInfo = getPinnedTaskInfo();
+            if (taskInfo == null || taskInfo.childTaskIds == null) {
+                Log.w(TAG, "There is nothing in pinned stack");
+                closePipInternal(false);
+                return;
+            }
+            for (int i = taskInfo.childTaskIds.length - 1; i >= 0; --i) {
+                if (taskInfo.childTaskIds[i] == mPipTaskId) {
+                    // PIP task is still alive.
+                    hasPip = true;
+                    break;
+                }
+            }
+            if (!hasPip) {
+                // PIP task doesn't exist anymore in PINNED_STACK.
+                closePipInternal(true);
+                return;
+            }
+        }
+        if (getState() == STATE_PIP) {
+            if (mPipBounds != mDefaultPipBounds) {
+                mPipBounds = mDefaultPipBounds;
+                resizePinnedStack(STATE_PIP);
+            }
+        }
+    }
+
+    /**
+     * Suspends resizing operation on the Pip until {@link #resumePipResizing} is called
+     *
+     * @param reason The reason for suspending resizing operations on the Pip.
+     */
+    public void suspendPipResizing(int reason) {
+        if (DEBUG) {
+            Log.d(TAG,
+                    "suspendPipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
+        }
+
+        mSuspendPipResizingReason |= reason;
+    }
+
+    /**
+     * Resumes resizing operation on the Pip that was previously suspended.
+     *
+     * @param reason The reason resizing operations on the Pip was suspended.
+     */
+    public void resumePipResizing(int reason) {
+        if ((mSuspendPipResizingReason & reason) == 0) {
+            return;
+        }
+        if (DEBUG) {
+            Log.d(TAG,
+                    "resumePipResizing() reason=" + reason + " callers=" + Debug.getCallers(2));
+        }
+        mSuspendPipResizingReason &= ~reason;
+        mHandler.post(mResizePinnedStackRunnable);
+    }
+
+    /**
+     * Resize the Pip to the appropriate size for the input state.
+     *
+     * @param state In Pip state also used to determine the new size for the Pip.
+     */
+    public void resizePinnedStack(int state) {
+        if (DEBUG) {
+            Log.d(TAG, "resizePinnedStack() state=" + stateToName(state) + ", current state="
+                    + getStateDescription(), new Exception());
+        }
+
+        boolean wasStateNoPip = (mState == STATE_NO_PIP);
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onPipResizeAboutToStart();
+        }
+        if (mSuspendPipResizingReason != 0) {
+            mResumeResizePinnedStackRunnableState = state;
+            if (DEBUG) {
+                Log.d(TAG, "resizePinnedStack() deferring"
+                        + " mSuspendPipResizingReason=" + mSuspendPipResizingReason
+                        + " mResumeResizePinnedStackRunnableState="
+                        + stateToName(mResumeResizePinnedStackRunnableState));
+            }
+            return;
+        }
+        mState = state;
+        final Rect newBounds;
+        switch (mState) {
+            case STATE_NO_PIP:
+                newBounds = null;
+                // If the state was already STATE_NO_PIP, then do not resize the stack below as it
+                // will not exist
+                if (wasStateNoPip) {
+                    return;
+                }
+                break;
+            case STATE_PIP_MENU:
+                newBounds = mMenuModePipBounds;
+                break;
+            case STATE_PIP: // fallthrough
+            default:
+                newBounds = mPipBounds;
+                break;
+        }
+        if (newBounds != null) {
+            mPipTaskOrganizer.scheduleAnimateResizePip(newBounds, mResizeAnimationDuration, null);
+        } else {
+            mPipTaskOrganizer.exitPip(mResizeAnimationDuration);
+        }
+    }
+
+    /**
+     * @return the current state, or the pending state if the state change was previously suspended.
+     */
+    private int getState() {
+        if (mSuspendPipResizingReason != 0) {
+            return mResumeResizePinnedStackRunnableState;
+        }
+        return mState;
+    }
+
+    /**
+     * Shows PIP menu UI by launching {@link PipMenuActivity}. It also locates the pinned
+     * stack to the centered PIP bound {@link R.config_centeredPictureInPictureBounds}.
+     */
+    private void showPipMenu() {
+        if (DEBUG) Log.d(TAG, "showPipMenu(), current state=" + getStateDescription());
+
+        mState = STATE_PIP_MENU;
+        for (int i = mListeners.size() - 1; i >= 0; --i) {
+            mListeners.get(i).onShowPipMenu();
+        }
+        Intent intent = new Intent(mContext, PipMenuActivity.class);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.putExtra(PipMenuActivity.EXTRA_CUSTOM_ACTIONS, mCustomActions);
+        mContext.startActivity(intent);
+    }
+
+    /**
+     * Adds a {@link Listener} to PipController.
+     */
+    public void addListener(Listener listener) {
+        mListeners.add(listener);
+    }
+
+    /**
+     * Removes a {@link Listener} from PipController.
+     */
+    public void removeListener(Listener listener) {
+        mListeners.remove(listener);
+    }
+
+    /**
+     * Adds a {@link MediaListener} to PipController.
+     */
+    public void addMediaListener(MediaListener listener) {
+        mMediaListeners.add(listener);
+    }
+
+    /**
+     * Removes a {@link MediaListener} from PipController.
+     */
+    public void removeMediaListener(MediaListener listener) {
+        mMediaListeners.remove(listener);
+    }
+
+    /**
+     * Returns {@code true} if PIP is shown.
+     */
+    public boolean isPipShown() {
+        return mState != STATE_NO_PIP;
+    }
+
+    private RootTaskInfo getPinnedTaskInfo() {
+        RootTaskInfo taskInfo = null;
+        try {
+            taskInfo = ActivityTaskManager.getService().getRootTaskInfo(
+                    WINDOWING_MODE_PINNED, ACTIVITY_TYPE_UNDEFINED);
+        } catch (RemoteException e) {
+            Log.e(TAG, "getRootTaskInfo failed", e);
+        }
+        return taskInfo;
+    }
+
+    private void handleMediaResourceGranted(String[] packageNames) {
+        if (getState() == STATE_NO_PIP) {
+            mLastPackagesResourceGranted = packageNames;
+        } else {
+            boolean requestedFromLastPackages = false;
+            if (mLastPackagesResourceGranted != null) {
+                for (String packageName : mLastPackagesResourceGranted) {
+                    for (String newPackageName : packageNames) {
+                        if (TextUtils.equals(newPackageName, packageName)) {
+                            requestedFromLastPackages = true;
+                            break;
+                        }
+                    }
+                }
+            }
+            mLastPackagesResourceGranted = packageNames;
+            if (!requestedFromLastPackages) {
+                closePip();
+            }
+        }
+    }
+
+    private void updateMediaController(List<MediaController> controllers) {
+        MediaController mediaController = null;
+        if (controllers != null && getState() != STATE_NO_PIP && mPipComponentName != null) {
+            for (int i = controllers.size() - 1; i >= 0; i--) {
+                MediaController controller = controllers.get(i);
+                // We assumes that an app with PIPable activity
+                // keeps the single instance of media controller especially when PIP is on.
+                if (controller.getPackageName().equals(mPipComponentName.getPackageName())) {
+                    mediaController = controller;
+                    break;
+                }
+            }
+        }
+        if (mPipMediaController != mediaController) {
+            mPipMediaController = mediaController;
+            for (int i = mMediaListeners.size() - 1; i >= 0; i--) {
+                mMediaListeners.get(i).onMediaControllerChanged();
+            }
+            if (mPipMediaController == null) {
+                mHandler.postDelayed(mClosePipRunnable,
+                        CLOSE_PIP_WHEN_MEDIA_SESSION_GONE_TIMEOUT_MS);
+            } else {
+                mHandler.removeCallbacks(mClosePipRunnable);
+            }
+        }
+    }
+
+    /**
+     * Gets the {@link android.media.session.MediaController} for the PIPed activity.
+     */
+    public MediaController getMediaController() {
+        return mPipMediaController;
+    }
+
+    @Override
+    public void hidePipMenu(Runnable onStartCallback, Runnable onEndCallback) {
+
+    }
+
+    /**
+     * Returns the PIPed activity's playback state.
+     * This returns one of {@link #PLAYBACK_STATE_PLAYING}, {@link #PLAYBACK_STATE_PAUSED},
+     * or {@link #PLAYBACK_STATE_UNAVAILABLE}.
+     */
+    public int getPlaybackState() {
+        if (mPipMediaController == null || mPipMediaController.getPlaybackState() == null) {
+            return PLAYBACK_STATE_UNAVAILABLE;
+        }
+        int state = mPipMediaController.getPlaybackState().getState();
+        boolean isPlaying = (state == PlaybackState.STATE_BUFFERING
+                || state == PlaybackState.STATE_CONNECTING
+                || state == PlaybackState.STATE_PLAYING
+                || state == PlaybackState.STATE_FAST_FORWARDING
+                || state == PlaybackState.STATE_REWINDING
+                || state == PlaybackState.STATE_SKIPPING_TO_PREVIOUS
+                || state == PlaybackState.STATE_SKIPPING_TO_NEXT);
+        long actions = mPipMediaController.getPlaybackState().getActions();
+        if (!isPlaying && ((actions & PlaybackState.ACTION_PLAY) != 0)) {
+            return PLAYBACK_STATE_PAUSED;
+        } else if (isPlaying && ((actions & PlaybackState.ACTION_PAUSE) != 0)) {
+            return PLAYBACK_STATE_PLAYING;
+        }
+        return PLAYBACK_STATE_UNAVAILABLE;
+    }
+
+    @Override
+    public void onPipTransitionStarted(ComponentName activity, int direction, Rect pipBounds) {
+    }
+
+    @Override
+    public void onPipTransitionFinished(ComponentName activity, int direction) {
+        onPipTransitionFinishedOrCanceled();
+    }
+
+    @Override
+    public void onPipTransitionCanceled(ComponentName activity, int direction) {
+        onPipTransitionFinishedOrCanceled();
+    }
+
+    private void onPipTransitionFinishedOrCanceled() {
+        if (DEBUG) Log.d(TAG, "onPipTransitionFinishedOrCanceled()");
+
+        if (getState() == STATE_PIP_MENU) {
+            showPipMenu();
+        }
+    }
+
+    /**
+     * A listener interface to receive notification on changes in PIP.
+     */
+    public interface Listener {
+        /**
+         * Invoked when an activity is pinned and PIP manager is set corresponding information.
+         * Classes must use this instead of {@link android.app.ITaskStackListener.onActivityPinned}
+         * because there's no guarantee for the PIP manager be return relavent information
+         * correctly. (e.g. {@link Pip.isPipShown}).
+         */
+        void onPipEntered(String packageName);
+        /** Invoked when a PIPed activity is closed. */
+        void onPipActivityClosed();
+        /** Invoked when the PIP menu gets shown. */
+        void onShowPipMenu();
+        /** Invoked when the PIP menu actions change. */
+        void onPipMenuActionsChanged(ParceledListSlice<RemoteAction> actions);
+        /** Invoked when the PIPed activity is about to return back to the fullscreen. */
+        void onMoveToFullscreen();
+        /** Invoked when we are above to start resizing the Pip. */
+        void onPipResizeAboutToStart();
+    }
+
+    /**
+     * A listener interface to receive change in PIP's media controller
+     */
+    public interface MediaListener {
+        /** Invoked when the MediaController on PIPed activity is changed. */
+        void onMediaControllerChanged();
+    }
+
+    private String getStateDescription() {
+        if (mSuspendPipResizingReason == 0) {
+            return stateToName(mState);
+        }
+        return stateToName(mResumeResizePinnedStackRunnableState) + " (while " + stateToName(mState)
+                + " is suspended)";
+    }
+
+    private static String stateToName(int state) {
+        switch (state) {
+            case STATE_NO_PIP:
+                return "NO_PIP";
+
+            case STATE_PIP:
+                return "PIP";
+
+            case STATE_PIP_MENU:
+                return "PIP_MENU";
+
+            default:
+                return "UNKNOWN(" + state + ")";
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsView.java
new file mode 100644
index 0000000..14960c3
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsView.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.tv;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.widget.LinearLayout;
+
+import com.android.wm.shell.R;
+
+
+/**
+ * A view containing PIP controls including fullscreen, close, and media controls.
+ */
+public class PipControlsView extends LinearLayout {
+
+    public PipControlsView(Context context) {
+        this(context, null);
+    }
+
+    public PipControlsView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public PipControlsView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public PipControlsView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        LayoutInflater layoutInflater = (LayoutInflater) getContext().getSystemService(
+                Context.LAYOUT_INFLATER_SERVICE);
+        layoutInflater.inflate(R.layout.tv_pip_controls, this);
+        setOrientation(LinearLayout.HORIZONTAL);
+        setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
+    }
+
+    PipControlButtonView getFullButtonView() {
+        return findViewById(R.id.full_button);
+    }
+
+    PipControlButtonView getCloseButtonView() {
+        return findViewById(R.id.close_button);
+    }
+
+    PipControlButtonView getPlayPauseButtonView() {
+        return findViewById(R.id.play_pause_button);
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsViewController.java
new file mode 100644
index 0000000..f66e902
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipControlsViewController.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.tv;
+
+import android.app.PendingIntent;
+import android.app.RemoteAction;
+import android.graphics.Color;
+import android.media.session.MediaController;
+import android.media.session.PlaybackState;
+import android.os.Handler;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+
+import com.android.wm.shell.R;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
+
+/**
+ * Controller for {@link PipControlsView}.
+ */
+public class PipControlsViewController {
+    private static final String TAG = PipControlsViewController.class.getSimpleName();
+
+    private static final float DISABLED_ACTION_ALPHA = 0.54f;
+
+    private final PipControlsView mView;
+    private final LayoutInflater mLayoutInflater;
+    private final Handler mHandler;
+    private final PipController mPipController;
+    private final PipControlButtonView mPlayPauseButtonView;
+    private MediaController mMediaController;
+    private PipControlButtonView mFocusedChild;
+    private Listener mListener;
+    private ArrayList<PipControlButtonView> mCustomButtonViews = new ArrayList<>();
+    private List<RemoteAction> mCustomActions = new ArrayList<>();
+
+    public PipControlsView getView() {
+        return mView;
+    }
+
+    /**
+     * An interface to listen user action.
+     */
+    public interface Listener {
+        /**
+         * Called when a user clicks close PIP button.
+         */
+        void onClosed();
+    }
+
+    private View.OnAttachStateChangeListener
+            mOnAttachStateChangeListener =
+            new View.OnAttachStateChangeListener() {
+                @Override
+                public void onViewAttachedToWindow(View v) {
+                    updateMediaController();
+                    mPipController.addMediaListener(mPipMediaListener);
+                }
+
+                @Override
+                public void onViewDetachedFromWindow(View v) {
+                    mPipController.removeMediaListener(mPipMediaListener);
+                }
+            };
+
+    private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() {
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            updateUserActions();
+        }
+    };
+
+    private final PipController.MediaListener mPipMediaListener = this::updateMediaController;
+
+    private final View.OnFocusChangeListener
+            mFocusChangeListener =
+            new View.OnFocusChangeListener() {
+                @Override
+                public void onFocusChange(View view, boolean hasFocus) {
+                    if (hasFocus) {
+                        mFocusedChild = (PipControlButtonView) view;
+                    } else if (mFocusedChild == view) {
+                        mFocusedChild = null;
+                    }
+                }
+            };
+
+    public PipControlsViewController(PipControlsView view, PipController pipController,
+            LayoutInflater layoutInflater, Handler handler) {
+        super();
+        mView = view;
+        mPipController = pipController;
+        mLayoutInflater = layoutInflater;
+        mHandler = handler;
+
+        mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
+        if (mView.isAttachedToWindow()) {
+            mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
+        }
+
+        View fullButtonView = mView.getFullButtonView();
+        fullButtonView.setOnFocusChangeListener(mFocusChangeListener);
+        fullButtonView.setOnClickListener(mView -> mPipController.movePipToFullscreen());
+
+        View closeButtonView = mView.getCloseButtonView();
+        closeButtonView.setOnFocusChangeListener(mFocusChangeListener);
+        closeButtonView.setOnClickListener(v -> {
+            mPipController.closePip();
+            if (mListener != null) {
+                mListener.onClosed();
+            }
+        });
+
+        mPlayPauseButtonView = mView.getPlayPauseButtonView();
+        mPlayPauseButtonView.setOnFocusChangeListener(mFocusChangeListener);
+        mPlayPauseButtonView.setOnClickListener(v -> {
+            if (mMediaController == null || mMediaController.getPlaybackState() == null) {
+                return;
+            }
+            final int playbackState = mPipController.getPlaybackState();
+            if (playbackState == PipController.PLAYBACK_STATE_PAUSED) {
+                mMediaController.getTransportControls().play();
+            } else if (playbackState == PipController.PLAYBACK_STATE_PLAYING) {
+                mMediaController.getTransportControls().pause();
+            }
+
+            // View will be updated later in {@link mMediaControllerCallback}
+        });
+    }
+
+    private void updateMediaController() {
+        AtomicReference<MediaController> newController = new AtomicReference<>();
+        newController.set(mPipController.getMediaController());
+
+        if (newController.get() == null || mMediaController == newController.get()) {
+            return;
+        }
+        if (mMediaController != null) {
+            mMediaController.unregisterCallback(mMediaControllerCallback);
+        }
+        mMediaController = newController.get();
+        if (mMediaController != null) {
+            mMediaController.registerCallback(mMediaControllerCallback);
+        }
+        updateUserActions();
+    }
+
+    /**
+     * Updates the actions for the PIP. If there are no custom actions, then the media session
+     * actions are shown.
+     */
+    private void updateUserActions() {
+        if (!mCustomActions.isEmpty()) {
+            // Ensure we have as many buttons as actions
+            while (mCustomButtonViews.size() < mCustomActions.size()) {
+                PipControlButtonView buttonView = (PipControlButtonView) mLayoutInflater.inflate(
+                        R.layout.tv_pip_custom_control, mView, false);
+                mView.addView(buttonView);
+                mCustomButtonViews.add(buttonView);
+            }
+
+            // Update the visibility of all views
+            for (int i = 0; i < mCustomButtonViews.size(); i++) {
+                mCustomButtonViews.get(i).setVisibility(
+                        i < mCustomActions.size() ? View.VISIBLE : View.GONE);
+            }
+
+            // Update the state and visibility of the action buttons, and hide the rest
+            for (int i = 0; i < mCustomActions.size(); i++) {
+                final RemoteAction action = mCustomActions.get(i);
+                PipControlButtonView actionView = mCustomButtonViews.get(i);
+
+                // TODO: Check if the action drawable has changed before we reload it
+                action.getIcon().loadDrawableAsync(mView.getContext(), d -> {
+                    d.setTint(Color.WHITE);
+                    actionView.setImageDrawable(d);
+                }, mHandler);
+                actionView.setText(action.getContentDescription());
+                if (action.isEnabled()) {
+                    actionView.setOnClickListener(v -> {
+                        try {
+                            action.getActionIntent().send();
+                        } catch (PendingIntent.CanceledException e) {
+                            Log.w(TAG, "Failed to send action", e);
+                        }
+                    });
+                }
+                actionView.setEnabled(action.isEnabled());
+                actionView.setAlpha(action.isEnabled() ? 1f : DISABLED_ACTION_ALPHA);
+            }
+
+            // Hide the media session buttons
+            mPlayPauseButtonView.setVisibility(View.GONE);
+        } else {
+            AtomicInteger state = new AtomicInteger(PipController.STATE_UNKNOWN);
+            state.set(mPipController.getPlaybackState());
+            if (state.get() == PipController.STATE_UNKNOWN
+                    || state.get() == PipController.PLAYBACK_STATE_UNAVAILABLE) {
+                mPlayPauseButtonView.setVisibility(View.GONE);
+            } else {
+                mPlayPauseButtonView.setVisibility(View.VISIBLE);
+                if (state.get() == PipController.PLAYBACK_STATE_PLAYING) {
+                    mPlayPauseButtonView.setImageResource(R.drawable.pip_ic_pause_white);
+                    mPlayPauseButtonView.setText(R.string.pip_pause);
+                } else {
+                    mPlayPauseButtonView.setImageResource(R.drawable.pip_ic_play_arrow_white);
+                    mPlayPauseButtonView.setText(R.string.pip_play);
+                }
+            }
+
+            // Hide all the custom action buttons
+            for (int i = 0; i < mCustomButtonViews.size(); i++) {
+                mCustomButtonViews.get(i).setVisibility(View.GONE);
+            }
+        }
+    }
+
+
+    /**
+     * Sets the {@link Listener} to listen user actions.
+     */
+    public void setListener(Listener listener) {
+        mListener = listener;
+    }
+
+
+    /**
+     * Updates the set of activity-defined actions.
+     */
+    public void setActions(List<? extends RemoteAction> actions) {
+        mCustomActions.clear();
+        mCustomActions.addAll(actions);
+        updateUserActions();
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java
new file mode 100644
index 0000000..06d2408
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipMenuActivity.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.tv;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.app.Activity;
+import android.app.RemoteAction;
+import android.content.Intent;
+import android.content.pm.ParceledListSlice;
+import android.os.Bundle;
+import android.util.Log;
+
+import com.android.wm.shell.R;
+
+import java.util.Collections;
+
+/**
+ * Activity to show the PIP menu to control PIP.
+ * TODO(b/169395392) Refactor PipMenuActivity to PipMenuView
+ */
+public class PipMenuActivity extends Activity implements PipController.Listener {
+    private static final String TAG = "PipMenuActivity";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    static final String EXTRA_CUSTOM_ACTIONS = "custom_actions";
+
+    private static PipController sPipController;
+
+    private Animator mFadeInAnimation;
+    private Animator mFadeOutAnimation;
+    private boolean mRestorePipSizeWhenClose;
+    private PipControlsViewController mPipControlsViewController;
+
+    @Override
+    protected void onCreate(Bundle bundle) {
+        if (DEBUG) Log.d(TAG, "onCreate()");
+
+        super.onCreate(bundle);
+        if (sPipController == null || sPipController.isPipShown()) {
+            finish();
+        }
+        setContentView(R.layout.tv_pip_menu);
+        mPipControlsViewController = new PipControlsViewController(
+                findViewById(R.id.pip_controls), sPipController,
+                getLayoutInflater(), getApplicationContext().getMainThreadHandler());
+        sPipController.addListener(this);
+        mRestorePipSizeWhenClose = true;
+        mFadeInAnimation = AnimatorInflater.loadAnimator(
+                this, R.anim.tv_pip_menu_fade_in_animation);
+        mFadeInAnimation.setTarget(mPipControlsViewController.getView());
+        mFadeOutAnimation = AnimatorInflater.loadAnimator(
+                this, R.anim.tv_pip_menu_fade_out_animation);
+        mFadeOutAnimation.setTarget(mPipControlsViewController.getView());
+
+        onPipMenuActionsChanged(getIntent().getParcelableExtra(EXTRA_CUSTOM_ACTIONS));
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        if (DEBUG) Log.d(TAG, "onNewIntent(), intent=" + intent);
+        super.onNewIntent(intent);
+
+        onPipMenuActionsChanged(getIntent().getParcelableExtra(EXTRA_CUSTOM_ACTIONS));
+    }
+
+    private void restorePipAndFinish() {
+        if (DEBUG) Log.d(TAG, "restorePipAndFinish()");
+
+        if (mRestorePipSizeWhenClose) {
+            if (DEBUG) Log.d(TAG, "   > restoring to the default position");
+
+            // When PIP menu activity is closed, restore to the default position.
+            sPipController.resizePinnedStack(PipController.STATE_PIP);
+        }
+        finish();
+    }
+
+    @Override
+    public void onResume() {
+        if (DEBUG) Log.d(TAG, "onResume()");
+
+        super.onResume();
+        mFadeInAnimation.start();
+    }
+
+    @Override
+    public void onPause() {
+        if (DEBUG) Log.d(TAG, "onPause()");
+
+        super.onPause();
+        mFadeOutAnimation.start();
+        restorePipAndFinish();
+    }
+
+    @Override
+    protected void onDestroy() {
+        if (DEBUG) Log.d(TAG, "onDestroy()");
+
+        super.onDestroy();
+        sPipController.removeListener(this);
+        sPipController.resumePipResizing(
+                PipController.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
+    }
+
+    @Override
+    public void onBackPressed() {
+        if (DEBUG) Log.d(TAG, "onBackPressed()");
+
+        restorePipAndFinish();
+    }
+
+    @Override
+    public void onPipEntered(String packageName) {
+        if (DEBUG) Log.d(TAG, "onPipEntered(), packageName=" + packageName);
+    }
+
+    @Override
+    public void onPipActivityClosed() {
+        if (DEBUG) Log.d(TAG, "onPipActivityClosed()");
+
+        finish();
+    }
+
+    @Override
+    public void onPipMenuActionsChanged(ParceledListSlice<RemoteAction> actions) {
+        if (DEBUG) Log.d(TAG, "onPipMenuActionsChanged()");
+
+        boolean hasCustomActions = actions != null && !actions.getList().isEmpty();
+        mPipControlsViewController.setActions(
+                hasCustomActions ? actions.getList() : Collections.emptyList());
+    }
+
+    @Override
+    public void onShowPipMenu() {
+        if (DEBUG) Log.d(TAG, "onShowPipMenu()");
+    }
+
+    @Override
+    public void onMoveToFullscreen() {
+        if (DEBUG) Log.d(TAG, "onMoveToFullscreen()");
+
+        // Moving PIP to fullscreen is implemented by resizing PINNED_STACK with null bounds.
+        // This conflicts with restoring PIP position, so disable it.
+        mRestorePipSizeWhenClose = false;
+        finish();
+    }
+
+    @Override
+    public void onPipResizeAboutToStart() {
+        if (DEBUG) Log.d(TAG, "onPipResizeAboutToStart()");
+
+        finish();
+        sPipController.suspendPipResizing(
+                PipController.SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH);
+    }
+
+    @Override
+    public void finish() {
+        if (DEBUG) Log.d(TAG, "finish()", new RuntimeException());
+
+        super.finish();
+    }
+
+    /**
+     * TODO(b/169395392) Refactor PipMenuActivity to PipMenuView
+     *
+     * @param pipController The singleton pipController instance for TV
+     */
+    public static void setPipController(PipController pipController) {
+        if (sPipController != null) {
+            return;
+        }
+        sPipController = pipController;
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java
new file mode 100644
index 0000000..7433085
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/tv/PipNotification.java
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip.tv;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.RemoteAction;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.media.MediaMetadata;
+import android.media.session.MediaController;
+import android.media.session.PlaybackState;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
+import com.android.wm.shell.R;
+
+/**
+ * A notification that informs users that PIP is running and also provides PIP controls.
+ * <p>Once it's created, it will manage the PIP notification UI by itself except for handling
+ * configuration changes.
+ */
+public class PipNotification {
+    private static final String TAG = "PipNotification";
+    private static final String NOTIFICATION_TAG = PipNotification.class.getSimpleName();
+    private static final boolean DEBUG = PipController.DEBUG;
+
+    private static final String ACTION_MENU = "PipNotification.menu";
+    private static final String ACTION_CLOSE = "PipNotification.close";
+
+    public static final String NOTIFICATION_CHANNEL_TVPIP = "TPP";
+
+    private final PackageManager mPackageManager;
+
+    private final PipController mPipController;
+
+    private final NotificationManager mNotificationManager;
+    private final Notification.Builder mNotificationBuilder;
+
+    private MediaController mMediaController;
+    private String mDefaultTitle;
+    private int mDefaultIconResId;
+
+    /** Package name for the application that owns PiP window. */
+    private String mPackageName;
+    private boolean mNotified;
+    private String mMediaTitle;
+    private Bitmap mArt;
+
+    private PipController.Listener mPipListener = new PipController.Listener() {
+        @Override
+        public void onPipEntered(String packageName) {
+            mPackageName = packageName;
+            updateMediaControllerMetadata();
+            notifyPipNotification();
+        }
+
+        @Override
+        public void onPipActivityClosed() {
+            dismissPipNotification();
+            mPackageName = null;
+        }
+
+        @Override
+        public void onShowPipMenu() {
+            // no-op.
+        }
+
+        @Override
+        public void onPipMenuActionsChanged(ParceledListSlice<RemoteAction> actions) {
+            // no-op.
+        }
+
+        @Override
+        public void onMoveToFullscreen() {
+            dismissPipNotification();
+            mPackageName = null;
+        }
+
+        @Override
+        public void onPipResizeAboutToStart() {
+            // no-op.
+        }
+    };
+
+    private MediaController.Callback mMediaControllerCallback = new MediaController.Callback() {
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            if (updateMediaControllerMetadata() && mNotified) {
+                // update notification
+                notifyPipNotification();
+            }
+        }
+
+        @Override
+        public void onMetadataChanged(MediaMetadata metadata) {
+            if (updateMediaControllerMetadata() && mNotified) {
+                // update notification
+                notifyPipNotification();
+            }
+        }
+    };
+
+    private final PipController.MediaListener mPipMediaListener =
+            new PipController.MediaListener() {
+                @Override
+                public void onMediaControllerChanged() {
+                    MediaController newController = mPipController.getMediaController();
+                    if (newController == null || mMediaController == newController) {
+                        return;
+                    }
+                    if (mMediaController != null) {
+                        mMediaController.unregisterCallback(mMediaControllerCallback);
+                    }
+                    mMediaController = newController;
+                    if (mMediaController != null) {
+                        mMediaController.registerCallback(mMediaControllerCallback);
+                    }
+                    if (updateMediaControllerMetadata() && mNotified) {
+                        // update notification
+                        notifyPipNotification();
+                    }
+                }
+            };
+
+    private final BroadcastReceiver mEventReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (DEBUG) {
+                Log.d(TAG, "Received " + intent.getAction() + " from the notification UI");
+            }
+            switch (intent.getAction()) {
+                case ACTION_MENU:
+                    mPipController.showPictureInPictureMenu();
+                    break;
+                case ACTION_CLOSE:
+                    mPipController.closePip();
+                    break;
+            }
+        }
+    };
+
+    public PipNotification(Context context, PipController pipController) {
+        mPackageManager = context.getPackageManager();
+
+        mNotificationManager = (NotificationManager) context.getSystemService(
+                Context.NOTIFICATION_SERVICE);
+
+        mNotificationBuilder = new Notification.Builder(context, NOTIFICATION_CHANNEL_TVPIP)
+                .setLocalOnly(true)
+                .setOngoing(false)
+                .setCategory(Notification.CATEGORY_SYSTEM)
+                .extend(new Notification.TvExtender()
+                        .setContentIntent(createPendingIntent(context, ACTION_MENU))
+                        .setDeleteIntent(createPendingIntent(context, ACTION_CLOSE)));
+
+        mPipController = pipController;
+        pipController.addListener(mPipListener);
+        pipController.addMediaListener(mPipMediaListener);
+
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(ACTION_MENU);
+        intentFilter.addAction(ACTION_CLOSE);
+        context.registerReceiver(mEventReceiver, intentFilter, UserHandle.USER_ALL);
+
+        onConfigurationChanged(context);
+    }
+
+    /**
+     * Called by {@link PipController} when the configuration is changed.
+     */
+    void onConfigurationChanged(Context context) {
+        Resources res = context.getResources();
+        mDefaultTitle = res.getString(R.string.pip_notification_unknown_title);
+        mDefaultIconResId = R.drawable.pip_icon;
+        if (mNotified) {
+            // update notification
+            notifyPipNotification();
+        }
+    }
+
+    private void notifyPipNotification() {
+        mNotified = true;
+        mNotificationBuilder
+                .setShowWhen(true)
+                .setWhen(System.currentTimeMillis())
+                .setSmallIcon(mDefaultIconResId)
+                .setContentTitle(getNotificationTitle());
+        if (mArt != null) {
+            mNotificationBuilder.setStyle(new Notification.BigPictureStyle()
+                    .bigPicture(mArt));
+        } else {
+            mNotificationBuilder.setStyle(null);
+        }
+        mNotificationManager.notify(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP,
+                mNotificationBuilder.build());
+    }
+
+    private void dismissPipNotification() {
+        mNotified = false;
+        mNotificationManager.cancel(NOTIFICATION_TAG, SystemMessage.NOTE_TV_PIP);
+    }
+
+    private boolean updateMediaControllerMetadata() {
+        String title = null;
+        Bitmap art = null;
+        if (mPipController.getMediaController() != null) {
+            MediaMetadata metadata = mPipController.getMediaController().getMetadata();
+            if (metadata != null) {
+                title = metadata.getString(MediaMetadata.METADATA_KEY_DISPLAY_TITLE);
+                if (TextUtils.isEmpty(title)) {
+                    title = metadata.getString(MediaMetadata.METADATA_KEY_TITLE);
+                }
+                art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
+                if (art == null) {
+                    art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
+                }
+            }
+        }
+        if (!TextUtils.equals(title, mMediaTitle) || art != mArt) {
+            mMediaTitle = title;
+            mArt = art;
+            return true;
+        }
+        return false;
+    }
+
+
+    private String getNotificationTitle() {
+        if (!TextUtils.isEmpty(mMediaTitle)) {
+            return mMediaTitle;
+        }
+
+        final String applicationTitle = getApplicationLabel(mPackageName);
+        if (!TextUtils.isEmpty(applicationTitle)) {
+            return applicationTitle;
+        }
+
+        return mDefaultTitle;
+    }
+
+    private String getApplicationLabel(String packageName) {
+        try {
+            final ApplicationInfo appInfo = mPackageManager.getApplicationInfo(packageName, 0);
+            return mPackageManager.getApplicationLabel(appInfo).toString();
+        } catch (PackageManager.NameNotFoundException e) {
+            return null;
+        }
+    }
+
+    private static PendingIntent createPendingIntent(Context context, String action) {
+        return PendingIntent.getBroadcast(context, 0,
+                new Intent(action), PendingIntent.FLAG_CANCEL_CURRENT);
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 937b00b..9940ea5 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -23,20 +23,30 @@
         "androidx.test.runner",
         "androidx.test.rules",
         "androidx.test.ext.junit",
+        "androidx.dynamicanimation_dynamicanimation",
+        "dagger2",
+        "kotlinx-coroutines-android",
+        "kotlinx-coroutines-core",
         "mockito-target-extended-minus-junit4",
         "truth-prebuilt",
         "testables",
     ],
+
     libs: [
         "android.test.mock",
         "android.test.base",
         "android.test.runner",
     ],
+
     jni_libs: [
         "libdexmakerjvmtiagent",
         "libstaticjvmtiagent",
     ],
 
+    kotlincflags: ["-Xjvm-default=enable"],
+
+    plugins: ["dagger2-compiler"],
+
     optimize: {
         enabled: false,
     },
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/animation/PhysicsAnimatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/animation/PhysicsAnimatorTest.kt
new file mode 100644
index 0000000..4bd9bed
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/animation/PhysicsAnimatorTest.kt
@@ -0,0 +1,627 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.animation
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.util.ArrayMap
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.dynamicanimation.animation.DynamicAnimation
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+import androidx.dynamicanimation.animation.SpringForce
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.wm.shell.animation.PhysicsAnimator.EndListener
+import com.android.wm.shell.animation.PhysicsAnimator.UpdateListener
+import com.android.wm.shell.animation.PhysicsAnimatorTestUtils.clearAnimationUpdateFrames
+import com.android.wm.shell.animation.PhysicsAnimatorTestUtils.getAnimationUpdateFrames
+import com.android.wm.shell.animation.PhysicsAnimatorTestUtils.verifyAnimationUpdateFrames
+import org.junit.After
+import org.junit.Assert
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertNotEquals
+import org.junit.Assert.assertNotNull
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyFloat
+import org.mockito.Mockito
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+import org.mockito.MockitoAnnotations
+
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+@Ignore("Blocking presubmits - investigating in b/158697054")
+class PhysicsAnimatorTest : SysuiTestCase() {
+    private lateinit var viewGroup: ViewGroup
+    private lateinit var testView: View
+    private lateinit var testView2: View
+
+    private lateinit var animator: PhysicsAnimator<View>
+
+    private val springConfig = PhysicsAnimator.SpringConfig(
+            SpringForce.STIFFNESS_LOW, SpringForce.DAMPING_RATIO_NO_BOUNCY)
+    private val flingConfig = PhysicsAnimator.FlingConfig(2f)
+
+    private lateinit var mockUpdateListener: UpdateListener<View>
+    private lateinit var mockEndListener: EndListener<View>
+    private lateinit var mockEndAction: Runnable
+
+    private fun <T> eq(value: T): T = Mockito.eq(value) ?: value
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        mockUpdateListener = mock(UpdateListener::class.java) as UpdateListener<View>
+        mockEndListener = mock(EndListener::class.java) as EndListener<View>
+        mockEndAction = mock(Runnable::class.java)
+
+        viewGroup = FrameLayout(context)
+        testView = View(context)
+        testView2 = View(context)
+        viewGroup.addView(testView)
+        viewGroup.addView(testView2)
+
+        PhysicsAnimatorTestUtils.prepareForTest()
+
+        // Most of our tests involve checking the end state of animations, so we want calls that
+        // start animations to block the test thread until the animations have ended.
+        PhysicsAnimatorTestUtils.setAllAnimationsBlock(true)
+
+        animator = PhysicsAnimator.getInstance(testView)
+    }
+
+    @After
+    fun tearDown() {
+        PhysicsAnimatorTestUtils.tearDown()
+    }
+
+    @Test
+    fun testOneAnimatorPerView() {
+        assertEquals(animator, PhysicsAnimator.getInstance(testView))
+        assertEquals(PhysicsAnimator.getInstance(testView), PhysicsAnimator.getInstance(testView))
+        assertNotEquals(animator, PhysicsAnimator.getInstance(testView2))
+    }
+
+    @Test
+    fun testSpringOneProperty() {
+        animator
+                .spring(DynamicAnimation.TRANSLATION_X, 50f, springConfig)
+                .start()
+
+        assertEquals(testView.translationX, 50f, 1f)
+    }
+
+    @Test
+    fun testSpringMultipleProperties() {
+        animator
+                .spring(DynamicAnimation.TRANSLATION_X, 10f, springConfig)
+                .spring(DynamicAnimation.TRANSLATION_Y, 50f, springConfig)
+                .spring(DynamicAnimation.SCALE_Y, 1.1f, springConfig)
+                .start()
+
+        assertEquals(10f, testView.translationX, 1f)
+        assertEquals(50f, testView.translationY, 1f)
+        assertEquals(1.1f, testView.scaleY, 0.01f)
+    }
+
+    @Test
+    fun testFling() {
+        val startTime = System.currentTimeMillis()
+
+        animator
+                .fling(DynamicAnimation.TRANSLATION_X, 1000f /* startVelocity */, flingConfig)
+                .fling(DynamicAnimation.TRANSLATION_Y, 500f, flingConfig)
+                .start()
+
+        val elapsedTimeSeconds = (System.currentTimeMillis() - startTime) / 1000f
+
+        // If the fling worked, the view should be somewhere between its starting position and the
+        // and the theoretical no-friction maximum of startVelocity (in pixels per second)
+        // multiplied by elapsedTimeSeconds. We can't calculate an exact expected location for a
+        // fling, so this is close enough.
+        assertTrue(testView.translationX > 0f)
+        assertTrue(testView.translationX < 1000f * elapsedTimeSeconds)
+        assertTrue(testView.translationY > 0f)
+        assertTrue(testView.translationY < 500f * elapsedTimeSeconds)
+    }
+
+    @Test
+    @Throws(InterruptedException::class)
+    @Ignore("Increasingly flaky")
+    fun testEndListenersAndActions() {
+        PhysicsAnimatorTestUtils.setAllAnimationsBlock(false)
+        animator
+                .spring(DynamicAnimation.TRANSLATION_X, 10f, springConfig)
+                .spring(DynamicAnimation.TRANSLATION_Y, 500f, springConfig)
+                .addEndListener(mockEndListener)
+                .withEndActions(mockEndAction::run)
+                .start()
+
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(animator, DynamicAnimation.TRANSLATION_X)
+
+        // Once TRANSLATION_X is done, the view should be at x = 10...
+        assertEquals(10f, testView.translationX, 1f)
+
+        // / ...TRANSLATION_Y should still be running...
+        assertTrue(animator.isPropertyAnimating(DynamicAnimation.TRANSLATION_Y))
+
+        // ...and our end listener should have been called with x = 10, velocity = 0, and allEnded =
+        // false since TRANSLATION_Y is still running.
+        verify(mockEndListener).onAnimationEnd(
+                testView,
+                DynamicAnimation.TRANSLATION_X,
+                wasFling = false,
+                canceled = false,
+                finalValue = 10f,
+                finalVelocity = 0f,
+                allRelevantPropertyAnimsEnded = false)
+        verifyNoMoreInteractions(mockEndListener)
+
+        // The end action should not have been run yet.
+        verify(mockEndAction, times(0)).run()
+
+        // Block until TRANSLATION_Y finishes.
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(animator, DynamicAnimation.TRANSLATION_Y)
+
+        // The view should have been moved.
+        assertEquals(10f, testView.translationX, 1f)
+        assertEquals(500f, testView.translationY, 1f)
+
+        // The end listener should have been called, this time with TRANSLATION_Y, y = 50, and
+        // allEnded = true.
+        verify(mockEndListener).onAnimationEnd(
+                testView,
+                DynamicAnimation.TRANSLATION_Y,
+                wasFling = false,
+                canceled = false,
+                finalValue = 500f,
+                finalVelocity = 0f,
+                allRelevantPropertyAnimsEnded = true)
+        verifyNoMoreInteractions(mockEndListener)
+
+        // Now that all properties are done animating, the end action should have been called.
+        verify(mockEndAction, times(1)).run()
+    }
+
+    @Test
+    fun testUpdateListeners() {
+        animator
+                .spring(DynamicAnimation.TRANSLATION_X, 100f, springConfig)
+                .spring(DynamicAnimation.TRANSLATION_Y, 50f, springConfig)
+                .addUpdateListener(object : UpdateListener<View> {
+                    override fun onAnimationUpdateForProperty(
+                        target: View,
+                        values: UpdateMap<View>
+                    ) {
+                        mockUpdateListener.onAnimationUpdateForProperty(target, values)
+                    }
+                })
+                .start()
+
+        verifyUpdateListenerCalls(animator, mockUpdateListener)
+    }
+
+    @Test
+    fun testListenersNotCalledOnSubsequentAnimations() {
+        animator
+                .spring(DynamicAnimation.TRANSLATION_X, 10f, springConfig)
+                .addUpdateListener(mockUpdateListener)
+                .addEndListener(mockEndListener)
+                .withEndActions(mockEndAction::run)
+                .start()
+
+        verifyUpdateListenerCalls(animator, mockUpdateListener)
+        verify(mockEndListener, times(1)).onAnimationEnd(
+                eq(testView), eq(DynamicAnimation.TRANSLATION_X), eq(false), eq(false), anyFloat(),
+                anyFloat(), eq(true))
+        verify(mockEndAction, times(1)).run()
+
+        animator
+                .spring(DynamicAnimation.TRANSLATION_X, 0f, springConfig)
+                .start()
+
+        // We didn't pass any of the listeners/actions to the subsequent animation, so they should
+        // never have been called.
+        verifyNoMoreInteractions(mockUpdateListener)
+        verifyNoMoreInteractions(mockEndListener)
+        verifyNoMoreInteractions(mockEndAction)
+    }
+
+    @Test
+    @Throws(InterruptedException::class)
+    fun testAnimationsUpdatedWhileInMotion() {
+        PhysicsAnimatorTestUtils.setAllAnimationsBlock(false)
+
+        // Spring towards x = 100f.
+        animator
+                .spring(
+                        DynamicAnimation.TRANSLATION_X,
+                        100f,
+                        springConfig)
+                .start()
+
+        // Block until it reaches x = 50f.
+        PhysicsAnimatorTestUtils.blockUntilFirstAnimationFrameWhereTrue(
+                animator) { view -> view.translationX > 50f }
+
+        // Translation X value at the time of reversing the animation to spring to x = 0f.
+        val reversalTranslationX = testView.translationX
+
+        // Spring back towards 0f.
+        animator
+                .spring(
+                        DynamicAnimation.TRANSLATION_X,
+                        0f,
+                        // Lower the stiffness to ensure the update listener receives at least one
+                        // update frame where the view has continued to move to the right.
+                        springConfig.apply { stiffness = SpringForce.STIFFNESS_LOW })
+                .start()
+
+        // Wait for TRANSLATION_X.
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(animator, DynamicAnimation.TRANSLATION_X)
+
+        // Verify that the animation continued past the X value at the time of reversal, before
+        // springing back. This ensures the change in direction was not abrupt.
+        verifyAnimationUpdateFrames(
+                animator, DynamicAnimation.TRANSLATION_X,
+                { u -> u.value > reversalTranslationX },
+                { u -> u.value < reversalTranslationX })
+
+        // Verify that the view is where it should be.
+        assertEquals(0f, testView.translationX, 1f)
+    }
+
+    @Test
+    @Throws(InterruptedException::class)
+    @Ignore("Sporadically flaking.")
+    fun testAnimationsUpdatedWhileInMotion_originalListenersStillCalled() {
+        PhysicsAnimatorTestUtils.setAllAnimationsBlock(false)
+
+        // Spring TRANSLATION_X to 100f, with an update and end listener provided.
+        animator
+                .spring(
+                        DynamicAnimation.TRANSLATION_X,
+                        100f,
+                        // Use very low stiffness to ensure that all of the keyframes we're testing
+                        // for are reported to the update listener.
+                        springConfig.apply { stiffness = SpringForce.STIFFNESS_VERY_LOW })
+                .addUpdateListener(mockUpdateListener)
+                .addEndListener(mockEndListener)
+                .start()
+
+        // Wait until the animation is halfway there.
+        PhysicsAnimatorTestUtils.blockUntilFirstAnimationFrameWhereTrue(
+                animator) { view -> view.translationX > 50f }
+
+        // The end listener shouldn't have been called since the animation hasn't ended.
+        verifyNoMoreInteractions(mockEndListener)
+
+        // Make sure we called the update listener with appropriate values.
+        verifyAnimationUpdateFrames(animator, DynamicAnimation.TRANSLATION_X,
+                { u -> u.value > 0f },
+                { u -> u.value >= 50f })
+
+        // Mock a second end listener.
+        val secondEndListener = mock(EndListener::class.java) as EndListener<View>
+        val secondUpdateListener = mock(UpdateListener::class.java) as UpdateListener<View>
+
+        // Start a new animation that springs both TRANSLATION_X and TRANSLATION_Y, and provide it
+        // the second end listener. This new end listener should be called for the end of
+        // TRANSLATION_X and TRANSLATION_Y, with allEnded = true when both have ended.
+        animator
+                .spring(DynamicAnimation.TRANSLATION_X, 200f, springConfig)
+                .spring(DynamicAnimation.TRANSLATION_Y, 4000f, springConfig)
+                .addUpdateListener(secondUpdateListener)
+                .addEndListener(secondEndListener)
+                .start()
+
+        // Wait for TRANSLATION_X to end.
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(animator, DynamicAnimation.TRANSLATION_X)
+
+        // The update listener provided to the initial animation call (the one that only animated
+        // TRANSLATION_X) should have been called with values on the way to x = 200f. This is
+        // because the second animation call updated the original TRANSLATION_X animation.
+        verifyAnimationUpdateFrames(
+                animator, DynamicAnimation.TRANSLATION_X,
+                { u -> u.value > 100f }, { u -> u.value >= 200f })
+
+        // The original end listener should also have been called, with allEnded = true since it was
+        // provided to an animator that animated only TRANSLATION_X.
+        verify(mockEndListener, times(1))
+                .onAnimationEnd(
+                        testView, DynamicAnimation.TRANSLATION_X,
+                        wasFling = false,
+                        canceled = false,
+                        finalValue = 200f,
+                        finalVelocity = 0f,
+                        allRelevantPropertyAnimsEnded = true)
+        verifyNoMoreInteractions(mockEndListener)
+
+        // The second end listener should have been called, but with allEnded = false since it was
+        // provided to an animator that animated both TRANSLATION_X and TRANSLATION_Y.
+        verify(secondEndListener, times(1))
+                .onAnimationEnd(testView, DynamicAnimation.TRANSLATION_X,
+                        wasFling = false,
+                        canceled = false,
+                        finalValue = 200f,
+                        finalVelocity = 0f,
+                        allRelevantPropertyAnimsEnded = false)
+        verifyNoMoreInteractions(secondEndListener)
+
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(animator, DynamicAnimation.TRANSLATION_Y)
+
+        // The original end listener shouldn't receive any callbacks because it was not provided to
+        // an animator that animated TRANSLATION_Y.
+        verifyNoMoreInteractions(mockEndListener)
+
+        verify(secondEndListener, times(1))
+                .onAnimationEnd(testView, DynamicAnimation.TRANSLATION_Y,
+                        wasFling = false,
+                        canceled = false,
+                        finalValue = 4000f,
+                        finalVelocity = 0f,
+                        allRelevantPropertyAnimsEnded = true)
+        verifyNoMoreInteractions(secondEndListener)
+    }
+
+    @Test
+    fun testFlingRespectsMinMax() {
+        animator
+                .fling(DynamicAnimation.TRANSLATION_X,
+                        startVelocity = 1000f,
+                        friction = 1.1f,
+                        max = 10f)
+                .addEndListener(mockEndListener)
+                .start()
+
+        // Ensure that the view stopped at x = 10f, and the end listener was called once with that
+        // value.
+        assertEquals(10f, testView.translationX, 1f)
+        verify(mockEndListener, times(1))
+                .onAnimationEnd(
+                        eq(testView), eq(DynamicAnimation.TRANSLATION_X), eq(true), eq(false),
+                        eq(10f), anyFloat(), eq(true))
+
+        animator
+                .fling(
+                        DynamicAnimation.TRANSLATION_X,
+                        startVelocity = -1000f,
+                        friction = 1.1f,
+                        min = -5f)
+                .addEndListener(mockEndListener)
+                .start()
+
+        // Ensure that the view stopped at x = -5f, and the end listener was called once with that
+        // value.
+        assertEquals(-5f, testView.translationX, 1f)
+        verify(mockEndListener, times(1))
+                .onAnimationEnd(
+                        eq(testView), eq(DynamicAnimation.TRANSLATION_X), eq(true), eq(false),
+                        eq(-5f), anyFloat(), eq(true))
+    }
+
+    @Test
+    fun testIsPropertyAnimating() {
+        PhysicsAnimatorTestUtils.setAllAnimationsBlock(false)
+
+        testView.physicsAnimator
+                .spring(DynamicAnimation.TRANSLATION_X, 500f, springConfig)
+                .fling(DynamicAnimation.TRANSLATION_Y, 10f, flingConfig)
+                .spring(DynamicAnimation.TRANSLATION_Z, 1000f, springConfig)
+                .start()
+
+        // All of the properties we just started should be animating.
+        assertTrue(testView.physicsAnimator.isPropertyAnimating(DynamicAnimation.TRANSLATION_X))
+        assertTrue(testView.physicsAnimator.isPropertyAnimating(DynamicAnimation.TRANSLATION_Y))
+        assertTrue(testView.physicsAnimator.isPropertyAnimating(DynamicAnimation.TRANSLATION_Z))
+
+        // Block until x and y end.
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(testView.physicsAnimator,
+                DynamicAnimation.TRANSLATION_X, DynamicAnimation.TRANSLATION_Y)
+
+        // Verify that x and y are no longer animating, but that Z is (it's springing to 1000f).
+        assertFalse(testView.physicsAnimator.isPropertyAnimating(DynamicAnimation.TRANSLATION_X))
+        assertFalse(testView.physicsAnimator.isPropertyAnimating(DynamicAnimation.TRANSLATION_Y))
+        assertTrue(testView.physicsAnimator.isPropertyAnimating(DynamicAnimation.TRANSLATION_Z))
+
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_Z)
+
+        assertFalse(testView.physicsAnimator.isPropertyAnimating(DynamicAnimation.TRANSLATION_X))
+        assertFalse(testView.physicsAnimator.isPropertyAnimating(DynamicAnimation.TRANSLATION_Y))
+        assertFalse(testView.physicsAnimator.isPropertyAnimating(DynamicAnimation.TRANSLATION_Z))
+    }
+
+    @Test
+    fun testExtensionProperty() {
+        testView
+                .physicsAnimator
+                .spring(DynamicAnimation.TRANSLATION_X, 200f)
+                .start()
+
+        assertEquals(200f, testView.translationX, 1f)
+    }
+
+    @Test
+    @Ignore("Sporadically flaking.")
+    fun testFlingThenSpring() {
+        PhysicsAnimatorTestUtils.setAllAnimationsBlock(false)
+
+        // Start at 500f and fling hard to the left. We should quickly reach the 250f minimum, fly
+        // past it since there's so much velocity remaining, then spring back to 250f.
+        testView.translationX = 500f
+        animator
+                .flingThenSpring(
+                        DynamicAnimation.TRANSLATION_X,
+                        -5000f,
+                        flingConfig.apply { min = 250f },
+                        springConfig)
+                .addUpdateListener(mockUpdateListener)
+                .addEndListener(mockEndListener)
+                .withEndActions(mockEndAction::run)
+                .start()
+
+        // Block until we pass the minimum.
+        PhysicsAnimatorTestUtils.blockUntilFirstAnimationFrameWhereTrue(
+                animator) { v -> v.translationX <= 250f }
+
+        // Double check that the view is there.
+        assertTrue(testView.translationX <= 250f)
+
+        // The update listener should have been called with a value < 500f, and then a value less
+        // than or equal to the 250f minimum.
+        verifyAnimationUpdateFrames(animator, DynamicAnimation.TRANSLATION_X,
+                { u -> u.value < 500f },
+                { u -> u.value <= 250f })
+
+        // Despite the fact that the fling has ended, the end listener shouldn't have been called
+        // since we're about to begin springing the same property.
+        verifyNoMoreInteractions(mockEndListener)
+        verifyNoMoreInteractions(mockEndAction)
+
+        // Wait for the spring to finish.
+        PhysicsAnimatorTestUtils.blockUntilAnimationsEnd(DynamicAnimation.TRANSLATION_X)
+
+        // Make sure we continued past 250f since the spring should have been started with some
+        // remaining negative velocity from the fling.
+        verifyAnimationUpdateFrames(animator, DynamicAnimation.TRANSLATION_X,
+                { u -> u.value < 250f })
+
+        // At this point, the animation end listener should have been called once, and only once,
+        // when the spring ended at 250f.
+        verify(mockEndListener).onAnimationEnd(testView, DynamicAnimation.TRANSLATION_X,
+                wasFling = false,
+                canceled = false,
+                finalValue = 250f,
+                finalVelocity = 0f,
+                allRelevantPropertyAnimsEnded = true)
+        verifyNoMoreInteractions(mockEndListener)
+
+        // The end action should also have been called once.
+        verify(mockEndAction, times(1)).run()
+        verifyNoMoreInteractions(mockEndAction)
+
+        assertEquals(250f, testView.translationX)
+    }
+
+    @Test
+    fun testFlingThenSpring_objectOutsideFlingBounds() {
+        // Start the view at x = -500, well outside the fling bounds of min = 0f, with strong
+        // negative velocity.
+        testView.translationX = -500f
+        animator
+                .flingThenSpring(
+                        DynamicAnimation.TRANSLATION_X,
+                        -5000f,
+                        flingConfig.apply { min = 0f },
+                        springConfig)
+                .addUpdateListener(mockUpdateListener)
+                .addEndListener(mockEndListener)
+                .withEndActions(mockEndAction::run)
+                .start()
+
+        // The initial -5000f velocity should result in frames to the left of -500f before the view
+        // springs back towards 0f.
+        verifyAnimationUpdateFrames(
+                animator, DynamicAnimation.TRANSLATION_X,
+                { u -> u.value < -500f },
+                { u -> u.value > -500f })
+
+        // We should end up at the fling min.
+        assertEquals(0f, testView.translationX, 1f)
+    }
+
+    @Test
+    fun testFlingToMinMaxThenSpring() {
+        // Start at x = 500f.
+        testView.translationX = 500f
+
+        // Fling to the left at the very sad rate of -1 pixels per second. That won't get us much of
+        // anywhere, and certainly not to the 0f min.
+        animator
+                // Good thing we have flingToMinMaxThenSpring!
+                .flingThenSpring(
+                        DynamicAnimation.TRANSLATION_X,
+                        -10000f,
+                        flingConfig.apply { min = 0f },
+                        springConfig,
+                        flingMustReachMinOrMax = true)
+                .addUpdateListener(mockUpdateListener)
+                .addEndListener(mockEndListener)
+                .withEndActions(mockEndAction::run)
+                .start()
+
+        // Thanks, flingToMinMaxThenSpring, for adding enough velocity to get us here.
+        assertEquals(0f, testView.translationX, 1f)
+    }
+
+    /**
+     * Verifies that the calls to the mock update listener match the animation update frames
+     * reported by the test internal listener, in order.
+     */
+    private fun <T : Any> verifyUpdateListenerCalls(
+        animator: PhysicsAnimator<T>,
+        mockUpdateListener: UpdateListener<T>
+    ) {
+        val updates = getAnimationUpdateFrames(animator)
+
+        for (invocation in Mockito.mockingDetails(mockUpdateListener).invocations) {
+
+            // Grab the update map of Property -> AnimationUpdate that was passed to the mock update
+            // listener.
+            val updateMap = invocation.arguments[1]
+                    as ArrayMap<FloatPropertyCompat<in T>, PhysicsAnimator.AnimationUpdate>
+
+            //
+            for ((property, update) in updateMap) {
+                val updatesForProperty = updates[property]!!
+
+                // This update should be the next one in the list for this property.
+                if (update != updatesForProperty[0]) {
+                    Assert.fail("The update listener was called with an unexpected value: $update.")
+                }
+
+                updatesForProperty.remove(update)
+            }
+
+            val target = animator.weakTarget.get()
+            assertNotNull(target)
+            // Mark this invocation verified.
+            verify(mockUpdateListener).onAnimationUpdateForProperty(target!!, updateMap)
+        }
+
+        verifyNoMoreInteractions(mockUpdateListener)
+
+        // Since we were removing values as matching invocations were found, there should no longer
+        // be any values remaining. If there are, it means the update listener wasn't notified when
+        // it should have been.
+        assertEquals(0,
+                updates.values.fold(0, { count, propertyUpdates -> count + propertyUpdates.size }))
+
+        clearAnimationUpdateFrames(animator)
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/magnetictarget/MagnetizedObjectTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/magnetictarget/MagnetizedObjectTest.kt
new file mode 100644
index 0000000..fe53641
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/magnetictarget/MagnetizedObjectTest.kt
@@ -0,0 +1,454 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.common.magnetictarget
+
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.MotionEvent
+import android.view.View
+import androidx.dynamicanimation.animation.FloatPropertyCompat
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.animation.PhysicsAnimatorTestUtils
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.anyFloat
+import org.mockito.Mockito
+import org.mockito.Mockito.`when`
+import org.mockito.Mockito.doAnswer
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.times
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoMoreInteractions
+
+@TestableLooper.RunWithLooper
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class MagnetizedObjectTest : SysuiTestCase() {
+    /** Incrementing value for fake MotionEvent timestamps. */
+    private var time = 0L
+
+    /** Value to add to each new MotionEvent's timestamp. */
+    private var timeStep = 100
+
+    private val underlyingObject = this
+
+    private lateinit var targetView: View
+
+    private val targetSize = 200
+    private val targetCenterX = 500
+    private val targetCenterY = 900
+    private val magneticFieldRadius = 200
+
+    private var objectX = 0f
+    private var objectY = 0f
+    private val objectSize = 50f
+
+    private lateinit var magneticTarget: MagnetizedObject.MagneticTarget
+    private lateinit var magnetizedObject: MagnetizedObject<*>
+    private lateinit var magnetListener: MagnetizedObject.MagnetListener
+
+    private val xProperty = object : FloatPropertyCompat<MagnetizedObjectTest>("") {
+        override fun setValue(target: MagnetizedObjectTest?, value: Float) {
+            objectX = value
+        }
+        override fun getValue(target: MagnetizedObjectTest?): Float {
+            return objectX
+        }
+    }
+
+    private val yProperty = object : FloatPropertyCompat<MagnetizedObjectTest>("") {
+        override fun setValue(target: MagnetizedObjectTest?, value: Float) {
+            objectY = value
+        }
+
+        override fun getValue(target: MagnetizedObjectTest?): Float {
+            return objectY
+        }
+    }
+
+    @Before
+    fun setup() {
+        PhysicsAnimatorTestUtils.prepareForTest()
+
+        // Mock the view since a real view's getLocationOnScreen() won't work unless it's attached
+        // to a real window (it'll always return x = 0, y = 0).
+        targetView = mock(View::class.java)
+        `when`(targetView.context).thenReturn(context)
+
+        // The mock target view will pretend that it's 200x200, and at (400, 800). This means it's
+        // occupying the bounds (400, 800, 600, 1000) and it has a center of (500, 900).
+        `when`(targetView.width).thenReturn(targetSize)  // width = 200
+        `when`(targetView.height).thenReturn(targetSize) // height = 200
+        doAnswer { invocation ->
+            (invocation.arguments[0] as IntArray).also { location ->
+                // Return the top left of the target.
+                location[0] = targetCenterX - targetSize / 2 // x = 400
+                location[1] = targetCenterY - targetSize / 2 // y = 800
+            }
+        }.`when`(targetView).getLocationOnScreen(ArgumentMatchers.any())
+        doAnswer { invocation ->
+            (invocation.arguments[0] as Runnable).run()
+            true
+        }.`when`(targetView).post(ArgumentMatchers.any())
+        `when`(targetView.context).thenReturn(context)
+
+        magneticTarget = MagnetizedObject.MagneticTarget(targetView, magneticFieldRadius)
+
+        magnetListener = mock(MagnetizedObject.MagnetListener::class.java)
+        magnetizedObject = object : MagnetizedObject<MagnetizedObjectTest>(
+                context, underlyingObject, xProperty, yProperty) {
+            override fun getWidth(underlyingObject: MagnetizedObjectTest): Float {
+                return objectSize
+            }
+
+            override fun getHeight(underlyingObject: MagnetizedObjectTest): Float {
+                return objectSize
+            }
+
+            override fun getLocationOnScreen(
+                underlyingObject: MagnetizedObjectTest,
+                loc: IntArray
+            ) {
+                loc[0] = objectX.toInt()
+                loc[1] = objectY.toInt() }
+        }
+
+        magnetizedObject.magnetListener = magnetListener
+        magnetizedObject.addTarget(magneticTarget)
+
+        timeStep = 100
+    }
+
+    @Test
+    fun testMotionEventConsumption() {
+        // Start at (0, 0). No magnetic field here.
+        assertFalse(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = 0, y = 0, action = MotionEvent.ACTION_DOWN)))
+
+        // Move to (400, 400), which is solidly outside the magnetic field.
+        assertFalse(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = 200, y = 200)))
+
+        // Move to (305, 705). This would be in the magnetic field radius if magnetic fields were
+        // square. It's not, because they're not.
+        assertFalse(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = targetCenterX - magneticFieldRadius + 5,
+                y = targetCenterY - magneticFieldRadius + 5)))
+
+        // Move to (400, 800). That's solidly in the radius so the magnetic target should begin
+        // consuming events.
+        assertTrue(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = targetCenterX - 100,
+                y = targetCenterY - 100)))
+
+        // Release at (400, 800). Since we're in the magnetic target, it should return true and
+        // consume the ACTION_UP.
+        assertTrue(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = 400, y = 800, action = MotionEvent.ACTION_UP)))
+
+        // ACTION_DOWN outside the field.
+        assertFalse(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = 200, y = 200, action = MotionEvent.ACTION_DOWN)))
+
+        // Move to the center. We absolutely should consume events there.
+        assertTrue(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = targetCenterX,
+                y = targetCenterY)))
+
+        // Drag out to (0, 0) and we should be returning false again.
+        assertFalse(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = 0, y = 0)))
+
+        // The ACTION_UP event shouldn't be consumed either since it's outside the field.
+        assertFalse(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = 0, y = 0, action = MotionEvent.ACTION_UP)))
+    }
+
+    @Test
+    fun testMotionEventConsumption_downInMagneticField() {
+        // We should not consume DOWN events even if they occur in the field.
+        assertFalse(magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = targetCenterX, y = targetCenterY, action = MotionEvent.ACTION_DOWN)))
+    }
+
+    @Test
+    fun testMoveIntoAroundAndOutOfMagneticField() {
+        // Move around but don't touch the magnetic field.
+        dispatchMotionEvents(
+                getMotionEvent(x = 0, y = 0, action = MotionEvent.ACTION_DOWN),
+                getMotionEvent(x = 100, y = 100),
+                getMotionEvent(x = 200, y = 200))
+
+        // You can't become unstuck if you were never stuck in the first place.
+        verify(magnetListener, never()).onStuckToTarget(magneticTarget)
+        verify(magnetListener, never()).onUnstuckFromTarget(
+                eq(magneticTarget), ArgumentMatchers.anyFloat(), ArgumentMatchers.anyFloat(),
+                eq(false))
+
+        // Move into and then around inside the magnetic field.
+        dispatchMotionEvents(
+                getMotionEvent(x = targetCenterX - 100, y = targetCenterY - 100),
+                getMotionEvent(x = targetCenterX, y = targetCenterY),
+                getMotionEvent(x = targetCenterX + 100, y = targetCenterY + 100))
+
+        // We should only have received one call to onStuckToTarget and none to unstuck.
+        verify(magnetListener, times(1)).onStuckToTarget(magneticTarget)
+        verify(magnetListener, never()).onUnstuckFromTarget(
+                eq(magneticTarget), ArgumentMatchers.anyFloat(), ArgumentMatchers.anyFloat(),
+                eq(false))
+
+        // Move out of the field and then release.
+        dispatchMotionEvents(
+                getMotionEvent(x = 100, y = 100),
+                getMotionEvent(x = 100, y = 100, action = MotionEvent.ACTION_UP))
+
+        // We should have received one unstuck call and no more stuck calls. We also should never
+        // have received an onReleasedInTarget call.
+        verify(magnetListener, times(1)).onUnstuckFromTarget(
+                eq(magneticTarget), ArgumentMatchers.anyFloat(), ArgumentMatchers.anyFloat(),
+                eq(false))
+        verifyNoMoreInteractions(magnetListener)
+    }
+
+    @Test
+    fun testMoveIntoOutOfAndBackIntoMagneticField() {
+        // Move into the field
+        dispatchMotionEvents(
+                getMotionEvent(
+                        x = targetCenterX - magneticFieldRadius,
+                        y = targetCenterY - magneticFieldRadius,
+                        action = MotionEvent.ACTION_DOWN),
+                getMotionEvent(
+                        x = targetCenterX, y = targetCenterY))
+
+        verify(magnetListener, times(1)).onStuckToTarget(magneticTarget)
+        verify(magnetListener, never()).onReleasedInTarget(magneticTarget)
+
+        // Move back out.
+        dispatchMotionEvents(
+                getMotionEvent(
+                        x = targetCenterX - magneticFieldRadius,
+                        y = targetCenterY - magneticFieldRadius))
+
+        verify(magnetListener, times(1)).onUnstuckFromTarget(
+                eq(magneticTarget), ArgumentMatchers.anyFloat(), ArgumentMatchers.anyFloat(),
+                eq(false))
+        verify(magnetListener, never()).onReleasedInTarget(magneticTarget)
+
+        // Move in again and release in the magnetic field.
+        dispatchMotionEvents(
+                getMotionEvent(x = targetCenterX - 100, y = targetCenterY - 100),
+                getMotionEvent(x = targetCenterX + 50, y = targetCenterY + 50),
+                getMotionEvent(x = targetCenterX, y = targetCenterY),
+                getMotionEvent(
+                        x = targetCenterX, y = targetCenterY, action = MotionEvent.ACTION_UP))
+
+        verify(magnetListener, times(2)).onStuckToTarget(magneticTarget)
+        verify(magnetListener).onReleasedInTarget(magneticTarget)
+        verifyNoMoreInteractions(magnetListener)
+    }
+
+    @Test
+    fun testFlingTowardsTarget_towardsTarget() {
+        timeStep = 10
+
+        // Forcefully fling the object towards the target (but never touch the magnetic field).
+        dispatchMotionEvents(
+                getMotionEvent(
+                        x = targetCenterX,
+                        y = 0,
+                        action = MotionEvent.ACTION_DOWN),
+                getMotionEvent(
+                        x = targetCenterX,
+                        y = targetCenterY / 2),
+                getMotionEvent(
+                        x = targetCenterX,
+                        y = targetCenterY - magneticFieldRadius * 2,
+                        action = MotionEvent.ACTION_UP))
+
+        // Nevertheless it should have ended up stuck to the target.
+        verify(magnetListener, times(1)).onStuckToTarget(magneticTarget)
+    }
+
+    @Test
+    fun testFlingTowardsTarget_towardsButTooSlow() {
+        // Very, very slowly fling the object towards the target (but never touch the magnetic
+        // field). This value is only used to create MotionEvent timestamps, it will not block the
+        // test for 10 seconds.
+        timeStep = 10000
+        dispatchMotionEvents(
+                getMotionEvent(
+                        x = targetCenterX,
+                        y = 0,
+                        action = MotionEvent.ACTION_DOWN),
+                getMotionEvent(
+                        x = targetCenterX,
+                        y = targetCenterY / 2),
+                getMotionEvent(
+                        x = targetCenterX,
+                        y = targetCenterY - magneticFieldRadius * 2,
+                        action = MotionEvent.ACTION_UP))
+
+        // No sticking should have occurred.
+        verifyNoMoreInteractions(magnetListener)
+    }
+
+    @Test
+    fun testFlingTowardsTarget_missTarget() {
+        timeStep = 10
+        // Forcefully fling the object down, but not towards the target.
+        dispatchMotionEvents(
+                getMotionEvent(
+                        x = 0,
+                        y = 0,
+                        action = MotionEvent.ACTION_DOWN),
+                getMotionEvent(
+                        x = 0,
+                        y = targetCenterY / 2),
+                getMotionEvent(
+                        x = 0,
+                        y = targetCenterY - magneticFieldRadius * 2,
+                        action = MotionEvent.ACTION_UP))
+
+        verifyNoMoreInteractions(magnetListener)
+    }
+
+    @Test
+    fun testMagnetAnimation() {
+        // Make sure the object starts at (0, 0).
+        assertEquals(0f, objectX)
+        assertEquals(0f, objectY)
+
+        // Trigger the magnet animation, and block the test until it ends.
+        PhysicsAnimatorTestUtils.setAllAnimationsBlock(true)
+        magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = targetCenterX - 250,
+                y = targetCenterY - 250,
+                action = MotionEvent.ACTION_DOWN))
+
+        magnetizedObject.maybeConsumeMotionEvent(getMotionEvent(
+                x = targetCenterX,
+                y = targetCenterY))
+
+        // The object's (top-left) position should now position it centered over the target.
+        assertEquals(targetCenterX - objectSize / 2, objectX)
+        assertEquals(targetCenterY - objectSize / 2, objectY)
+    }
+
+    @Test
+    fun testMultipleTargets() {
+        val secondMagneticTarget = getSecondMagneticTarget()
+
+        // Drag into the second target.
+        dispatchMotionEvents(
+                getMotionEvent(x = 0, y = 0, action = MotionEvent.ACTION_DOWN),
+                getMotionEvent(x = 100, y = 900))
+
+        // Verify that we received an onStuck for the second target, and no others.
+        verify(magnetListener).onStuckToTarget(secondMagneticTarget)
+        verifyNoMoreInteractions(magnetListener)
+
+        // Drag into the original target.
+        dispatchMotionEvents(
+                getMotionEvent(x = 0, y = 0),
+                getMotionEvent(x = 500, y = 900))
+
+        // We should have unstuck from the second one and stuck into the original one.
+        verify(magnetListener).onUnstuckFromTarget(
+                eq(secondMagneticTarget), anyFloat(), anyFloat(), eq(false))
+        verify(magnetListener).onStuckToTarget(magneticTarget)
+        verifyNoMoreInteractions(magnetListener)
+    }
+
+    @Test
+    fun testMultipleTargets_flingIntoSecond() {
+        val secondMagneticTarget = getSecondMagneticTarget()
+
+        timeStep = 10
+
+        // Fling towards the second target.
+        dispatchMotionEvents(
+                getMotionEvent(x = 100, y = 0, action = MotionEvent.ACTION_DOWN),
+                getMotionEvent(x = 100, y = 350),
+                getMotionEvent(x = 100, y = 650, action = MotionEvent.ACTION_UP))
+
+        // Verify that we received an onStuck for the second target.
+        verify(magnetListener).onStuckToTarget(secondMagneticTarget)
+
+        // Fling towards the first target.
+        dispatchMotionEvents(
+                getMotionEvent(x = 300, y = 0, action = MotionEvent.ACTION_DOWN),
+                getMotionEvent(x = 400, y = 350),
+                getMotionEvent(x = 500, y = 650, action = MotionEvent.ACTION_UP))
+
+        // Verify that we received onStuck for the original target.
+        verify(magnetListener).onStuckToTarget(magneticTarget)
+    }
+
+    private fun getSecondMagneticTarget(): MagnetizedObject.MagneticTarget {
+        // The first target view is at bounds (400, 800, 600, 1000) and it has a center of
+        // (500, 900). We'll add a second one at bounds (0, 800, 200, 1000) with center (100, 900).
+        val secondTargetView = mock(View::class.java)
+        var secondTargetCenterX = 100
+        var secondTargetCenterY = 900
+
+        `when`(secondTargetView.context).thenReturn(context)
+        `when`(secondTargetView.width).thenReturn(targetSize)  // width = 200
+        `when`(secondTargetView.height).thenReturn(targetSize) // height = 200
+        doAnswer { invocation ->
+            (invocation.arguments[0] as Runnable).run()
+            true
+        }.`when`(secondTargetView).post(ArgumentMatchers.any())
+        doAnswer { invocation ->
+            (invocation.arguments[0] as IntArray).also { location ->
+                // Return the top left of the target.
+                location[0] = secondTargetCenterX - targetSize / 2 // x = 0
+                location[1] = secondTargetCenterY - targetSize / 2 // y = 800
+            }
+        }.`when`(secondTargetView).getLocationOnScreen(ArgumentMatchers.any())
+
+        return magnetizedObject.addTarget(secondTargetView, magneticFieldRadius)
+    }
+
+    /**
+     * Return a MotionEvent at the given coordinates, with the given action (or MOVE by default).
+     * The event's time fields will be incremented by 10ms each time this is called, so tha
+     * VelocityTracker works.
+     */
+    private fun getMotionEvent(
+        x: Int,
+        y: Int,
+        action: Int = MotionEvent.ACTION_MOVE
+    ): MotionEvent {
+        return MotionEvent.obtain(time, time, action, x.toFloat(), y.toFloat(), 0)
+                .also { time += timeStep }
+    }
+
+    /** Dispatch all of the provided events to the target view. */
+    private fun dispatchMotionEvents(vararg events: MotionEvent) {
+        events.forEach { magnetizedObject.maybeConsumeMotionEvent(it) }
+    }
+
+    /** Prevents Kotlin from being mad that eq() is nullable. */
+    private fun <T> eq(value: T): T = Mockito.eq(value) ?: value
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
new file mode 100644
index 0000000..7d51886
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipAnimationControllerTest.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2020 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.systemui.pip;
+
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_LEAVE_PIP;
+import static com.android.wm.shell.pip.PipAnimationController.TRANSITION_DIRECTION_TO_PIP;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.SurfaceControl;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.pip.PipAnimationController;
+import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
+import com.android.wm.shell.pip.PipTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests against {@link PipAnimationController} to ensure that it sends the right callbacks
+ * depending on the various interactions.
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class PipAnimationControllerTest extends PipTestCase {
+
+    private PipAnimationController mPipAnimationController;
+
+    private SurfaceControl mLeash;
+
+    @Mock
+    private PipAnimationController.PipAnimationCallback mPipAnimationCallback;
+
+    @Before
+    public void setUp() throws Exception {
+        mPipAnimationController = new PipAnimationController(
+                new PipSurfaceTransactionHelper(mContext));
+        mLeash = new SurfaceControl.Builder()
+                .setContainerLayer()
+                .setName("FakeLeash")
+                .build();
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void getAnimator_withAlpha_returnFloatAnimator() {
+        final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
+                .getAnimator(mLeash, new Rect(), 0f, 1f);
+
+        assertEquals("Expect ANIM_TYPE_ALPHA animation",
+                animator.getAnimationType(), PipAnimationController.ANIM_TYPE_ALPHA);
+    }
+
+    @Test
+    public void getAnimator_withBounds_returnBoundsAnimator() {
+        final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
+                .getAnimator(mLeash, new Rect(), new Rect(), null, TRANSITION_DIRECTION_TO_PIP);
+
+        assertEquals("Expect ANIM_TYPE_BOUNDS animation",
+                animator.getAnimationType(), PipAnimationController.ANIM_TYPE_BOUNDS);
+    }
+
+    @Test
+    public void getAnimator_whenSameTypeRunning_updateExistingAnimator() {
+        final Rect startValue = new Rect(0, 0, 100, 100);
+        final Rect endValue1 = new Rect(100, 100, 200, 200);
+        final Rect endValue2 = new Rect(200, 200, 300, 300);
+        final PipAnimationController.PipTransitionAnimator oldAnimator = mPipAnimationController
+                .getAnimator(mLeash, startValue, endValue1, null, TRANSITION_DIRECTION_TO_PIP);
+        oldAnimator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new);
+        oldAnimator.start();
+
+        final PipAnimationController.PipTransitionAnimator newAnimator = mPipAnimationController
+                .getAnimator(mLeash, startValue, endValue2, null, TRANSITION_DIRECTION_TO_PIP);
+
+        assertEquals("getAnimator with same type returns same animator",
+                oldAnimator, newAnimator);
+        assertEquals("getAnimator with same type updates end value",
+                endValue2, newAnimator.getEndValue());
+    }
+
+    @Test
+    public void getAnimator_setTransitionDirection() {
+        PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
+                .getAnimator(mLeash, new Rect(), 0f, 1f)
+                .setTransitionDirection(TRANSITION_DIRECTION_TO_PIP);
+        assertEquals("Transition to PiP mode",
+                animator.getTransitionDirection(), TRANSITION_DIRECTION_TO_PIP);
+
+        animator = mPipAnimationController
+                .getAnimator(mLeash, new Rect(), 0f, 1f)
+                .setTransitionDirection(TRANSITION_DIRECTION_LEAVE_PIP);
+        assertEquals("Transition to fullscreen mode",
+                animator.getTransitionDirection(), TRANSITION_DIRECTION_LEAVE_PIP);
+    }
+
+    @Test
+    @SuppressWarnings("unchecked")
+    public void pipTransitionAnimator_updateEndValue() {
+        final Rect startValue = new Rect(0, 0, 100, 100);
+        final Rect endValue1 = new Rect(100, 100, 200, 200);
+        final Rect endValue2 = new Rect(200, 200, 300, 300);
+        final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
+                .getAnimator(mLeash, startValue, endValue1, null, TRANSITION_DIRECTION_TO_PIP);
+
+        animator.updateEndValue(endValue2);
+
+        assertEquals("updateEndValue updates end value", animator.getEndValue(), endValue2);
+    }
+
+    @Test
+    public void pipTransitionAnimator_setPipAnimationCallback() {
+        final Rect startValue = new Rect(0, 0, 100, 100);
+        final Rect endValue = new Rect(100, 100, 200, 200);
+        final PipAnimationController.PipTransitionAnimator animator = mPipAnimationController
+                .getAnimator(mLeash, startValue, endValue, null, TRANSITION_DIRECTION_TO_PIP);
+        animator.setSurfaceControlTransactionFactory(DummySurfaceControlTx::new);
+
+        animator.setPipAnimationCallback(mPipAnimationCallback);
+
+        // onAnimationStart triggers onPipAnimationStart
+        animator.onAnimationStart(animator);
+        verify(mPipAnimationCallback).onPipAnimationStart(animator);
+
+        // onAnimationCancel triggers onPipAnimationCancel
+        animator.onAnimationCancel(animator);
+        verify(mPipAnimationCallback).onPipAnimationCancel(animator);
+
+        // onAnimationEnd triggers onPipAnimationEnd
+        animator.onAnimationEnd(animator);
+        verify(mPipAnimationCallback).onPipAnimationEnd(any(SurfaceControl.Transaction.class),
+                eq(animator));
+    }
+
+    /**
+     * A dummy {@link SurfaceControl.Transaction} class.
+     * This is created as {@link Mock} does not support method chaining.
+     */
+    public static class DummySurfaceControlTx extends SurfaceControl.Transaction {
+        @Override
+        public SurfaceControl.Transaction setAlpha(SurfaceControl leash, float alpha) {
+            return this;
+        }
+
+        @Override
+        public SurfaceControl.Transaction setPosition(SurfaceControl leash, float x, float y) {
+            return this;
+        }
+
+        @Override
+        public SurfaceControl.Transaction setWindowCrop(SurfaceControl leash, int w, int h) {
+            return this;
+        }
+
+        @Override
+        public SurfaceControl.Transaction setCornerRadius(SurfaceControl leash, float radius) {
+            return this;
+        }
+
+        @Override
+        public SurfaceControl.Transaction setMatrix(SurfaceControl leash, Matrix matrix,
+                float[] float9) {
+            return this;
+        }
+
+        @Override
+        public void apply() {}
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
new file mode 100644
index 0000000..f514b0b
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipBoundsHandlerTest.java
@@ -0,0 +1,348 @@
+/*
+ * Copyright (C) 2020 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.systemui.pip;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ComponentName;
+import android.graphics.Rect;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableResources;
+import android.util.Size;
+import android.view.DisplayInfo;
+import android.view.Gravity;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.pip.PipBoundsHandler;
+import com.android.wm.shell.pip.PipTestCase;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Unit tests against {@link PipBoundsHandler}, including but not limited to:
+ * - default/movement bounds
+ * - save/restore PiP position on application lifecycle
+ * - save/restore PiP position on screen rotation
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class PipBoundsHandlerTest extends PipTestCase {
+    private static final int ROUNDING_ERROR_MARGIN = 16;
+    private static final float ASPECT_RATIO_ERROR_MARGIN = 0.01f;
+    private static final float DEFAULT_ASPECT_RATIO = 1f;
+    private static final float MIN_ASPECT_RATIO = 0.5f;
+    private static final float MAX_ASPECT_RATIO = 2f;
+    private static final Rect EMPTY_CURRENT_BOUNDS = null;
+    private static final Size EMPTY_MINIMAL_SIZE = null;
+
+    private PipBoundsHandler mPipBoundsHandler;
+    private DisplayInfo mDefaultDisplayInfo;
+    private ComponentName mTestComponentName1;
+    private ComponentName mTestComponentName2;
+
+    @Before
+    public void setUp() throws Exception {
+        initializeMockResources();
+        mPipBoundsHandler = new PipBoundsHandler(mContext);
+        mTestComponentName1 = new ComponentName(mContext, "component1");
+        mTestComponentName2 = new ComponentName(mContext, "component2");
+
+        mPipBoundsHandler.onDisplayInfoChanged(mDefaultDisplayInfo);
+    }
+
+    private void initializeMockResources() {
+        final TestableResources res = mContext.getOrCreateTestableResources();
+        res.addOverride(
+                com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio,
+                DEFAULT_ASPECT_RATIO);
+        res.addOverride(
+                com.android.internal.R.integer.config_defaultPictureInPictureGravity,
+                Gravity.END | Gravity.BOTTOM);
+        res.addOverride(
+                com.android.internal.R.dimen.default_minimal_size_pip_resizable_task, 100);
+        res.addOverride(
+                com.android.internal.R.string.config_defaultPictureInPictureScreenEdgeInsets,
+                "16x16");
+        res.addOverride(
+                com.android.internal.R.dimen.config_pictureInPictureMinAspectRatio,
+                MIN_ASPECT_RATIO);
+        res.addOverride(
+                com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio,
+                MAX_ASPECT_RATIO);
+
+        mDefaultDisplayInfo = new DisplayInfo();
+        mDefaultDisplayInfo.displayId = 1;
+        mDefaultDisplayInfo.logicalWidth = 1000;
+        mDefaultDisplayInfo.logicalHeight = 1500;
+    }
+
+    @Test
+    public void getDefaultAspectRatio() {
+        assertEquals("Default aspect ratio matches resources",
+                DEFAULT_ASPECT_RATIO, mPipBoundsHandler.getDefaultAspectRatio(),
+                ASPECT_RATIO_ERROR_MARGIN);
+    }
+
+    @Test
+    public void onConfigurationChanged_reloadResources() {
+        final float newDefaultAspectRatio = (DEFAULT_ASPECT_RATIO + MAX_ASPECT_RATIO) / 2;
+        final TestableResources res = mContext.getOrCreateTestableResources();
+        res.addOverride(com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio,
+                newDefaultAspectRatio);
+
+        mPipBoundsHandler.onConfigurationChanged(mContext);
+
+        assertEquals("Default aspect ratio should be reloaded",
+                mPipBoundsHandler.getDefaultAspectRatio(), newDefaultAspectRatio,
+                ASPECT_RATIO_ERROR_MARGIN);
+    }
+
+    @Test
+    public void getDestinationBounds_returnBoundsMatchesAspectRatio() {
+        final float[] aspectRatios = new float[] {
+                (MIN_ASPECT_RATIO + DEFAULT_ASPECT_RATIO) / 2,
+                DEFAULT_ASPECT_RATIO,
+                (MAX_ASPECT_RATIO + DEFAULT_ASPECT_RATIO) / 2
+        };
+        for (float aspectRatio : aspectRatios) {
+            final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
+                    mTestComponentName1, aspectRatio, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+            final float actualAspectRatio =
+                    destinationBounds.width() / (destinationBounds.height() * 1f);
+            assertEquals("Destination bounds matches the given aspect ratio",
+                    aspectRatio, actualAspectRatio, ASPECT_RATIO_ERROR_MARGIN);
+        }
+    }
+
+    @Test
+    public void getDestinationBounds_invalidAspectRatio_returnsDefaultAspectRatio() {
+        final float[] invalidAspectRatios = new float[] {
+                MIN_ASPECT_RATIO / 2,
+                MAX_ASPECT_RATIO * 2
+        };
+        for (float aspectRatio : invalidAspectRatios) {
+            final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
+                    mTestComponentName1, aspectRatio, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+            final float actualAspectRatio =
+                    destinationBounds.width() / (destinationBounds.height() * 1f);
+            assertEquals("Destination bounds fallbacks to default aspect ratio",
+                    mPipBoundsHandler.getDefaultAspectRatio(), actualAspectRatio,
+                    ASPECT_RATIO_ERROR_MARGIN);
+        }
+    }
+
+    @Test
+    public void  getDestinationBounds_withCurrentBounds_returnBoundsMatchesAspectRatio() {
+        final float aspectRatio = (DEFAULT_ASPECT_RATIO + MAX_ASPECT_RATIO) / 2;
+        final Rect currentBounds = new Rect(0, 0, 0, 100);
+        currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left;
+
+        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
+                mTestComponentName1, aspectRatio, currentBounds, EMPTY_MINIMAL_SIZE);
+
+        final float actualAspectRatio =
+                destinationBounds.width() / (destinationBounds.height() * 1f);
+        assertEquals("Destination bounds matches the given aspect ratio",
+                aspectRatio, actualAspectRatio, ASPECT_RATIO_ERROR_MARGIN);
+    }
+
+    @Test
+    public void getDestinationBounds_withMinSize_returnMinBounds() {
+        final float[] aspectRatios = new float[] {
+                (MIN_ASPECT_RATIO + DEFAULT_ASPECT_RATIO) / 2,
+                DEFAULT_ASPECT_RATIO,
+                (MAX_ASPECT_RATIO + DEFAULT_ASPECT_RATIO) / 2
+        };
+        final Size[] minimalSizes = new Size[] {
+                new Size((int) (100 * aspectRatios[0]), 100),
+                new Size((int) (100 * aspectRatios[1]), 100),
+                new Size((int) (100 * aspectRatios[2]), 100)
+        };
+        for (int i = 0; i < aspectRatios.length; i++) {
+            final float aspectRatio = aspectRatios[i];
+            final Size minimalSize = minimalSizes[i];
+            final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
+                    mTestComponentName1, aspectRatio, EMPTY_CURRENT_BOUNDS, minimalSize);
+            assertTrue("Destination bounds is no smaller than minimal requirement",
+                    (destinationBounds.width() == minimalSize.getWidth()
+                            && destinationBounds.height() >= minimalSize.getHeight())
+                            || (destinationBounds.height() == minimalSize.getHeight()
+                            && destinationBounds.width() >= minimalSize.getWidth()));
+            final float actualAspectRatio =
+                    destinationBounds.width() / (destinationBounds.height() * 1f);
+            assertEquals("Destination bounds matches the given aspect ratio",
+                    aspectRatio, actualAspectRatio, ASPECT_RATIO_ERROR_MARGIN);
+        }
+    }
+
+    @Test
+    public void getDestinationBounds_withCurrentBounds_ignoreMinBounds() {
+        final float aspectRatio = (DEFAULT_ASPECT_RATIO + MAX_ASPECT_RATIO) / 2;
+        final Rect currentBounds = new Rect(0, 0, 0, 100);
+        currentBounds.right = (int) (currentBounds.height() * aspectRatio) + currentBounds.left;
+        final Size minSize = new Size(currentBounds.width() / 2, currentBounds.height() / 2);
+
+        final Rect destinationBounds = mPipBoundsHandler.getDestinationBounds(
+                mTestComponentName1, aspectRatio, currentBounds, minSize);
+
+        assertTrue("Destination bounds ignores minimal size",
+                destinationBounds.width() > minSize.getWidth()
+                        && destinationBounds.height() > minSize.getHeight());
+    }
+
+    @Test
+    public void getDestinationBounds_withDifferentComponentName_ignoreLastPosition() {
+        final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        oldPosition.offset(0, -100);
+        mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, oldPosition);
+
+        final Rect newPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName2,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        assertNonBoundsInclusionWithMargin("ignore saved bounds", oldPosition, newPosition);
+    }
+
+    @Test
+    public void setShelfHeight_offsetBounds() {
+        final int shelfHeight = 100;
+        final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        mPipBoundsHandler.setShelfHeight(true, shelfHeight);
+        final Rect newPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        oldPosition.offset(0, -shelfHeight);
+        assertBoundsInclusionWithMargin("offsetBounds by shelf", oldPosition, newPosition);
+    }
+
+    @Test
+    public void onImeVisibilityChanged_offsetBounds() {
+        final int imeHeight = 100;
+        final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        mPipBoundsHandler.onImeVisibilityChanged(true, imeHeight);
+        final Rect newPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        oldPosition.offset(0, -imeHeight);
+        assertBoundsInclusionWithMargin("offsetBounds by IME", oldPosition, newPosition);
+    }
+
+    @Test
+    public void onSaveReentryBounds_restoreLastPosition() {
+        final Rect oldPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        oldPosition.offset(0, -100);
+        mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, oldPosition);
+
+        final Rect newPosition = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        assertBoundsInclusionWithMargin("restoreLastPosition", oldPosition, newPosition);
+    }
+
+    @Test
+    public void onSaveReentryBounds_restoreLastSize() {
+        final Rect oldSize = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        oldSize.scale(1.25f);
+        mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, oldSize);
+
+        final Rect newSize = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        assertEquals(oldSize.width(), newSize.width());
+        assertEquals(oldSize.height(), newSize.height());
+    }
+
+    @Test
+    public void onResetReentryBounds_useDefaultBounds() {
+        final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+        final Rect newBounds = new Rect(defaultBounds);
+        newBounds.offset(0, -100);
+        mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, newBounds);
+
+        mPipBoundsHandler.onResetReentryBounds(mTestComponentName1);
+        final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        assertBoundsInclusionWithMargin("useDefaultBounds", defaultBounds, actualBounds);
+    }
+
+    @Test
+    public void onResetReentryBounds_componentMismatch_restoreLastPosition() {
+        final Rect defaultBounds = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+        final Rect newBounds = new Rect(defaultBounds);
+        newBounds.offset(0, -100);
+        mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, newBounds);
+
+        mPipBoundsHandler.onResetReentryBounds(mTestComponentName2);
+        final Rect actualBounds = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        assertBoundsInclusionWithMargin("restoreLastPosition", newBounds, actualBounds);
+    }
+
+    @Test
+    public void onSaveReentryBounds_componentMismatch_restoreLastSize() {
+        final Rect oldSize = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        oldSize.scale(1.25f);
+        mPipBoundsHandler.onSaveReentryBounds(mTestComponentName1, oldSize);
+
+        mPipBoundsHandler.onResetReentryBounds(mTestComponentName2);
+        final Rect newSize = mPipBoundsHandler.getDestinationBounds(mTestComponentName1,
+                DEFAULT_ASPECT_RATIO, EMPTY_CURRENT_BOUNDS, EMPTY_MINIMAL_SIZE);
+
+        assertEquals(oldSize.width(), newSize.width());
+        assertEquals(oldSize.height(), newSize.height());
+    }
+
+    private void assertBoundsInclusionWithMargin(String from, Rect expected, Rect actual) {
+        final Rect expectedWithMargin = new Rect(expected);
+        expectedWithMargin.inset(-ROUNDING_ERROR_MARGIN, -ROUNDING_ERROR_MARGIN);
+        assertTrue(from + ": expect " + expected
+                + " contains " + actual
+                + " with error margin " + ROUNDING_ERROR_MARGIN,
+                expectedWithMargin.contains(actual));
+    }
+
+    private void assertNonBoundsInclusionWithMargin(String from, Rect expected, Rect actual) {
+        final Rect expectedWithMargin = new Rect(expected);
+        expectedWithMargin.inset(-ROUNDING_ERROR_MARGIN, -ROUNDING_ERROR_MARGIN);
+        assertFalse(from + ": expect " + expected
+                        + " not contains " + actual
+                        + " with error margin " + ROUNDING_ERROR_MARGIN,
+                expectedWithMargin.contains(actual));
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTestCase.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTestCase.java
new file mode 100644
index 0000000..fdebe4e
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/PipTestCase.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2020 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.wm.shell.pip;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.testing.TestableContext;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
+
+/**
+ * Base class that does One Handed specific setup.
+ */
+public abstract class PipTestCase {
+
+    protected TestableContext mContext;
+
+    @Before
+    public void setup() {
+        final Context context =
+                InstrumentationRegistry.getInstrumentation().getTargetContext();
+        final DisplayManager dm = context.getSystemService(DisplayManager.class);
+        mContext = new TestableContext(
+                context.createDisplayContext(dm.getDisplay(DEFAULT_DISPLAY)));
+
+        InstrumentationRegistry
+                .getInstrumentation()
+                .getUiAutomation()
+                .adoptShellPermissionIdentity();
+    }
+
+    protected Context getContext() {
+        return mContext;
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
new file mode 100644
index 0000000..d305c64
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 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.systemui.pip.phone;
+
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableContext;
+import android.testing.TestableLooper;
+
+import com.android.wm.shell.WindowManagerShellWrapper;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.pip.PipBoundsHandler;
+import com.android.wm.shell.pip.PipTaskOrganizer;
+import com.android.wm.shell.pip.PipTestCase;
+import com.android.wm.shell.pip.phone.PipAppOpsListener;
+import com.android.wm.shell.pip.phone.PipController;
+import com.android.wm.shell.pip.phone.PipMediaController;
+import com.android.wm.shell.pip.phone.PipTouchHandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests for {@link PipController}
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class PipControllerTest extends PipTestCase {
+    private com.android.wm.shell.pip.phone.PipController mPipController;
+    private TestableContext mSpiedContext;
+
+    @Mock private DisplayController mMockdDisplayController;
+    @Mock private PackageManager mPackageManager;
+    @Mock private com.android.wm.shell.pip.phone.PipMenuActivityController
+            mMockPipMenuActivityController;
+    @Mock private PipAppOpsListener mMockPipAppOpsListener;
+    @Mock private PipBoundsHandler mMockPipBoundsHandler;
+    @Mock private PipMediaController mMockPipMediaController;
+    @Mock private PipTaskOrganizer mMockPipTaskOrganizer;
+    @Mock private PipTouchHandler mMockPipTouchHandler;
+    @Mock private WindowManagerShellWrapper mMockWindowManagerShellWrapper;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+
+        mSpiedContext = spy(mContext);
+
+        when(mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false);
+        when(mSpiedContext.getPackageManager()).thenReturn(mPackageManager);
+
+        mPipController = new PipController(mSpiedContext, mMockdDisplayController,
+                mMockPipAppOpsListener, mMockPipBoundsHandler, mMockPipMediaController,
+                mMockPipMenuActivityController, mMockPipTaskOrganizer, mMockPipTouchHandler,
+                mMockWindowManagerShellWrapper);
+    }
+
+    @Test
+    public void testNonPipDevice_shouldNotRegisterPipTransitionCallback() {
+        verify(mMockPipTaskOrganizer, never()).registerPipTransitionCallback(any());
+    }
+
+    @Test
+    public void testNonPipDevice_shouldNotAddDisplayChangingController() {
+        verify(mMockdDisplayController, never()).addDisplayChangingController(any());
+    }
+
+    @Test
+    public void testNonPipDevice_shouldNotAddDisplayWindowListener() {
+        verify(mMockdDisplayController, never()).addDisplayWindowListener(any());
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTaskOrganizerTest.java
new file mode 100644
index 0000000..663169f
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTaskOrganizerTest.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2020 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.systemui.pip.phone;
+
+import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.pm.PackageManager;
+import android.os.RemoteException;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableContext;
+import android.testing.TestableLooper;
+
+import com.android.wm.shell.ShellTaskOrganizer;
+import com.android.wm.shell.common.DisplayController;
+import com.android.wm.shell.pip.PipBoundsHandler;
+import com.android.wm.shell.pip.PipSurfaceTransactionHelper;
+import com.android.wm.shell.pip.PipTaskOrganizer;
+import com.android.wm.shell.pip.PipTestCase;
+import com.android.wm.shell.pip.PipUiEventLogger;
+import com.android.wm.shell.splitscreen.SplitScreen;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.Optional;
+
+/**
+ * Unit tests for {@link PipTaskOrganizer}
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class PipTaskOrganizerTest extends PipTestCase {
+    private PipTaskOrganizer mSpiedPipTaskOrganizer;
+    private TestableContext mSpiedContext;
+
+    @Mock private DisplayController mMockdDisplayController;
+    @Mock private PackageManager mPackageManager;
+    @Mock private PipBoundsHandler mMockPipBoundsHandler;
+    @Mock private PipSurfaceTransactionHelper mMockPipSurfaceTransactionHelper;
+    @Mock private PipUiEventLogger mMockPipUiEventLogger;
+    @Mock private Optional<SplitScreen> mMockOptionalSplitScreen;
+    @Mock private ShellTaskOrganizer mMockShellTaskOrganizer;
+
+    @Before
+    public void setUp() throws RemoteException {
+        MockitoAnnotations.initMocks(this);
+
+        mSpiedContext = spy(mContext);
+
+        when(mPackageManager.hasSystemFeature(FEATURE_PICTURE_IN_PICTURE)).thenReturn(false);
+        when(mSpiedContext.getPackageManager()).thenReturn(mPackageManager);
+
+        mSpiedPipTaskOrganizer = spy(new PipTaskOrganizer(mSpiedContext, mMockPipBoundsHandler,
+                mMockPipSurfaceTransactionHelper, mMockOptionalSplitScreen, mMockdDisplayController,
+                mMockPipUiEventLogger, mMockShellTaskOrganizer));
+    }
+
+    @Test
+    public void testNonPipDevice_shellTaskOrganizer_shouldNotAddListener() {
+        verify(mMockShellTaskOrganizer, never()).addListener(any(), anyInt());
+    }
+
+    @Test
+    public void testNonPipDevice_displayController_shouldNotAddDisplayWindowListener() {
+        verify(mMockdDisplayController, never()).addDisplayWindowListener(any());
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
new file mode 100644
index 0000000..c96cb20
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2020 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.systemui.pip.phone;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.util.Size;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.R;
+import com.android.wm.shell.common.FloatingContentCoordinator;
+import com.android.wm.shell.pip.PipBoundsHandler;
+import com.android.wm.shell.pip.PipSnapAlgorithm;
+import com.android.wm.shell.pip.PipTaskOrganizer;
+import com.android.wm.shell.pip.PipTestCase;
+import com.android.wm.shell.pip.PipUiEventLogger;
+import com.android.wm.shell.pip.phone.PipMenuActivityController;
+import com.android.wm.shell.pip.phone.PipMotionHelper;
+import com.android.wm.shell.pip.phone.PipResizeGestureHandler;
+import com.android.wm.shell.pip.phone.PipTouchHandler;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Unit tests against {@link PipTouchHandler}, including but not limited to:
+ * - Update movement bounds based on new bounds
+ * - Update movement bounds based on IME/shelf
+ * - Update movement bounds to PipResizeHandler
+ */
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+public class PipTouchHandlerTest extends PipTestCase {
+
+    private PipTouchHandler mPipTouchHandler;
+
+    @Mock
+    private PipMenuActivityController mPipMenuActivityController;
+
+    @Mock
+    private PipTaskOrganizer mPipTaskOrganizer;
+
+    @Mock
+    private FloatingContentCoordinator mFloatingContentCoordinator;
+
+    @Mock
+    private PipUiEventLogger mPipUiEventLogger;
+
+    private PipBoundsHandler mPipBoundsHandler;
+    private PipSnapAlgorithm mPipSnapAlgorithm;
+    private PipMotionHelper mMotionHelper;
+    private PipResizeGestureHandler mPipResizeGestureHandler;
+
+    private Rect mInsetBounds;
+    private Rect mMinBounds;
+    private Rect mCurBounds;
+    private boolean mFromImeAdjustment;
+    private boolean mFromShelfAdjustment;
+    private int mDisplayRotation;
+    private int mImeHeight;
+
+    @Before
+    public void setUp() throws Exception {
+        MockitoAnnotations.initMocks(this);
+        mPipBoundsHandler = new PipBoundsHandler(mContext);
+        mPipSnapAlgorithm = mPipBoundsHandler.getSnapAlgorithm();
+        mPipSnapAlgorithm = new PipSnapAlgorithm(mContext);
+        mPipTouchHandler = new PipTouchHandler(mContext, mPipMenuActivityController,
+                mPipBoundsHandler, mPipTaskOrganizer, mFloatingContentCoordinator,
+                mPipUiEventLogger);
+        mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper());
+        mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler());
+        mPipTouchHandler.setPipMotionHelper(mMotionHelper);
+        mPipTouchHandler.setPipResizeGestureHandler(mPipResizeGestureHandler);
+
+        // Assume a display of 1000 x 1000
+        // inset of 10
+        mInsetBounds = new Rect(10, 10, 990, 990);
+        // minBounds of 100x100 bottom right corner
+        mMinBounds = new Rect(890, 890, 990, 990);
+        mCurBounds = new Rect(mMinBounds);
+        mFromImeAdjustment = false;
+        mFromShelfAdjustment = false;
+        mDisplayRotation = 0;
+        mImeHeight = 100;
+    }
+
+    @Test
+    public void updateMovementBounds_minBounds() {
+        Rect expectedMinMovementBounds = new Rect();
+        mPipSnapAlgorithm.getMovementBounds(mMinBounds, mInsetBounds, expectedMinMovementBounds, 0);
+
+        mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
+                mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
+
+        assertEquals(expectedMinMovementBounds, mPipTouchHandler.mNormalMovementBounds);
+        verify(mPipResizeGestureHandler, times(1))
+                .updateMinSize(mMinBounds.width(), mMinBounds.height());
+    }
+
+    @Test
+    public void updateMovementBounds_maxBounds() {
+        Point displaySize = new Point();
+        mContext.getDisplay().getRealSize(displaySize);
+        Size maxSize = mPipSnapAlgorithm.getSizeForAspectRatio(1,
+                mContext.getResources().getDimensionPixelSize(
+                        R.dimen.pip_expanded_shortest_edge_size), displaySize.x, displaySize.y);
+        Rect maxBounds = new Rect(0, 0, maxSize.getWidth(), maxSize.getHeight());
+        Rect expectedMaxMovementBounds = new Rect();
+        mPipSnapAlgorithm.getMovementBounds(maxBounds, mInsetBounds, expectedMaxMovementBounds, 0);
+
+        mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
+                mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
+
+        assertEquals(expectedMaxMovementBounds, mPipTouchHandler.mExpandedMovementBounds);
+        verify(mPipResizeGestureHandler, times(1))
+                .updateMaxSize(maxBounds.width(), maxBounds.height());
+    }
+
+    @Test
+    public void updateMovementBounds_withImeAdjustment_movesPip() {
+        mFromImeAdjustment = true;
+        mPipTouchHandler.onImeVisibilityChanged(true /* imeVisible */, mImeHeight);
+
+        mPipTouchHandler.onMovementBoundsChanged(mInsetBounds, mMinBounds, mCurBounds,
+                mFromImeAdjustment, mFromShelfAdjustment, mDisplayRotation);
+
+        verify(mMotionHelper, times(1)).animateToOffset(any(), anyInt());
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java
new file mode 100644
index 0000000..2702130
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchStateTest.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2017 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.systemui.pip.phone;
+
+import static android.view.MotionEvent.ACTION_BUTTON_PRESS;
+import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_MOVE;
+import static android.view.MotionEvent.ACTION_UP;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.testing.TestableLooper.RunWithLooper;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.pip.PipTestCase;
+import com.android.wm.shell.pip.phone.PipTouchState;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.CountDownLatch;
+
+@RunWith(AndroidTestingRunner.class)
+@SmallTest
+@RunWithLooper
+public class PipTouchStateTest extends PipTestCase {
+
+    private PipTouchState mTouchState;
+    private CountDownLatch mDoubleTapCallbackTriggeredLatch;
+    private CountDownLatch mHoverExitCallbackTriggeredLatch;
+
+    @Before
+    public void setUp() throws Exception {
+        mDoubleTapCallbackTriggeredLatch = new CountDownLatch(1);
+        mHoverExitCallbackTriggeredLatch = new CountDownLatch(1);
+        mTouchState = new PipTouchState(ViewConfiguration.get(getContext()),
+                Handler.createAsync(Looper.myLooper()), () -> {
+            mDoubleTapCallbackTriggeredLatch.countDown();
+        }, () -> {
+            mHoverExitCallbackTriggeredLatch.countDown();
+        });
+        assertFalse(mTouchState.isDoubleTap());
+        assertFalse(mTouchState.isWaitingForDoubleTap());
+    }
+
+    @Test
+    public void testDoubleTapLongSingleTap_notDoubleTapAndNotWaiting() {
+        final long currentTime = SystemClock.uptimeMillis();
+
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN, currentTime, 0, 0));
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_UP,
+                currentTime + PipTouchState.DOUBLE_TAP_TIMEOUT + 10, 0, 0));
+        assertFalse(mTouchState.isDoubleTap());
+        assertFalse(mTouchState.isWaitingForDoubleTap());
+        assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == -1);
+    }
+
+    @Test
+    public void testDoubleTapTimeout_timeoutCallbackCalled() throws Exception {
+        final long currentTime = SystemClock.uptimeMillis();
+
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN, currentTime, 0, 0));
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_UP,
+                currentTime + PipTouchState.DOUBLE_TAP_TIMEOUT - 10, 0, 0));
+        assertFalse(mTouchState.isDoubleTap());
+        assertTrue(mTouchState.isWaitingForDoubleTap());
+
+        assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == 10);
+        mTouchState.scheduleDoubleTapTimeoutCallback();
+
+        // TODO: Remove this sleep. Its only being added because it speeds up this test a bit.
+        Thread.sleep(15);
+        TestableLooper.get(this).processAllMessages();
+        assertTrue(mDoubleTapCallbackTriggeredLatch.getCount() == 0);
+    }
+
+    @Test
+    public void testDoubleTapDrag_doubleTapCanceled() {
+        final long currentTime = SystemClock.uptimeMillis();
+
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN, currentTime, 0, 0));
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_MOVE, currentTime + 10, 500, 500));
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_UP, currentTime + 20, 500, 500));
+        assertTrue(mTouchState.isDragging());
+        assertFalse(mTouchState.isDoubleTap());
+        assertFalse(mTouchState.isWaitingForDoubleTap());
+        assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == -1);
+    }
+
+    @Test
+    public void testDoubleTap_doubleTapRegistered() {
+        final long currentTime = SystemClock.uptimeMillis();
+
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN, currentTime, 0, 0));
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_UP, currentTime + 10, 0, 0));
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_DOWN,
+                currentTime + PipTouchState.DOUBLE_TAP_TIMEOUT - 20, 0, 0));
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_UP,
+                currentTime + PipTouchState.DOUBLE_TAP_TIMEOUT - 10, 0, 0));
+        assertTrue(mTouchState.isDoubleTap());
+        assertFalse(mTouchState.isWaitingForDoubleTap());
+        assertTrue(mTouchState.getDoubleTapTimeoutCallbackDelay() == -1);
+    }
+
+    @Test
+    public void testHoverExitTimeout_timeoutCallbackCalled() throws Exception {
+        mTouchState.scheduleHoverExitTimeoutCallback();
+
+        // TODO: Remove this sleep. Its only being added because it speeds up this test a bit.
+        Thread.sleep(50);
+        TestableLooper.get(this).processAllMessages();
+        assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 0);
+    }
+
+    @Test
+    public void testHoverExitTimeout_timeoutCallbackNotCalled() throws Exception {
+        mTouchState.scheduleHoverExitTimeoutCallback();
+        TestableLooper.get(this).processAllMessages();
+        assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 1);
+    }
+
+    @Test
+    public void testHoverExitTimeout_timeoutCallbackNotCalled_ifButtonPress() throws Exception {
+        mTouchState.scheduleHoverExitTimeoutCallback();
+        mTouchState.onTouchEvent(createMotionEvent(ACTION_BUTTON_PRESS, SystemClock.uptimeMillis(),
+                0, 0));
+
+        // TODO: Remove this sleep. Its only being added because it speeds up this test a bit.
+        Thread.sleep(50);
+        TestableLooper.get(this).processAllMessages();
+        assertTrue(mHoverExitCallbackTriggeredLatch.getCount() == 1);
+    }
+
+    private MotionEvent createMotionEvent(int action, long eventTime, float x, float y) {
+        return MotionEvent.obtain(0, eventTime, action, x, y, 0);
+    }
+}
