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

Commit 9eaa39c4 authored by Peter Kalauskas's avatar Peter Kalauskas Committed by Automerger Merge Worker
Browse files

Merge changes I3f3f10e8,I527e401b into sc-dev am: 9bcd1aef

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13608825

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: I50c4c02b57713011b6945c143d2988ed30185938
parents 08bb6f8b 9bcd1aef
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -37,12 +37,6 @@
        android:layout_height="match_parent"
        android:layout_height="match_parent"
        android:layout_width="match_parent" />
        android:layout_width="match_parent" />


    <ViewStub
        android:id="@+id/keyguard_user_switcher_stub"
        android:layout="@layout/keyguard_user_switcher"
        android:layout_height="match_parent"
        android:layout_width="match_parent" />

    <include
    <include
        layout="@layout/keyguard_status_view"
        layout="@layout/keyguard_status_view"
        android:visibility="gone" />
        android:visibility="gone" />
@@ -109,5 +103,11 @@
        layout="@layout/keyguard_bottom_area"
        layout="@layout/keyguard_bottom_area"
        android:visibility="gone" />
        android:visibility="gone" />


    <ViewStub
        android:id="@+id/keyguard_user_switcher_stub"
        android:layout="@layout/keyguard_user_switcher"
        android:layout_height="match_parent"
        android:layout_width="match_parent" />

    <include layout="@layout/status_bar_expanded_plugin_frame"/>
    <include layout="@layout/status_bar_expanded_plugin_frame"/>
</com.android.systemui.statusbar.phone.NotificationPanelView>
</com.android.systemui.statusbar.phone.NotificationPanelView>
+11 −10
Original line number Original line Diff line number Diff line
@@ -89,7 +89,8 @@ public class KeyguardClockPositionAlgorithm {
    private int mNotificationStackHeight;
    private int mNotificationStackHeight;


    /**
    /**
     * Minimum top margin to avoid overlap with status bar.
     * Minimum top margin to avoid overlap with status bar, lock icon, or multi-user switcher
     * avatar.
     */
     */
    private int mMinTopMargin;
    private int mMinTopMargin;


@@ -186,15 +187,15 @@ public class KeyguardClockPositionAlgorithm {
    /**
    /**
     * Sets up algorithm values.
     * Sets up algorithm values.
     */
     */
    public void setup(int statusBarMinHeight, int maxShadeBottom, int notificationStackHeight,
    public void setup(int keyguardStatusBarHeaderHeight, int maxShadeBottom,
            float panelExpansion, int parentHeight, int keyguardStatusHeight,
            int notificationStackHeight, float panelExpansion, int parentHeight,
            int userSwitchHeight, int clockPreferredY, int userSwitchPreferredY,
            int keyguardStatusHeight, int userSwitchHeight, int clockPreferredY,
            boolean hasCustomClock, boolean hasVisibleNotifs, float dark, float emptyDragAmount,
            int userSwitchPreferredY, boolean hasCustomClock, boolean hasVisibleNotifs, float dark,
            boolean bypassEnabled, int unlockedStackScrollerPadding, boolean showLockIcon,
            float emptyDragAmount, boolean bypassEnabled, int unlockedStackScrollerPadding,
            float qsExpansion, int cutoutTopInset) {
            boolean showLockIcon, float qsExpansion, int cutoutTopInset) {
        mMinTopMargin = statusBarMinHeight + (showLockIcon
        mMinTopMargin = keyguardStatusBarHeaderHeight + Math.max(showLockIcon
                ? mContainerTopPaddingWithLockIcon : mContainerTopPaddingWithoutLockIcon)
                        ? mContainerTopPaddingWithLockIcon : mContainerTopPaddingWithoutLockIcon,
                + userSwitchHeight;
                userSwitchHeight);
        mMaxShadeBottom = maxShadeBottom;
        mMaxShadeBottom = maxShadeBottom;
        mNotificationStackHeight = notificationStackHeight;
        mNotificationStackHeight = notificationStackHeight;
        mPanelExpansion = panelExpansion;
        mPanelExpansion = panelExpansion;
+6 −48
Original line number Original line Diff line number Diff line
@@ -287,21 +287,6 @@ public class NotificationPanelViewController extends PanelViewController {
                }
                }
    };
    };


    final KeyguardUserSwitcherController.KeyguardUserSwitcherListener
            mKeyguardUserSwitcherListener =
            new KeyguardUserSwitcherController.KeyguardUserSwitcherListener() {
                @Override
                public void onKeyguardUserSwitcherChanged(boolean open) {
                    if (mKeyguardUserSwitcherController == null) {
                        updateUserSwitcherVisibility(false);
                    } else if (!mKeyguardUserSwitcherController.isSimpleUserSwitcher()) {
                        updateUserSwitcherVisibility(open
                                && mKeyguardStateController.isShowing()
                                && !mKeyguardStateController.isKeyguardFadingAway());
                    }
                }
            };

    private final LayoutInflater mLayoutInflater;
    private final LayoutInflater mLayoutInflater;
    private final PowerManager mPowerManager;
    private final PowerManager mPowerManager;
    private final AccessibilityManager mAccessibilityManager;
    private final AccessibilityManager mAccessibilityManager;
@@ -329,7 +314,6 @@ public class NotificationPanelViewController extends PanelViewController {


    private KeyguardAffordanceHelper mAffordanceHelper;
    private KeyguardAffordanceHelper mAffordanceHelper;
    private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
    private KeyguardQsUserSwitchController mKeyguardQsUserSwitchController;
    private boolean mKeyguardUserSwitcherIsShowing;
    private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
    private KeyguardUserSwitcherController mKeyguardUserSwitcherController;
    private KeyguardStatusBarView mKeyguardStatusBar;
    private KeyguardStatusBarView mKeyguardStatusBar;
    private ViewGroup mBigClockContainer;
    private ViewGroup mBigClockContainer;
@@ -374,6 +358,7 @@ public class NotificationPanelViewController extends PanelViewController {
    private ValueAnimator mQsExpansionAnimator;
    private ValueAnimator mQsExpansionAnimator;
    private FlingAnimationUtils mFlingAnimationUtils;
    private FlingAnimationUtils mFlingAnimationUtils;
    private int mStatusBarMinHeight;
    private int mStatusBarMinHeight;
    private int mStatusBarHeaderHeightKeyguard;
    private int mNotificationsHeaderCollideDistance;
    private int mNotificationsHeaderCollideDistance;
    private float mEmptyDragAmount;
    private float mEmptyDragAmount;
    private float mDownX;
    private float mDownX;
@@ -772,6 +757,8 @@ public class NotificationPanelViewController extends PanelViewController {
                .setMaxLengthSeconds(0.4f).build();
                .setMaxLengthSeconds(0.4f).build();
        mStatusBarMinHeight = mResources.getDimensionPixelSize(
        mStatusBarMinHeight = mResources.getDimensionPixelSize(
                com.android.internal.R.dimen.status_bar_height);
                com.android.internal.R.dimen.status_bar_height);
        mStatusBarHeaderHeightKeyguard = mResources.getDimensionPixelSize(
                R.dimen.status_bar_header_height_keyguard);
        mQsPeekHeight = mResources.getDimensionPixelSize(R.dimen.qs_peek_height);
        mQsPeekHeight = mResources.getDimensionPixelSize(R.dimen.qs_peek_height);
        mNotificationsHeaderCollideDistance = mResources.getDimensionPixelSize(
        mNotificationsHeaderCollideDistance = mResources.getDimensionPixelSize(
                R.dimen.header_notifications_collide_distance);
                R.dimen.header_notifications_collide_distance);
@@ -808,7 +795,6 @@ public class NotificationPanelViewController extends PanelViewController {
            // Try to close the switcher so that callbacks are triggered if necessary.
            // Try to close the switcher so that callbacks are triggered if necessary.
            // Otherwise, NPV can get into a state where some of the views are still hidden
            // Otherwise, NPV can get into a state where some of the views are still hidden
            mKeyguardUserSwitcherController.closeSwitcherIfOpenAndNotSimple(false);
            mKeyguardUserSwitcherController.closeSwitcherIfOpenAndNotSimple(false);
            mKeyguardUserSwitcherController.removeCallback();
        }
        }


        mKeyguardQsUserSwitchController = null;
        mKeyguardQsUserSwitchController = null;
@@ -828,7 +814,6 @@ public class NotificationPanelViewController extends PanelViewController {
                    mKeyguardUserSwitcherComponentFactory.build(keyguardUserSwitcherView);
                    mKeyguardUserSwitcherComponentFactory.build(keyguardUserSwitcherView);
            mKeyguardUserSwitcherController =
            mKeyguardUserSwitcherController =
                    userSwitcherComponent.getKeyguardUserSwitcherController();
                    userSwitcherComponent.getKeyguardUserSwitcherController();
            mKeyguardUserSwitcherController.setCallback(mKeyguardUserSwitcherListener);
            mKeyguardUserSwitcherController.init();
            mKeyguardUserSwitcherController.init();
            mKeyguardStatusBar.setKeyguardUserSwitcherEnabled(true);
            mKeyguardStatusBar.setKeyguardUserSwitcherEnabled(true);
        } else {
        } else {
@@ -1069,7 +1054,7 @@ public class NotificationPanelViewController extends PanelViewController {
            int totalHeight = mView.getHeight();
            int totalHeight = mView.getHeight();
            int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
            int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
            int clockPreferredY = mKeyguardStatusViewController.getClockPreferredY(totalHeight);
            int clockPreferredY = mKeyguardStatusViewController.getClockPreferredY(totalHeight);
            int userSwitcherPreferredY = mStatusBarMinHeight;
            int userSwitcherPreferredY = mStatusBarHeaderHeightKeyguard;
            boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
            boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
            final boolean hasVisibleNotifications = mNotificationStackScrollLayoutController
            final boolean hasVisibleNotifications = mNotificationStackScrollLayoutController
                    .getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMedia();
                    .getVisibleNotificationCount() != 0 || mMediaDataManager.hasActiveMedia();
@@ -1078,7 +1063,8 @@ public class NotificationPanelViewController extends PanelViewController {
                    ? mKeyguardQsUserSwitchController.getUserIconHeight()
                    ? mKeyguardQsUserSwitchController.getUserIconHeight()
                    : (mKeyguardUserSwitcherController != null
                    : (mKeyguardUserSwitcherController != null
                            ? mKeyguardUserSwitcherController.getUserIconHeight() : 0);
                            ? mKeyguardUserSwitcherController.getUserIconHeight() : 0);
            mClockPositionAlgorithm.setup(mStatusBarMinHeight, totalHeight - bottomPadding,
            mClockPositionAlgorithm.setup(mStatusBarHeaderHeightKeyguard,
                    totalHeight - bottomPadding,
                    mNotificationStackScrollLayoutController.getIntrinsicContentHeight(),
                    mNotificationStackScrollLayoutController.getIntrinsicContentHeight(),
                    getExpandedFraction(),
                    getExpandedFraction(),
                    totalHeight,
                    totalHeight,
@@ -3523,34 +3509,6 @@ public class NotificationPanelViewController extends PanelViewController {
        return false;
        return false;
    }
    }


    private void updateUserSwitcherVisibility(boolean open) {
        // Do not update if previously called with the same state.
        if (mKeyguardUserSwitcherIsShowing == open) {
            return;
        }
        mKeyguardUserSwitcherIsShowing = open;

        if (open) {
            animateKeyguardStatusBarOut();
            mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
                    mBarState,
                    true /* keyguardFadingAway */,
                    true /* goingToFullShade */,
                    mBarState);
            setKeyguardBottomAreaVisibility(mBarState, true);
            mNotificationContainerParent.setVisibility(View.GONE);
        } else {
            animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
            mKeyguardStatusViewController.setKeyguardStatusViewVisibility(
                    StatusBarState.KEYGUARD,
                    false,
                    false,
                    StatusBarState.SHADE_LOCKED);
            setKeyguardBottomAreaVisibility(mBarState, false);
            mNotificationContainerParent.setVisibility(View.VISIBLE);
        }
    }

    private void updateDisabledUdfpsController() {
    private void updateDisabledUdfpsController() {
        final boolean udfpsEnrolled = mAuthController.getUdfpsRegion() != null
        final boolean udfpsEnrolled = mAuthController.getUdfpsRegion() != null
                && mAuthController.isUdfpsEnrolled(
                && mAuthController.isUdfpsEnrolled(
+52 −59
Original line number Original line Diff line number Diff line
@@ -19,9 +19,13 @@ package com.android.systemui.statusbar.policy;
import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_DISABLED_ALPHA;
import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_DISABLED_ALPHA;
import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_ENABLED_ALPHA;
import static com.android.systemui.statusbar.policy.UserSwitcherController.USER_SWITCH_ENABLED_ALPHA;


import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources;
import android.database.DataSetObserver;
import android.database.DataSetObserver;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.LayerDrawable;
import android.os.UserHandle;
import android.os.UserHandle;
@@ -50,7 +54,6 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.util.ViewController;
import com.android.systemui.util.ViewController;


import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.ArrayList;


import javax.inject.Inject;
import javax.inject.Inject;
@@ -73,9 +76,10 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
    private final KeyguardUserAdapter mAdapter;
    private final KeyguardUserAdapter mAdapter;
    private final KeyguardStateController mKeyguardStateController;
    private final KeyguardStateController mKeyguardStateController;
    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    private WeakReference<KeyguardUserSwitcherListener> mKeyguardUserSwitcherCallback;
    protected final SysuiStatusBarStateController mStatusBarStateController;
    protected final SysuiStatusBarStateController mStatusBarStateController;
    private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
    private final KeyguardVisibilityHelper mKeyguardVisibilityHelper;
    private ObjectAnimator mBgAnimator;
    private final KeyguardUserSwitcherScrim mBackground;


    // Child views of KeyguardUserSwitcherView
    // Child views of KeyguardUserSwitcherView
    private KeyguardUserSwitcherListView mListView;
    private KeyguardUserSwitcherListView mListView;
@@ -171,6 +175,7 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
                mUserSwitcherController, this);
                mUserSwitcherController, this);
        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
        mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView,
                keyguardStateController, dozeParameters);
                keyguardStateController, dozeParameters);
        mBackground = new KeyguardUserSwitcherScrim(context);
    }
    }


    @Override
    @Override
@@ -204,6 +209,9 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
        mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
        mKeyguardUpdateMonitor.registerCallback(mInfoCallback);
        mStatusBarStateController.addCallback(mStatusBarStateListener);
        mStatusBarStateController.addCallback(mStatusBarStateListener);
        mScreenLifecycle.addObserver(mScreenObserver);
        mScreenLifecycle.addObserver(mScreenObserver);
        mView.addOnLayoutChangeListener(mBackground);
        mView.setBackground(mBackground);
        mBackground.setAlpha(0);
    }
    }


    @Override
    @Override
@@ -217,6 +225,9 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
        mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
        mKeyguardUpdateMonitor.removeCallback(mInfoCallback);
        mStatusBarStateController.removeCallback(mStatusBarStateListener);
        mStatusBarStateController.removeCallback(mStatusBarStateListener);
        mScreenLifecycle.removeObserver(mScreenObserver);
        mScreenLifecycle.removeObserver(mScreenObserver);
        mView.removeOnLayoutChangeListener(mBackground);
        mView.setBackground(null);
        mBackground.setAlpha(0);
    }
    }


    /**
    /**
@@ -338,6 +349,13 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
                animate);
                animate);
        PropertyAnimator.setProperty(mListView, AnimatableProperty.TRANSLATION_X, -Math.abs(x),
        PropertyAnimator.setProperty(mListView, AnimatableProperty.TRANSLATION_X, -Math.abs(x),
                ANIMATION_PROPERTIES, animate);
                ANIMATION_PROPERTIES, animate);

        Rect r = new Rect();
        mListView.getDrawingRect(r);
        mView.offsetDescendantRectToMyCoords(mListView, r);
        mBackground.setGradientCenter(
                (int) (mListView.getTranslationX() + r.left + r.width() / 2),
                (int) (mListView.getTranslationY() + r.top + r.height() / 2));
    }
    }


    /**
    /**
@@ -372,49 +390,52 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
    }
    }


    /**
    /**
     * Remove the callback if it exists.
     * NOTE: switcher state is updated before animations finish.
     */
    public void removeCallback() {
        if (DEBUG) Log.d(TAG, "removeCallback");
        mKeyguardUserSwitcherCallback = null;
    }

    /**
     * Register to receive notifications about keyguard user switcher state
     * (see {@link KeyguardUserSwitcherListener}.
     *
     * Only one callback can be used at a time.
     *
     * @param callback The callback to register
     */
    public void setCallback(KeyguardUserSwitcherListener callback) {
        if (DEBUG) Log.d(TAG, "setCallback");
        mKeyguardUserSwitcherCallback = new WeakReference<>(callback);
    }

    /**
     * If user switcher state changes, notifies all {@link KeyguardUserSwitcherListener}.
     * Switcher state is updatd before animations finish.
     *
     *
     * @param animate true to animate transition. The user switcher state (i.e.
     * @param animate true to animate transition. The user switcher state (i.e.
     *                {@link #isUserSwitcherOpen()}) is updated before animation is finished.
     *                {@link #isUserSwitcherOpen()}) is updated before animation is finished.
     */
     */
    private void setUserSwitcherOpened(boolean open, boolean animate) {
    private void setUserSwitcherOpened(boolean open, boolean animate) {
        boolean wasOpen = mUserSwitcherOpen;
        if (DEBUG) {
        if (DEBUG) {
            Log.d(TAG, String.format("setUserSwitcherOpened: %b -> %b (animate=%b)", wasOpen,
            Log.d(TAG,
                    open, animate));
                    String.format("setUserSwitcherOpened: %b -> %b (animate=%b)",
                            mUserSwitcherOpen, open, animate));
        }
        }
        mUserSwitcherOpen = open;
        mUserSwitcherOpen = open;
        if (mUserSwitcherOpen != wasOpen) {
            notifyUserSwitcherStateChanged();
        }
        updateVisibilities(animate);
        updateVisibilities(animate);
    }
    }


    private void updateVisibilities(boolean animate) {
    private void updateVisibilities(boolean animate) {
        if (DEBUG) Log.d(TAG, String.format("updateVisibilities: animate=%b", animate));
        if (DEBUG) Log.d(TAG, String.format("updateVisibilities: animate=%b", animate));
        mEndGuestButton.animate().cancel();
        mEndGuestButton.animate().cancel();
        if (mBgAnimator != null) {
            mBgAnimator.cancel();
        }

        if (mUserSwitcherOpen) {
            mBgAnimator = ObjectAnimator.ofInt(mBackground, "alpha", 0, 255);
            mBgAnimator.setDuration(400);
            mBgAnimator.setInterpolator(Interpolators.ALPHA_IN);
            mBgAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mBgAnimator = null;
                }
            });
            mBgAnimator.start();
        } else {
            mBgAnimator = ObjectAnimator.ofInt(mBackground, "alpha", 255, 0);
            mBgAnimator.setDuration(400);
            mBgAnimator.setInterpolator(Interpolators.ALPHA_OUT);
            mBgAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mBgAnimator = null;
                }
            });
            mBgAnimator.start();
        }

        if (mUserSwitcherOpen && mCurrentUserIsGuest) {
        if (mUserSwitcherOpen && mCurrentUserIsGuest) {
            // Show the "End guest session" button
            // Show the "End guest session" button
            mEndGuestButton.setVisibility(View.VISIBLE);
            mEndGuestButton.setVisibility(View.VISIBLE);
@@ -459,34 +480,6 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS
        return mUserSwitcherOpen;
        return mUserSwitcherOpen;
    }
    }


    private void notifyUserSwitcherStateChanged() {
        if (DEBUG) {
            Log.d(TAG, String.format("notifyUserSwitcherStateChanged: mUserSwitcherOpen=%b",
                    mUserSwitcherOpen));
        }
        if (mKeyguardUserSwitcherCallback != null) {
            KeyguardUserSwitcherListener cb = mKeyguardUserSwitcherCallback.get();
            if (cb != null) {
                cb.onKeyguardUserSwitcherChanged(mUserSwitcherOpen);
            }
        }
    }

    /**
     * Callback for keyguard user switcher state information
     */
    public interface KeyguardUserSwitcherListener {

        /**
         * Called when the keyguard enters or leaves user switcher mode. This will be called
         * before the animations are finished.
         *
         * @param open if true, keyguard is showing the user switcher or transitioning from/to user
         *             switcher mode.
         */
        void onKeyguardUserSwitcherChanged(boolean open);
    }

    static class KeyguardUserAdapter extends
    static class KeyguardUserAdapter extends
            UserSwitcherController.BaseUserAdapter implements View.OnClickListener {
            UserSwitcherController.BaseUserAdapter implements View.OnClickListener {


+27 −18
Original line number Original line Diff line number Diff line
@@ -26,7 +26,6 @@ import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Shader;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.util.LayoutDirection;
import android.view.View;
import android.view.View;


import com.android.systemui.R;
import com.android.systemui.R;
@@ -38,13 +37,14 @@ public class KeyguardUserSwitcherScrim extends Drawable
        implements View.OnLayoutChangeListener {
        implements View.OnLayoutChangeListener {


    private static final float OUTER_EXTENT = 2.5f;
    private static final float OUTER_EXTENT = 2.5f;
    private static final float INNER_EXTENT = 0.75f;
    private static final float INNER_EXTENT = 0.25f;


    private int mDarkColor;
    private int mDarkColor;
    private int mTop;
    private int mAlpha = 255;
    private int mAlpha = 255;
    private Paint mRadialGradientPaint = new Paint();
    private Paint mRadialGradientPaint = new Paint();
    private int mLayoutWidth;
    private int mCircleX;
    private int mCircleY;
    private int mSize;


    public KeyguardUserSwitcherScrim(Context context) {
    public KeyguardUserSwitcherScrim(Context context) {
        mDarkColor = context.getColor(
        mDarkColor = context.getColor(
@@ -53,14 +53,11 @@ public class KeyguardUserSwitcherScrim extends Drawable


    @Override
    @Override
    public void draw(Canvas canvas) {
    public void draw(Canvas canvas) {
        boolean isLtr = getLayoutDirection() == LayoutDirection.LTR;
        if (mAlpha == 0) {
            return;
        }
        Rect bounds = getBounds();
        Rect bounds = getBounds();
        float width = bounds.width() * OUTER_EXTENT;
        canvas.drawRect(bounds.left, bounds.top, bounds.right, bounds.bottom, mRadialGradientPaint);
        float height = (mTop + bounds.height()) * OUTER_EXTENT;
        canvas.translate(0, -mTop);
        canvas.scale(1, height / width);
        canvas.drawRect(isLtr ? bounds.right - width : 0, 0,
                isLtr ? bounds.right : bounds.left + width, width, mRadialGradientPaint);
    }
    }


    @Override
    @Override
@@ -88,24 +85,36 @@ public class KeyguardUserSwitcherScrim extends Drawable
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
            int oldTop, int oldRight, int oldBottom) {
            int oldTop, int oldRight, int oldBottom) {
        if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) {
        if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) {
            mLayoutWidth = right - left;
            int width = right - left;
            mTop = top;
            int height = bottom - top;
            mSize = Math.max(width, height);
            updatePaint();
            updatePaint();
        }
        }
    }
    }


    private void updatePaint() {
    private void updatePaint() {
        if (mLayoutWidth == 0) {
        if (mSize == 0) {
            return;
            return;
        }
        }
        float radius = mLayoutWidth * OUTER_EXTENT;
        float outerRadius = mSize * OUTER_EXTENT;
        boolean isLtr = getLayoutDirection() == LayoutDirection.LTR;
        mRadialGradientPaint.setShader(
        mRadialGradientPaint.setShader(
                new RadialGradient(isLtr ? mLayoutWidth : 0, 0, radius,
                new RadialGradient(mCircleX, mCircleY, outerRadius,
                        new int[] { Color.argb(
                        new int[] { Color.argb(
                                        (int) (Color.alpha(mDarkColor) * mAlpha / 255f), 0, 0, 0),
                                        (int) (Color.alpha(mDarkColor) * mAlpha / 255f), 0, 0, 0),
                                Color.TRANSPARENT },
                                Color.TRANSPARENT },
                        new float[] { Math.max(0f, mLayoutWidth * INNER_EXTENT / radius), 1f },
                        new float[] { Math.max(0f, INNER_EXTENT / OUTER_EXTENT), 1f },
                        Shader.TileMode.CLAMP));
                        Shader.TileMode.CLAMP));
    }
    }

    /**
     * Sets the center of the radial gradient used as a background
     *
     * @param x
     * @param y
     */
    public void setGradientCenter(int x, int y) {
        mCircleX = x;
        mCircleY = y;
        updatePaint();
    }
}
}