Experiment with allowing tap to break through to interact with the PIP.
Test: Enable SysUI tuner, tap once on PIP to interact with the activity.
This is only experimental behaviour, and
android.server.cts.ActivityManagerPinnedStackTests will be updated
accordingly if we keep this behavior.
Change-Id: I278ab8c360c44718cfcac0fd761f476a875f9b15
This commit is contained in:
@@ -415,6 +415,18 @@
|
||||
android:launchMode="singleTop"
|
||||
android:excludeFromRecents="true" />
|
||||
|
||||
<activity
|
||||
android:name=".pip.phone.PipMenuActivity"
|
||||
android:theme="@style/PipPhoneOverlayControlTheme"
|
||||
android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
|
||||
android:excludeFromRecents="true"
|
||||
android:exported="false"
|
||||
android:resizeableActivity="true"
|
||||
android:supportsPictureInPicture="true"
|
||||
android:stateNotNeeded="true"
|
||||
android:taskAffinity=""
|
||||
androidprv:alwaysFocusable="true" />
|
||||
|
||||
<!-- platform logo easter egg activity -->
|
||||
<activity
|
||||
android:name=".DessertCase"
|
||||
|
||||
36
packages/SystemUI/res/layout/pip_menu_activity.xml
Normal file
36
packages/SystemUI/res/layout/pip_menu_activity.xml
Normal file
@@ -0,0 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2014 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.
|
||||
-->
|
||||
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#33000000">
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center">
|
||||
<Button
|
||||
android:id="@+id/expand_pip"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#ffffffff"
|
||||
android:text="@string/pip_phone_expand"
|
||||
android:fontFamily="sans-serif" />
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
@@ -1675,6 +1675,9 @@
|
||||
not appear on production builds ever. -->
|
||||
<string name="tuner_doze_always_on" translatable="false">Always on</string>
|
||||
|
||||
<!-- Making the PIP fullscreen -->
|
||||
<string name="pip_phone_expand">Expand</string>
|
||||
|
||||
<!-- PIP section of the tuner. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="picture_in_picture" translatable="false">Picture-in-Picture</string>
|
||||
@@ -1695,4 +1698,12 @@
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_drag_to_dismiss_summary" translatable="false">Drag to the dismiss target at the bottom of the screen to close the PIP</string>
|
||||
|
||||
<!-- PIP tap once to break through to the activity. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_tap_through_title" translatable="false">Tap to interact</string>
|
||||
|
||||
<!-- PIP tap once to break through to the activity. Non-translatable since it should
|
||||
not appear on production builds ever. -->
|
||||
<string name="pip_tap_through_summary" translatable="false">Tap once to interact with the activity</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -56,6 +56,24 @@
|
||||
<item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
|
||||
</style>
|
||||
|
||||
<style name="PipPhoneOverlayControlTheme" parent="@android:style/Theme.Material">
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowContentOverlay">@null</item>
|
||||
<item name="android:windowBackground">@drawable/forced_resizable_background</item>
|
||||
<item name="android:colorBackgroundCacheHint">@null</item>
|
||||
<item name="android:statusBarColor">@color/transparent</item>
|
||||
<item name="android:windowAnimationStyle">@style/Animation.PipPhoneOverlayControl</item>
|
||||
</style>
|
||||
|
||||
<style name="Animation.PipPhoneOverlayControl" parent="@android:style/Animation">
|
||||
<item name="android:activityOpenEnterAnimation">@anim/forced_resizable_enter</item>
|
||||
|
||||
<!-- If the target stack doesn't have focus, we do a task to front animation. -->
|
||||
<item name="android:taskToFrontEnterAnimation">@anim/forced_resizable_enter</item>
|
||||
<item name="android:activityCloseExitAnimation">@anim/forced_resizable_exit</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.StatusBar.HeadsUp"
|
||||
parent="@*android:style/TextAppearance.StatusBar">
|
||||
</style>
|
||||
|
||||
@@ -137,6 +137,12 @@
|
||||
android:summary="@string/pip_drag_to_dismiss_summary"
|
||||
sysui:defValue="true" />
|
||||
|
||||
<com.android.systemui.tuner.TunerSwitch
|
||||
android:key="pip_tap_through"
|
||||
android:title="@string/pip_tap_through_title"
|
||||
android:summary="@string/pip_tap_through_summary"
|
||||
sysui:defValue="false" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceScreen
|
||||
|
||||
@@ -34,6 +34,7 @@ public class PipManager {
|
||||
private IActivityManager mActivityManager;
|
||||
private IWindowManager mWindowManager;
|
||||
|
||||
private PipMenuActivityController mMenuController;
|
||||
private PipTouchHandler mTouchHandler;
|
||||
|
||||
private PipManager() {}
|
||||
@@ -46,7 +47,9 @@ public class PipManager {
|
||||
mActivityManager = ActivityManagerNative.getDefault();
|
||||
mWindowManager = WindowManagerGlobal.getWindowManagerService();
|
||||
|
||||
mTouchHandler = new PipTouchHandler(context, mActivityManager, mWindowManager);
|
||||
mMenuController = new PipMenuActivityController(context, mActivityManager, mWindowManager);
|
||||
mTouchHandler = new PipTouchHandler(context, mMenuController, mActivityManager,
|
||||
mWindowManager);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 android.annotation.Nullable;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import com.android.systemui.R;
|
||||
|
||||
/**
|
||||
* Translucent activity that gets started on top of a task in PIP to allow the user to control it.
|
||||
*/
|
||||
public class PipMenuActivity extends Activity {
|
||||
|
||||
private static final String TAG = "PipMenuActivity";
|
||||
|
||||
public static final int MESSAGE_FINISH_SELF = 2;
|
||||
|
||||
private static final long INITIAL_DISMISS_DELAY = 2000;
|
||||
private static final long POST_INTERACTION_DISMISS_DELAY = 1500;
|
||||
|
||||
private Messenger mToControllerMessenger;
|
||||
private Messenger mMessenger = new Messenger(new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MESSAGE_FINISH_SELF:
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
private final Runnable mFinishRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
Intent startingIntet = getIntent();
|
||||
mToControllerMessenger = startingIntet.getParcelableExtra(
|
||||
PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER);
|
||||
|
||||
setContentView(R.layout.pip_menu_activity);
|
||||
findViewById(R.id.expand_pip).setOnClickListener((view) -> {
|
||||
finish();
|
||||
notifyExpandPip();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
notifyActivityVisibility(true);
|
||||
repostDelayedFinish(INITIAL_DISMISS_DELAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUserInteraction() {
|
||||
repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish() {
|
||||
View v = getWindow().getDecorView();
|
||||
v.removeCallbacks(mFinishRunnable);
|
||||
notifyActivityVisibility(false);
|
||||
super.finish();
|
||||
overridePendingTransition(0, R.anim.forced_resizable_exit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
private void notifyActivityVisibility(boolean visible) {
|
||||
Message m = Message.obtain();
|
||||
m.what = PipMenuActivityController.MESSAGE_ACTIVITY_VISIBILITY_CHANGED;
|
||||
m.arg1 = visible ? 1 : 0;
|
||||
m.replyTo = visible ? mMessenger : null;
|
||||
try {
|
||||
mToControllerMessenger.send(m);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not notify controller of PIP menu visibility", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyExpandPip() {
|
||||
Message m = Message.obtain();
|
||||
m.what = PipMenuActivityController.MESSAGE_EXPAND_PIP;
|
||||
try {
|
||||
mToControllerMessenger.send(m);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not notify controller to expand PIP", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void repostDelayedFinish(long delay) {
|
||||
View v = getWindow().getDecorView();
|
||||
v.removeCallbacks(mFinishRunnable);
|
||||
v.postDelayed(mFinishRunnable, delay);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.android.systemui.pip.phone;
|
||||
|
||||
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
|
||||
import static android.view.WindowManager.INPUT_CONSUMER_PIP;
|
||||
|
||||
import android.app.ActivityManager.StackInfo;
|
||||
import android.app.ActivityOptions;
|
||||
import android.app.IActivityManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.view.IWindowManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class PipMenuActivityController {
|
||||
|
||||
private static final String TAG = "PipMenuActivityController";
|
||||
|
||||
public static final String EXTRA_CONTROLLER_MESSENGER = "messenger";
|
||||
public static final int MESSAGE_ACTIVITY_VISIBILITY_CHANGED = 1;
|
||||
public static final int MESSAGE_EXPAND_PIP = 3;
|
||||
|
||||
/**
|
||||
* A listener interface to receive notification on changes in PIP.
|
||||
*/
|
||||
public interface Listener {
|
||||
/**
|
||||
* Called when the PIP menu visibility changes.
|
||||
*/
|
||||
void onPipMenuVisibilityChanged(boolean visible);
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private IActivityManager mActivityManager;
|
||||
private IWindowManager mWindowManager;
|
||||
private ArrayList<Listener> mListeners = new ArrayList<>();
|
||||
|
||||
private Messenger mToActivityMessenger;
|
||||
private Messenger mMessenger = new Messenger(new Handler() {
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case MESSAGE_ACTIVITY_VISIBILITY_CHANGED: {
|
||||
boolean visible = msg.arg1 > 0;
|
||||
int listenerCount = mListeners.size();
|
||||
for (int i = 0; i < listenerCount; i++) {
|
||||
mListeners.get(i).onPipMenuVisibilityChanged(visible);
|
||||
}
|
||||
mToActivityMessenger = msg.replyTo;
|
||||
break;
|
||||
}
|
||||
case MESSAGE_EXPAND_PIP: {
|
||||
try {
|
||||
mActivityManager.resizeStack(PINNED_STACK_ID, null, true, true, true, 225);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error showing PIP menu activity", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
public PipMenuActivityController(Context context, IActivityManager activityManager,
|
||||
IWindowManager windowManager) {
|
||||
mContext = context;
|
||||
mActivityManager = activityManager;
|
||||
mWindowManager = windowManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new menu activity listener.
|
||||
*/
|
||||
public void addListener(Listener listener) {
|
||||
if (!mListeners.contains(listener)) {
|
||||
mListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the menu activity.
|
||||
*/
|
||||
public void showMenu() {
|
||||
// Start the menu activity on the top task of the pinned stack
|
||||
try {
|
||||
StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
|
||||
if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null &&
|
||||
pinnedStackInfo.taskIds.length > 0) {
|
||||
Intent intent = new Intent(mContext, PipMenuActivity.class);
|
||||
intent.putExtra(EXTRA_CONTROLLER_MESSENGER, mMessenger);
|
||||
ActivityOptions options = ActivityOptions.makeBasic();
|
||||
options.setLaunchTaskId(
|
||||
pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]);
|
||||
options.setTaskOverlay(true);
|
||||
mContext.startActivityAsUser(intent, options.toBundle(), UserHandle.CURRENT);
|
||||
} else {
|
||||
Log.e(TAG, "No PIP tasks found");
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Error showing PIP menu activity", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides the menu activity.
|
||||
*/
|
||||
public void hideMenu() {
|
||||
if (mToActivityMessenger != null) {
|
||||
Message m = Message.obtain();
|
||||
m.what = PipMenuActivity.MESSAGE_FINISH_SELF;
|
||||
try {
|
||||
mToActivityMessenger.send(m);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Could not notify menu activity to finish", e);
|
||||
}
|
||||
mToActivityMessenger = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import android.app.IActivityManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
@@ -61,6 +62,7 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
|
||||
private static final String TUNER_KEY_SWIPE_TO_DISMISS = "pip_swipe_to_dismiss";
|
||||
private static final String TUNER_KEY_DRAG_TO_DISMISS = "pip_drag_to_dismiss";
|
||||
private static final String TUNER_KEY_TAP_THROUGH = "pip_tap_through";
|
||||
|
||||
private static final int SNAP_STACK_DURATION = 225;
|
||||
private static final int DISMISS_STACK_DURATION = 375;
|
||||
@@ -70,17 +72,19 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
private final IActivityManager mActivityManager;
|
||||
private final IWindowManager mWindowManager;
|
||||
private final ViewConfiguration mViewConfig;
|
||||
private final InputChannel mInputChannel = new InputChannel();
|
||||
private final PinnedStackListener mPinnedStackListener = new PinnedStackListener();
|
||||
private final PipMenuListener mMenuListener = new PipMenuListener();
|
||||
private IPinnedStackController mPinnedStackController;
|
||||
|
||||
private final PipInputEventReceiver mInputEventReceiver;
|
||||
private PipInputEventReceiver mInputEventReceiver;
|
||||
private PipMenuActivityController mMenuController;
|
||||
private PipDismissViewController mDismissViewController;
|
||||
private final PipSnapAlgorithm mSnapAlgorithm;
|
||||
private PipMotionHelper mMotionHelper;
|
||||
|
||||
private boolean mEnableSwipeToDismiss = true;
|
||||
private boolean mEnableDragToDismiss = true;
|
||||
private boolean mEnableTapThrough = false;
|
||||
|
||||
private final Rect mPinnedStackBounds = new Rect();
|
||||
private final Rect mBoundedPinnedStackBounds = new Rect();
|
||||
@@ -97,6 +101,7 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
private final PointF mLastTouch = new PointF();
|
||||
private boolean mIsDragging;
|
||||
private boolean mIsSwipingToDismiss;
|
||||
private boolean mIsTappingThrough;
|
||||
private int mActivePointerId;
|
||||
|
||||
private final FlingAnimationUtils mFlingAnimationUtils;
|
||||
@@ -120,7 +125,7 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
// To be implemented for input handling over Pip windows
|
||||
if (event instanceof MotionEvent) {
|
||||
MotionEvent ev = (MotionEvent) event;
|
||||
handleTouchEvent(ev);
|
||||
handled = handleTouchEvent(ev);
|
||||
}
|
||||
} finally {
|
||||
finishInputEvent(event, handled);
|
||||
@@ -144,13 +149,26 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
}
|
||||
}
|
||||
|
||||
public PipTouchHandler(Context context, IActivityManager activityManager,
|
||||
IWindowManager windowManager) {
|
||||
/**
|
||||
* A listener for the PIP menu activity.
|
||||
*/
|
||||
private class PipMenuListener implements PipMenuActivityController.Listener {
|
||||
@Override
|
||||
public void onPipMenuVisibilityChanged(boolean visible) {
|
||||
if (!visible) {
|
||||
mIsTappingThrough = false;
|
||||
registerInputConsumer();
|
||||
} else {
|
||||
unregisterInputConsumer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PipTouchHandler(Context context, PipMenuActivityController menuController,
|
||||
IActivityManager activityManager, IWindowManager windowManager) {
|
||||
|
||||
// Initialize the Pip input consumer
|
||||
try {
|
||||
windowManager.destroyInputConsumer(INPUT_CONSUMER_PIP);
|
||||
windowManager.createInputConsumer(INPUT_CONSUMER_PIP, mInputChannel);
|
||||
windowManager.registerPinnedStackListener(DEFAULT_DISPLAY, mPinnedStackListener);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to create PIP input consumer", e);
|
||||
@@ -159,22 +177,27 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
mActivityManager = activityManager;
|
||||
mWindowManager = windowManager;
|
||||
mViewConfig = ViewConfiguration.get(context);
|
||||
mInputEventReceiver = new PipInputEventReceiver(mInputChannel, Looper.myLooper());
|
||||
if (mEnableDragToDismiss) {
|
||||
mDismissViewController = new PipDismissViewController(context);
|
||||
}
|
||||
mMenuController = menuController;
|
||||
mMenuController.addListener(mMenuListener);
|
||||
mDismissViewController = new PipDismissViewController(context);
|
||||
mSnapAlgorithm = new PipSnapAlgorithm(mContext);
|
||||
mFlingAnimationUtils = new FlingAnimationUtils(context, 2f);
|
||||
mMotionHelper = new PipMotionHelper(BackgroundThread.getHandler());
|
||||
registerInputConsumer();
|
||||
|
||||
// Register any tuner settings changes
|
||||
TunerService.get(context).addTunable(this, TUNER_KEY_SWIPE_TO_DISMISS,
|
||||
TUNER_KEY_DRAG_TO_DISMISS);
|
||||
TUNER_KEY_DRAG_TO_DISMISS, TUNER_KEY_TAP_THROUGH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTuningChanged(String key, String newValue) {
|
||||
if (newValue == null) {
|
||||
// Reset back to default
|
||||
mEnableSwipeToDismiss = true;
|
||||
mEnableDragToDismiss = true;
|
||||
mEnableTapThrough = false;
|
||||
mIsTappingThrough = false;
|
||||
return;
|
||||
}
|
||||
switch (key) {
|
||||
@@ -184,6 +207,10 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
case TUNER_KEY_DRAG_TO_DISMISS:
|
||||
mEnableDragToDismiss = Integer.parseInt(newValue) != 0;
|
||||
break;
|
||||
case TUNER_KEY_TAP_THROUGH:
|
||||
mEnableTapThrough = Integer.parseInt(newValue) != 0;
|
||||
mIsTappingThrough = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,10 +219,10 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
updateBoundedPinnedStackBounds(false /* updatePinnedStackBounds */);
|
||||
}
|
||||
|
||||
private void handleTouchEvent(MotionEvent ev) {
|
||||
private boolean handleTouchEvent(MotionEvent ev) {
|
||||
// Skip touch handling until we are bound to the controller
|
||||
if (mPinnedStackController == null) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (ev.getAction()) {
|
||||
@@ -239,6 +266,8 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
float movement = PointF.length(mDownTouch.x - x, mDownTouch.y - y);
|
||||
if (movement > mViewConfig.getScaledTouchSlop()) {
|
||||
mIsDragging = true;
|
||||
mIsTappingThrough = false;
|
||||
mMenuController.hideMenu();
|
||||
if (mEnableSwipeToDismiss) {
|
||||
// TODO: this check can have some buffer so that we only start swiping
|
||||
// after a significant move out of bounds
|
||||
@@ -328,7 +357,14 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
expandPinnedStackToFullscreen();
|
||||
if (mEnableTapThrough) {
|
||||
if (!mIsTappingThrough) {
|
||||
mMenuController.showMenu();
|
||||
mIsTappingThrough = true;
|
||||
}
|
||||
} else {
|
||||
expandPinnedStackToFullscreen();
|
||||
}
|
||||
}
|
||||
if (mEnableDragToDismiss) {
|
||||
mDismissViewController.destroyDismissTarget();
|
||||
@@ -348,6 +384,7 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return !mIsTappingThrough;
|
||||
}
|
||||
|
||||
private void initOrResetVelocityTracker() {
|
||||
@@ -365,6 +402,32 @@ public class PipTouchHandler implements TunerService.Tunable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the input consumer.
|
||||
*/
|
||||
private void registerInputConsumer() {
|
||||
final InputChannel inputChannel = new InputChannel();
|
||||
try {
|
||||
mWindowManager.destroyInputConsumer(INPUT_CONSUMER_PIP);
|
||||
mWindowManager.createInputConsumer(INPUT_CONSUMER_PIP, inputChannel);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to create PIP input consumer", e);
|
||||
}
|
||||
mInputEventReceiver = new PipInputEventReceiver(inputChannel, Looper.myLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the input consumer.
|
||||
*/
|
||||
private void unregisterInputConsumer() {
|
||||
try {
|
||||
mWindowManager.destroyInputConsumer(INPUT_CONSUMER_PIP);
|
||||
} catch (RemoteException e) {
|
||||
Log.e(TAG, "Failed to destroy PIP input consumer", e);
|
||||
}
|
||||
mInputEventReceiver.dispose();
|
||||
}
|
||||
|
||||
/**
|
||||
* Flings the PIP to the closest snap target.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user