Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ecbab366 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Introduce SHADE_LOCKED as a special state for the shade.

This state can be either reached by tapping the more card or dragging
down on any card. In this state, the shade is fully interactive, but
the phone is stil locked. This state can only be enterred if
redaction is off but security is on. If redaction is on, we will show
the bouncer instead and go to the normal shade.

Bug: 14161523
Change-Id: I95ca0991745ffc11ed1028581e3da15265c12ae5
parent 434bdf50
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -268,4 +268,7 @@
    <dimen name="quick_settings_tmp_scrim_text_size">30dp</dimen>

    <dimen name="notifications_top_padding">8dp</dimen>
    
    <!-- Minimum distance the user has to drag down to go to the full shade. -->
    <dimen name="keyguard_drag_down_min_distance">100dp</dimen>
</resources>
+4 −9
Original line number Diff line number Diff line
@@ -88,14 +88,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
                if (mDownY > getActualHeight()) {
                    return false;
                }

                // Call the listener tentatively directly, even if we don't know whether the user
                // will stay within the touch slop, as the listener is implemented as a scale
                // animation, which is cancellable without jarring effects when swiping away
                // notifications.
                if (mOnActivatedListener != null) {
                    mOnActivatedListener.onActivated(this);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isWithinTouchSlop(event)) {
@@ -109,8 +101,8 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
                        makeActive(event.getX(), event.getY());
                        postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
                    } else {
                        performClick();
                        makeInactive();
                        performClick();
                    }
                } else {
                    makeInactive();
@@ -128,6 +120,9 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
    private void makeActive(float x, float y) {
        mCustomBackground.setHotspot(0, x, y);
        mActivated = true;
        if (mOnActivatedListener != null) {
            mOnActivatedListener.onActivated(this);
        }
    }

    /**
+11 −6
Original line number Diff line number Diff line
@@ -167,7 +167,11 @@ public abstract class BaseStatusBar extends SystemUI implements

    protected int mZenMode;

    protected boolean mOnKeyguard;
    /**
     * The {@link StatusBarState} of the status bar.
     */
    protected int mState;

    protected NotificationOverflowContainer mKeyguardIconOverflowContainer;

    public boolean isDeviceProvisioned() {
@@ -1057,9 +1061,10 @@ public abstract class BaseStatusBar extends SystemUI implements
        mKeyguardIconOverflowContainer.getIconsView().removeAllViews();
        int n = mNotificationData.size();
        int visibleNotifications = 0;
        boolean onKeyguard = mState == StatusBarState.KEYGUARD;
        for (int i = n-1; i >= 0; i--) {
            NotificationData.Entry entry = mNotificationData.get(i);
            if (mOnKeyguard) {
            if (onKeyguard) {
                entry.row.setExpansionDisabled(true);
            } else {
                entry.row.setExpansionDisabled(false);
@@ -1068,10 +1073,10 @@ public abstract class BaseStatusBar extends SystemUI implements
                    entry.row.setSystemExpanded(top);
                }
            }
            entry.row.setDimmed(mOnKeyguard);
            entry.row.setLocked(mOnKeyguard);
            entry.row.setDimmed(onKeyguard);
            entry.row.setLocked(onKeyguard);
            boolean showOnKeyguard = shouldShowOnKeyguard(entry.notification);
            if (mOnKeyguard && (visibleNotifications >= maxKeyguardNotifications
            if (onKeyguard && (visibleNotifications >= maxKeyguardNotifications
                    || !showOnKeyguard)) {
                entry.row.setVisibility(View.GONE);
                if (showOnKeyguard) {
@@ -1087,7 +1092,7 @@ public abstract class BaseStatusBar extends SystemUI implements
            }
        }

        if (mOnKeyguard && mKeyguardIconOverflowContainer.getIconsView().getChildCount() > 0) {
        if (onKeyguard && mKeyguardIconOverflowContainer.getIconsView().getChildCount() > 0) {
            mKeyguardIconOverflowContainer.setVisibility(View.VISIBLE);
        } else {
            mKeyguardIconOverflowContainer.setVisibility(View.GONE);
+158 −0
Original line number Diff line number Diff line
/*
 * 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 android.content.Context;
import android.util.ArraySet;
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 java.util.HashSet;

/**
 * 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 int mMinDragDistance;
    private ExpandHelper.Callback mCallback;
    private float mInitialTouchX;
    private float mInitialTouchY;
    private boolean mDraggingDown;
    private float mTouchSlop;
    private OnDragDownListener mOnDragDownListener;
    private View mHost;
    private final int[] mTemp2 = new int[2];
    private final ArraySet<View> mHoveredChildren = new ArraySet<View>();
    private boolean mDraggedFarEnough;
    private View mStartingChild;

    public DragDownHelper(Context context, View host, ExpandHelper.Callback callback,
            OnDragDownListener onDragDownListener) {
        mMinDragDistance = context.getResources().getDimensionPixelSize(
                R.dimen.keyguard_drag_down_min_distance);
        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mCallback = callback;
        mOnDragDownListener = onDragDownListener;
        mHost = host;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        final float x = event.getX();
        final float y = event.getY();

        switch (event.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                mHoveredChildren.clear();
                mDraggedFarEnough = false;
                mDraggingDown = false;
                mStartingChild = null;
                mInitialTouchY = y;
                mInitialTouchX = x;
                break;

            case MotionEvent.ACTION_MOVE:
                final float h = y - mInitialTouchY;
                if (h > mTouchSlop && h > Math.abs(x - mInitialTouchX)) {
                    mDraggingDown = true;
                    mInitialTouchY = y;
                    mInitialTouchX = x;
                    return true;
                }
                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:
                final float h = y - mInitialTouchY;
                View child = findView(x, y);
                if (child != null) {
                    hoverChild(findView(x, y));
                }
                if (h > mMinDragDistance) {
                    if (!mDraggedFarEnough) {
                        mDraggedFarEnough = true;
                        mOnDragDownListener.onThresholdReached();
                    }
                } else {
                    if (mDraggedFarEnough) {
                        mDraggedFarEnough = false;
                        mOnDragDownListener.onReset();
                    }
                }
                return true;
            case MotionEvent.ACTION_UP:
                if (mDraggedFarEnough) {
                    mOnDragDownListener.onDraggedDown(mStartingChild);
                } else {
                    stopDragging();
                    return false;
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                stopDragging();
                return false;
        }
        return false;
    }

    private void stopDragging() {
        mDraggingDown = false;
        mOnDragDownListener.onReset();
    }

    private void hoverChild(View child) {
        if (mHoveredChildren.isEmpty()) {
            mStartingChild = child;
        }
        if (!mHoveredChildren.contains(child)) {
            mOnDragDownListener.onHover(child);
            mHoveredChildren.add(child);
        }
    }

    private View findView(float x, float y) {
        mHost.getLocationOnScreen(mTemp2);
        x += mTemp2[0];
        y += mTemp2[1];
        return mCallback.getChildAtRawPosition(x, y);
    }

    public interface OnDragDownListener {
        void onHover(View child);
        void onDraggedDown(View startingChild);
        void onReset();
        void onThresholdReached();
    }
}
+5 −2
Original line number Diff line number Diff line
@@ -23,7 +23,8 @@ import android.view.accessibility.AccessibilityEvent;

import com.android.systemui.R;

public class ExpandableNotificationRow extends ActivatableNotificationView {
public class ExpandableNotificationRow extends ActivatableNotificationView implements
        NotificationActivatable {
    private int mRowMinHeight;
    private int mRowMaxHeight;

@@ -64,7 +65,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
        mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
        mPrivateLayout = (NotificationContentView) findViewById(R.id.expanded);

        mActivator = new NotificationActivator(this);
        mActivator = new NotificationActivator(this, this);
    }

    @Override
@@ -113,6 +114,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
    public void setUserExpanded(boolean userExpanded) {
        mHasUserChangedExpansion = true;
        mUserExpanded = userExpanded;
        applyExpansionToLayout();
    }

    public boolean isUserLocked() {
@@ -225,6 +227,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
        return mMaxExpandHeight;
    }

    @Override
    public NotificationActivator getActivator() {
        return mActivator;
    }
Loading