Convert DragDownHelper to Kotlin
Bug: 184946919 Test: build, test drag down behavior on lockscreen Change-Id: I56eebf57a169ce6d22ad071d029135078a3b712b
This commit is contained in:
@@ -1,292 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar;
|
||||
|
||||
import static com.android.systemui.classifier.Classifier.NOTIFICATION_DRAG_DOWN;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.android.systemui.ExpandHelper;
|
||||
import com.android.systemui.Gefingerpoken;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.animation.Interpolators;
|
||||
import com.android.systemui.classifier.FalsingCollector;
|
||||
import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableView;
|
||||
|
||||
/**
|
||||
* A utility class to enable the downward swipe on the lockscreen to go to the full shade and expand
|
||||
* the notification where the drag started.
|
||||
*/
|
||||
public class DragDownHelper implements Gefingerpoken {
|
||||
|
||||
private static final float RUBBERBAND_FACTOR_EXPANDABLE = 0.5f;
|
||||
private static final float RUBBERBAND_FACTOR_STATIC = 0.15f;
|
||||
|
||||
private static final int SPRING_BACK_ANIMATION_LENGTH_MS = 375;
|
||||
|
||||
private int mMinDragDistance;
|
||||
private final FalsingManager mFalsingManager;
|
||||
private ExpandHelper.Callback mCallback;
|
||||
private float mInitialTouchX;
|
||||
private float mInitialTouchY;
|
||||
private boolean mDraggingDown;
|
||||
private final float mTouchSlop;
|
||||
private final float mSlopMultiplier;
|
||||
private DragDownCallback mDragDownCallback;
|
||||
private View mHost;
|
||||
private final int[] mTemp2 = new int[2];
|
||||
private boolean mDraggedFarEnough;
|
||||
private ExpandableView mStartingChild;
|
||||
private float mLastHeight;
|
||||
private FalsingCollector mFalsingCollector;
|
||||
|
||||
public DragDownHelper(Context context, View host, ExpandHelper.Callback callback,
|
||||
DragDownCallback dragDownCallback, FalsingManager falsingManager,
|
||||
FalsingCollector falsingCollector) {
|
||||
mMinDragDistance = context.getResources().getDimensionPixelSize(
|
||||
R.dimen.keyguard_drag_down_min_distance);
|
||||
mFalsingManager = falsingManager;
|
||||
final ViewConfiguration configuration = ViewConfiguration.get(context);
|
||||
mTouchSlop = configuration.getScaledTouchSlop();
|
||||
mSlopMultiplier = configuration.getScaledAmbiguousGestureMultiplier();
|
||||
mCallback = callback;
|
||||
mDragDownCallback = dragDownCallback;
|
||||
mHost = host;
|
||||
mFalsingCollector = falsingCollector;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onInterceptTouchEvent(MotionEvent event) {
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
mDraggedFarEnough = false;
|
||||
mDraggingDown = false;
|
||||
mStartingChild = null;
|
||||
mInitialTouchY = y;
|
||||
mInitialTouchX = x;
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
final float h = y - mInitialTouchY;
|
||||
// Adjust the touch slop if another gesture may be being performed.
|
||||
final float touchSlop =
|
||||
event.getClassification() == MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE
|
||||
? mTouchSlop * mSlopMultiplier
|
||||
: mTouchSlop;
|
||||
if (h > touchSlop && h > Math.abs(x - mInitialTouchX)) {
|
||||
mFalsingCollector.onNotificationStartDraggingDown();
|
||||
mDraggingDown = true;
|
||||
captureStartingChild(mInitialTouchX, mInitialTouchY);
|
||||
mInitialTouchY = y;
|
||||
mInitialTouchX = x;
|
||||
mDragDownCallback.onTouchSlopExceeded();
|
||||
return mStartingChild != null || mDragDownCallback.isDragDownAnywhereEnabled();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
if (!mDraggingDown) {
|
||||
return false;
|
||||
}
|
||||
final float x = event.getX();
|
||||
final float y = event.getY();
|
||||
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
mLastHeight = y - mInitialTouchY;
|
||||
captureStartingChild(mInitialTouchX, mInitialTouchY);
|
||||
if (mStartingChild != null) {
|
||||
handleExpansion(mLastHeight, mStartingChild);
|
||||
} else {
|
||||
mDragDownCallback.setEmptyDragAmount(mLastHeight);
|
||||
}
|
||||
if (mLastHeight > mMinDragDistance) {
|
||||
if (!mDraggedFarEnough) {
|
||||
mDraggedFarEnough = true;
|
||||
mDragDownCallback.onCrossedThreshold(true);
|
||||
}
|
||||
} else {
|
||||
if (mDraggedFarEnough) {
|
||||
mDraggedFarEnough = false;
|
||||
mDragDownCallback.onCrossedThreshold(false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (!mFalsingManager.isUnlockingDisabled() && mDragDownCallback.canDragDown()
|
||||
&& !isFalseTouch()) {
|
||||
mDragDownCallback.onDraggedDown(mStartingChild, (int) (y - mInitialTouchY));
|
||||
if (mStartingChild == null) {
|
||||
cancelExpansion();
|
||||
} else {
|
||||
mCallback.setUserLockedChild(mStartingChild, false);
|
||||
mStartingChild = null;
|
||||
}
|
||||
mDraggingDown = false;
|
||||
} else {
|
||||
stopDragging();
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
stopDragging();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isFalseTouch() {
|
||||
if (!mDragDownCallback.isFalsingCheckNeeded()) {
|
||||
return false;
|
||||
}
|
||||
return mFalsingManager.isFalseTouch(NOTIFICATION_DRAG_DOWN) || !mDraggedFarEnough;
|
||||
}
|
||||
|
||||
private void captureStartingChild(float x, float y) {
|
||||
if (mStartingChild == null) {
|
||||
mStartingChild = findView(x, y);
|
||||
if (mStartingChild != null) {
|
||||
if (mDragDownCallback.isDragDownEnabledForView(mStartingChild)) {
|
||||
mCallback.setUserLockedChild(mStartingChild, true);
|
||||
} else {
|
||||
mStartingChild = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleExpansion(float heightDelta, ExpandableView child) {
|
||||
if (heightDelta < 0) {
|
||||
heightDelta = 0;
|
||||
}
|
||||
boolean expandable = child.isContentExpandable();
|
||||
float rubberbandFactor = expandable
|
||||
? RUBBERBAND_FACTOR_EXPANDABLE
|
||||
: RUBBERBAND_FACTOR_STATIC;
|
||||
float rubberband = heightDelta * rubberbandFactor;
|
||||
if (expandable
|
||||
&& (rubberband + child.getCollapsedHeight()) > child.getMaxContentHeight()) {
|
||||
float overshoot =
|
||||
(rubberband + child.getCollapsedHeight()) - child.getMaxContentHeight();
|
||||
overshoot *= (1 - RUBBERBAND_FACTOR_STATIC);
|
||||
rubberband -= overshoot;
|
||||
}
|
||||
child.setActualHeight((int) (child.getCollapsedHeight() + rubberband));
|
||||
}
|
||||
|
||||
private void cancelExpansion(final ExpandableView child) {
|
||||
if (child.getActualHeight() == child.getCollapsedHeight()) {
|
||||
mCallback.setUserLockedChild(child, false);
|
||||
return;
|
||||
}
|
||||
ObjectAnimator anim = ObjectAnimator.ofInt(child, "actualHeight",
|
||||
child.getActualHeight(), child.getCollapsedHeight());
|
||||
anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS);
|
||||
anim.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
mCallback.setUserLockedChild(child, false);
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
}
|
||||
|
||||
private void cancelExpansion() {
|
||||
ValueAnimator anim = ValueAnimator.ofFloat(mLastHeight, 0);
|
||||
anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
|
||||
anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS);
|
||||
anim.addUpdateListener(animation -> {
|
||||
mDragDownCallback.setEmptyDragAmount((Float) animation.getAnimatedValue());
|
||||
});
|
||||
anim.start();
|
||||
}
|
||||
|
||||
private void stopDragging() {
|
||||
mFalsingCollector.onNotificationStopDraggingDown();
|
||||
if (mStartingChild != null) {
|
||||
cancelExpansion(mStartingChild);
|
||||
mStartingChild = null;
|
||||
} else {
|
||||
cancelExpansion();
|
||||
}
|
||||
mDraggingDown = false;
|
||||
mDragDownCallback.onDragDownReset();
|
||||
}
|
||||
|
||||
private ExpandableView findView(float x, float y) {
|
||||
mHost.getLocationOnScreen(mTemp2);
|
||||
x += mTemp2[0];
|
||||
y += mTemp2[1];
|
||||
return mCallback.getChildAtRawPosition(x, y);
|
||||
}
|
||||
|
||||
public boolean isDraggingDown() {
|
||||
return mDraggingDown;
|
||||
}
|
||||
|
||||
public boolean isDragDownEnabled() {
|
||||
return mDragDownCallback.isDragDownEnabledForView(null);
|
||||
}
|
||||
|
||||
public interface DragDownCallback {
|
||||
|
||||
/**
|
||||
* @return true if the interaction is accepted, false if it should be cancelled
|
||||
*/
|
||||
boolean canDragDown();
|
||||
|
||||
/** Call when a view has been dragged. */
|
||||
void onDraggedDown(View startingChild, int dragLengthY);
|
||||
void onDragDownReset();
|
||||
|
||||
/**
|
||||
* The user has dragged either above or below the threshold
|
||||
* @param above whether he dragged above it
|
||||
*/
|
||||
void onCrossedThreshold(boolean above);
|
||||
void onTouchSlopExceeded();
|
||||
void setEmptyDragAmount(float amount);
|
||||
boolean isFalsingCheckNeeded();
|
||||
|
||||
/**
|
||||
* Is dragging down enabled on a given view
|
||||
* @param view The view to check or {@code null} to check if it's enabled at all
|
||||
*/
|
||||
boolean isDragDownEnabledForView(ExpandableView view);
|
||||
|
||||
/**
|
||||
* @return if drag down is enabled anywhere, not just on selected views.
|
||||
*/
|
||||
boolean isDragDownAnywhereEnabled();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
package com.android.systemui.statusbar
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewConfiguration
|
||||
import com.android.systemui.ExpandHelper
|
||||
import com.android.systemui.Gefingerpoken
|
||||
import com.android.systemui.animation.Interpolators
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.classifier.Classifier
|
||||
import com.android.systemui.classifier.FalsingCollector
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.plugins.FalsingManager
|
||||
import com.android.systemui.statusbar.notification.row.ExpandableView
|
||||
|
||||
/**
|
||||
* A utility class to enable the downward swipe on the lockscreen to go to the full shade and expand
|
||||
* the notification where the drag started.
|
||||
*/
|
||||
class DragDownHelper(private val falsingManager: FalsingManager,
|
||||
private val expandCallback: ExpandHelper.Callback,
|
||||
private val dragDownCallback: DragDownCallback,
|
||||
private val falsingCollector: FalsingCollector,
|
||||
private val host: View,
|
||||
context: Context): Gefingerpoken {
|
||||
|
||||
private val minDragDistance: Int
|
||||
private var initialTouchX = 0f
|
||||
private var initialTouchY = 0f
|
||||
private val touchSlop: Float
|
||||
private val slopMultiplier: Float
|
||||
private val temp2 = IntArray(2)
|
||||
private var draggedFarEnough = false
|
||||
private var startingChild: ExpandableView? = null
|
||||
private var lastHeight = 0f
|
||||
var isDraggingDown = false
|
||||
private set
|
||||
|
||||
init {
|
||||
minDragDistance = context.resources.getDimensionPixelSize(
|
||||
R.dimen.keyguard_drag_down_min_distance)
|
||||
val configuration = ViewConfiguration.get(context)
|
||||
touchSlop = configuration.scaledTouchSlop.toFloat()
|
||||
slopMultiplier = configuration.scaledAmbiguousGestureMultiplier
|
||||
}
|
||||
|
||||
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
|
||||
val x = event.x
|
||||
val y = event.y
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
draggedFarEnough = false
|
||||
isDraggingDown = false
|
||||
startingChild = null
|
||||
initialTouchY = y
|
||||
initialTouchX = x
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
val h = y - initialTouchY
|
||||
// Adjust the touch slop if another gesture may be being performed.
|
||||
val touchSlop = if (event.classification
|
||||
== MotionEvent.CLASSIFICATION_AMBIGUOUS_GESTURE)
|
||||
touchSlop * slopMultiplier
|
||||
else
|
||||
touchSlop
|
||||
if (h > touchSlop && h > Math.abs(x - initialTouchX)) {
|
||||
falsingCollector.onNotificationStartDraggingDown()
|
||||
isDraggingDown = true
|
||||
captureStartingChild(initialTouchX, initialTouchY)
|
||||
initialTouchY = y
|
||||
initialTouchX = x
|
||||
dragDownCallback.onTouchSlopExceeded()
|
||||
return startingChild != null || dragDownCallback.isDragDownAnywhereEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
if (!isDraggingDown) {
|
||||
return false
|
||||
}
|
||||
val x = event.x
|
||||
val y = event.y
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
lastHeight = y - initialTouchY
|
||||
captureStartingChild(initialTouchX, initialTouchY)
|
||||
if (startingChild != null) {
|
||||
handleExpansion(lastHeight, startingChild!!)
|
||||
} else {
|
||||
dragDownCallback.setEmptyDragAmount(lastHeight)
|
||||
}
|
||||
if (lastHeight > minDragDistance) {
|
||||
if (!draggedFarEnough) {
|
||||
draggedFarEnough = true
|
||||
dragDownCallback.onCrossedThreshold(true)
|
||||
}
|
||||
} else {
|
||||
if (draggedFarEnough) {
|
||||
draggedFarEnough = false
|
||||
dragDownCallback.onCrossedThreshold(false)
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
MotionEvent.ACTION_UP -> if (!falsingManager.isUnlockingDisabled && !isFalseTouch
|
||||
&& dragDownCallback.canDragDown()) {
|
||||
dragDownCallback.onDraggedDown(startingChild, (y - initialTouchY).toInt())
|
||||
if (startingChild == null) {
|
||||
cancelExpansion()
|
||||
} else {
|
||||
expandCallback.setUserLockedChild(startingChild, false)
|
||||
startingChild = null
|
||||
}
|
||||
isDraggingDown = false
|
||||
} else {
|
||||
stopDragging()
|
||||
return false
|
||||
}
|
||||
MotionEvent.ACTION_CANCEL -> {
|
||||
stopDragging()
|
||||
return false
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private val isFalseTouch: Boolean
|
||||
get() {
|
||||
return if (!dragDownCallback.isFalsingCheckNeeded) {
|
||||
false
|
||||
} else {
|
||||
falsingManager.isFalseTouch(Classifier.NOTIFICATION_DRAG_DOWN) || !draggedFarEnough
|
||||
}
|
||||
}
|
||||
|
||||
private fun captureStartingChild(x: Float, y: Float) {
|
||||
if (startingChild == null) {
|
||||
startingChild = findView(x, y)
|
||||
if (startingChild != null) {
|
||||
if (dragDownCallback.isDragDownEnabledForView(startingChild)) {
|
||||
expandCallback.setUserLockedChild(startingChild, true)
|
||||
} else {
|
||||
startingChild = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleExpansion(heightDelta: Float, child: ExpandableView) {
|
||||
var hDelta = heightDelta
|
||||
if (hDelta < 0) {
|
||||
hDelta = 0f
|
||||
}
|
||||
val expandable = child.isContentExpandable
|
||||
val rubberbandFactor = if (expandable) {
|
||||
RUBBERBAND_FACTOR_EXPANDABLE
|
||||
} else {
|
||||
RUBBERBAND_FACTOR_STATIC
|
||||
}
|
||||
var rubberband = hDelta * rubberbandFactor
|
||||
if (expandable && rubberband + child.collapsedHeight > child.maxContentHeight) {
|
||||
var overshoot = rubberband + child.collapsedHeight - child.maxContentHeight
|
||||
overshoot *= 1 - RUBBERBAND_FACTOR_STATIC
|
||||
rubberband -= overshoot
|
||||
}
|
||||
child.actualHeight = (child.collapsedHeight + rubberband).toInt()
|
||||
}
|
||||
|
||||
private fun cancelExpansion(child: ExpandableView) {
|
||||
if (child.actualHeight == child.collapsedHeight) {
|
||||
expandCallback.setUserLockedChild(child, false)
|
||||
return
|
||||
}
|
||||
val anim = ObjectAnimator.ofInt(child, "actualHeight",
|
||||
child.actualHeight, child.collapsedHeight)
|
||||
anim.interpolator = Interpolators.FAST_OUT_SLOW_IN
|
||||
anim.duration = SPRING_BACK_ANIMATION_LENGTH_MS.toLong()
|
||||
anim.addListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
expandCallback.setUserLockedChild(child, false)
|
||||
}
|
||||
})
|
||||
anim.start()
|
||||
}
|
||||
|
||||
private fun cancelExpansion() {
|
||||
val anim = ValueAnimator.ofFloat(lastHeight, 0f)
|
||||
anim.interpolator = Interpolators.FAST_OUT_SLOW_IN
|
||||
anim.duration = SPRING_BACK_ANIMATION_LENGTH_MS.toLong()
|
||||
anim.addUpdateListener { animation: ValueAnimator ->
|
||||
dragDownCallback.setEmptyDragAmount(animation.animatedValue as Float)
|
||||
}
|
||||
anim.start()
|
||||
}
|
||||
|
||||
private fun stopDragging() {
|
||||
falsingCollector.onNotificationStopDraggingDown()
|
||||
if (startingChild != null) {
|
||||
cancelExpansion(startingChild!!)
|
||||
startingChild = null
|
||||
} else {
|
||||
cancelExpansion()
|
||||
}
|
||||
isDraggingDown = false
|
||||
dragDownCallback.onDragDownReset()
|
||||
}
|
||||
|
||||
private fun findView(x: Float, y: Float): ExpandableView {
|
||||
host.getLocationOnScreen(temp2)
|
||||
return expandCallback.getChildAtRawPosition(x + temp2[0] , y + temp2[1])
|
||||
}
|
||||
|
||||
val isDragDownEnabled: Boolean
|
||||
get() = dragDownCallback.isDragDownEnabledForView(null)
|
||||
|
||||
interface DragDownCallback {
|
||||
|
||||
/**
|
||||
* @return true if the interaction is accepted, false if it should be cancelled
|
||||
*/
|
||||
fun canDragDown(): Boolean
|
||||
|
||||
/**
|
||||
* Call when a view has been dragged.
|
||||
**/
|
||||
fun onDraggedDown(startingChild: View?, dragLengthY: Int)
|
||||
fun onDragDownReset()
|
||||
|
||||
/**
|
||||
* The user has dragged either above or below the threshold
|
||||
* @param above whether they dragged above it
|
||||
*/
|
||||
fun onCrossedThreshold(above: Boolean)
|
||||
fun onTouchSlopExceeded()
|
||||
fun setEmptyDragAmount(amount: Float)
|
||||
val isFalsingCheckNeeded: Boolean
|
||||
|
||||
/**
|
||||
* Is dragging down enabled on a given view
|
||||
* @param view The view to check or `null` to check if it's enabled at all
|
||||
*/
|
||||
fun isDragDownEnabledForView(view: ExpandableView?): Boolean
|
||||
|
||||
/**
|
||||
* @return if drag down is enabled anywhere, not just on selected views.
|
||||
*/
|
||||
val isDragDownAnywhereEnabled: Boolean
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val RUBBERBAND_FACTOR_EXPANDABLE = 0.5f
|
||||
private const val RUBBERBAND_FACTOR_STATIC = 0.15f
|
||||
private const val SPRING_BACK_ANIMATION_LENGTH_MS = 375
|
||||
}
|
||||
}
|
||||
@@ -409,9 +409,8 @@ public class NotificationShadeWindowViewController {
|
||||
ExpandHelper.Callback expandHelperCallback = mStackScrollLayout.getExpandHelperCallback();
|
||||
DragDownHelper.DragDownCallback dragDownCallback = mStackScrollLayout.getDragDownCallback();
|
||||
setDragDownHelper(
|
||||
new DragDownHelper(
|
||||
mView.getContext(), mView, expandHelperCallback,
|
||||
dragDownCallback, mFalsingManager, mFalsingCollector));
|
||||
new DragDownHelper(mFalsingManager, expandHelperCallback, dragDownCallback,
|
||||
mFalsingCollector, mView, mView.getContext()));
|
||||
|
||||
mDepthController.setRoot(mView);
|
||||
mNotificationPanelViewController.addExpansionListener(mDepthController);
|
||||
|
||||
Reference in New Issue
Block a user