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

Commit f1f0bd69 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add gradient clock to AOD/LS behind LS flag"

parents 2dbc9473 4116599e
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -61,6 +61,28 @@
             android:visibility="invisible"
             />
    </FrameLayout>
    <FrameLayout
        android:id="@+id/new_lockscreen_clock_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentTop="true"
        android:visibility="gone">
        <com.android.keyguard.GradientTextClock
            android:id="@+id/gradient_clock_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="100dp"
            android:letterSpacing="0.02"
            android:lineSpacingMultiplier=".8"
            android:includeFontPadding="false"
            android:fontFamily="sans-serif"
            android:typeface="monospace"
            android:format12Hour="hh\nmm"
            android:format24Hour="HH\nmm"
            android:elegantTextHeight="false"
        />
    </FrameLayout>
    <include layout="@layout/keyguard_status_area"
        android:id="@+id/keyguard_status_area"
        android:layout_width="match_parent"
+102 −0
Original line number Diff line number Diff line
/*
 * 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.keyguard;

import android.content.Context;
import android.graphics.LinearGradient;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.widget.TextClock;

/**
 * Displays the time with the hour positioned above the minutes. (ie: 09 above 30 is 9:30)
 * The time's text color is a gradient that changes its colors based on its controller.
 */
public class GradientTextClock extends TextClock {
    private int[] mGradientColors;
    private float[] mPositions;

    public GradientTextClock(Context context) {
        this(context, null, 0, 0);
    }

    public GradientTextClock(Context context, AttributeSet attrs) {
        this(context, attrs, 0, 0);
    }

    public GradientTextClock(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public GradientTextClock(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        addOnLayoutChangeListener(mOnLayoutChangeListener);
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        removeOnLayoutChangeListener(mOnLayoutChangeListener);
    }

    @Override
    public void refreshTime() {
        updatePaint();
        super.refreshTime();
    }

    @Override
    public void setFormat12Hour(CharSequence format) {
        super.setFormat12Hour(FORMAT_12);
    }

    @Override
    public void setFormat24Hour(CharSequence format) {
        super.setFormat24Hour(FORMAT_24);
    }

    public void setGradientColors(int[] colors) {
        mGradientColors = colors;
    }

    public void setColorPositions(float[] positions) {
        mPositions = positions;
    }

    private void updatePaint() {
        getPaint().setShader(
                new LinearGradient(
                        getX(), getY(), getX(), getMeasuredHeight() + getY(),
                        mGradientColors, mPositions, Shader.TileMode.REPEAT));
    }

    private final OnLayoutChangeListener mOnLayoutChangeListener =
            (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
                if (bottom != oldBottom || top != oldTop) {
                    updatePaint();
                }
            };

    public static final CharSequence FORMAT_12 = "hh\nmm";
    public static final CharSequence FORMAT_24 = "HH\nmm";
}
+22 −9
Original line number Diff line number Diff line
@@ -71,6 +71,16 @@ public class KeyguardClockSwitch extends RelativeLayout {
     */
    private TextClock mClockViewBold;

    /**
     * Gradient clock for usage when mode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL.
     */
    private TimeBasedColorsClockController mNewLockscreenClockViewController;

    /**
     * Frame for clock when mode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL.
     */
    private FrameLayout mNewLockscreenClockFrame;

    /**
     * Frame for default and custom clock.
     */
@@ -137,23 +147,22 @@ public class KeyguardClockSwitch extends RelativeLayout {
        mLockScreenMode = mode;
        RelativeLayout.LayoutParams statusAreaLP = (RelativeLayout.LayoutParams)
                mKeyguardStatusArea.getLayoutParams();
        RelativeLayout.LayoutParams clockLP = (RelativeLayout.LayoutParams)
                mSmallClockFrame.getLayoutParams();

        if (mode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
            mSmallClockFrame.setVisibility(GONE);
            mNewLockscreenClockFrame.setVisibility(VISIBLE);
            mNewLockscreenClockViewController.init();

            statusAreaLP.removeRule(RelativeLayout.BELOW);
            statusAreaLP.addRule(RelativeLayout.LEFT_OF, R.id.clock_view);
            statusAreaLP.addRule(RelativeLayout.LEFT_OF, R.id.new_lockscreen_clock_view);
            statusAreaLP.addRule(RelativeLayout.ALIGN_PARENT_START);

            clockLP.addRule(RelativeLayout.ALIGN_PARENT_END);
            clockLP.width = ViewGroup.LayoutParams.WRAP_CONTENT;
        } else {
            mSmallClockFrame.setVisibility(VISIBLE);
            mNewLockscreenClockFrame.setVisibility(GONE);

            statusAreaLP.removeRule(RelativeLayout.LEFT_OF);
            statusAreaLP.removeRule(RelativeLayout.ALIGN_PARENT_START);
            statusAreaLP.addRule(RelativeLayout.BELOW, R.id.clock_view);

            clockLP.removeRule(RelativeLayout.ALIGN_PARENT_END);
            clockLP.width = ViewGroup.LayoutParams.MATCH_PARENT;
        }

        requestLayout();
@@ -164,6 +173,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
        super.onFinishInflate();
        mClockView = findViewById(R.id.default_clock_view);
        mClockViewBold = findViewById(R.id.default_clock_view_bold);
        mNewLockscreenClockFrame = findViewById(R.id.new_lockscreen_clock_view);
        mNewLockscreenClockViewController =
                new TimeBasedColorsClockController(findViewById(R.id.gradient_clock_view));
        mSmallClockFrame = findViewById(R.id.clock_view);
        mKeyguardStatusArea = findViewById(R.id.keyguard_status_area);
    }
@@ -336,6 +348,7 @@ public class KeyguardClockSwitch extends RelativeLayout {
     * Refresh the time of the clock, due to either time tick broadcast or doze time tick alarm.
     */
    public void refresh() {
        mNewLockscreenClockViewController.refreshTime(System.currentTimeMillis());
        mClockView.refreshTime();
        mClockViewBold.refreshTime();
        if (mClockPlugin != null) {
+111 −3
Original line number Diff line number Diff line
@@ -33,9 +33,11 @@ import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.animation.Animation;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.slice.SliceItem;
@@ -55,8 +57,10 @@ import com.android.systemui.util.wakelock.KeepAwakeAnimationListener;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * View visible under the clock on the lock screen and AoD.
@@ -86,6 +90,8 @@ public class KeyguardSliceView extends LinearLayout {
    private float mRowWithHeaderTextSize;
    private View.OnClickListener mOnClickListener;

    private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;

    public KeyguardSliceView(Context context, AttributeSet attrs) {
        super(context, attrs);

@@ -142,6 +148,40 @@ public class KeyguardSliceView extends LinearLayout {
        }
    }

    /**
     * Updates the lockscreen mode which may change the layout of the keyguard slice view.
     */
    public void updateLockScreenMode(int mode) {
        mLockScreenMode = mode;
        if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
            // add top padding to better align with top of clock
            final int topPadding = (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP,
                    20,
                    getResources().getDisplayMetrics());
            mTitle.setPaddingRelative(0, topPadding, 0, 0);
            mTitle.setGravity(Gravity.START);
            setGravity(Gravity.START);
            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
            lp.removeRule(RelativeLayout.CENTER_HORIZONTAL);
            setLayoutParams(lp);
        } else {
            final int horizontalPaddingDpValue = (int) TypedValue.applyDimension(
                    TypedValue.COMPLEX_UNIT_DIP,
                    44,
                    getResources().getDisplayMetrics()
            );
            mTitle.setPaddingRelative(horizontalPaddingDpValue, 0, horizontalPaddingDpValue, 0);
            mTitle.setGravity(Gravity.CENTER_HORIZONTAL);
            setGravity(Gravity.CENTER_HORIZONTAL);
            RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
            lp.addRule(RelativeLayout.CENTER_HORIZONTAL);
            setLayoutParams(lp);
        }
        mRow.setLockscreenMode(mode);
        requestLayout();
    }

    Map<View, PendingIntent> showSlice(RowContent header, List<SliceContent> subItems) {
        Trace.beginSection("KeyguardSliceView#showSlice");
        mHasHeader = header != null;
@@ -166,6 +206,8 @@ public class KeyguardSliceView extends LinearLayout {
        final int startIndex = mHasHeader ? 1 : 0; // First item is header; skip it
        mRow.setVisibility(subItemsCount > 0 ? VISIBLE : GONE);
        LinearLayout.LayoutParams layoutParams = (LayoutParams) mRow.getLayoutParams();
        layoutParams.gravity = mLockScreenMode !=  KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL
                ? Gravity.START :  Gravity.CENTER;
        layoutParams.topMargin = mHasHeader ? mRowWithHeaderPadding : mRowPadding;
        mRow.setLayoutParams(layoutParams);

@@ -282,6 +324,7 @@ public class KeyguardSliceView extends LinearLayout {
        pw.println("  mTextColor: " + Integer.toHexString(mTextColor));
        pw.println("  mDarkAmount: " + mDarkAmount);
        pw.println("  mHasHeader: " + mHasHeader);
        pw.println("  mLockScreenMode: " + mLockScreenMode);
    }

    @Override
@@ -291,6 +334,8 @@ public class KeyguardSliceView extends LinearLayout {
    }

    public static class Row extends LinearLayout {
        private Set<KeyguardSliceTextView> mKeyguardSliceTextViewSet = new HashSet();
        private int mLockScreenModeRow = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;

        /**
         * This view is visible in AOD, which means that the device will sleep if we
@@ -361,12 +406,18 @@ public class KeyguardSliceView extends LinearLayout {
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int width = MeasureSpec.getSize(widthMeasureSpec);
            int childCount = getChildCount();

            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                if (child instanceof KeyguardSliceTextView) {
                    if (mLockScreenModeRow == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
                        ((KeyguardSliceTextView) child).setMaxWidth(Integer.MAX_VALUE);
                    } else {
                        ((KeyguardSliceTextView) child).setMaxWidth(width / 3);
                    }
                }
            }

            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }

@@ -384,6 +435,42 @@ public class KeyguardSliceView extends LinearLayout {
        public boolean hasOverlappingRendering() {
            return false;
        }

        @Override
        public void addView(View view, int index) {
            super.addView(view, index);

            if (view instanceof KeyguardSliceTextView) {
                ((KeyguardSliceTextView) view).setLockScreenMode(mLockScreenModeRow);
                mKeyguardSliceTextViewSet.add((KeyguardSliceTextView) view);
            }
        }

        @Override
        public void removeView(View view) {
            super.removeView(view);
            if (view instanceof KeyguardSliceTextView) {
                mKeyguardSliceTextViewSet.remove((KeyguardSliceTextView) view);
            }
        }

        /**
         * Updates the lockscreen mode which may change the layout of this view.
         */
        public void setLockscreenMode(int mode) {
            mLockScreenModeRow = mode;
            if (mLockScreenModeRow == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
                setOrientation(LinearLayout.VERTICAL);
                setGravity(Gravity.START);
            } else {
                setOrientation(LinearLayout.HORIZONTAL);
                setGravity(Gravity.CENTER);
            }

            for (KeyguardSliceTextView textView : mKeyguardSliceTextViewSet) {
                textView.setLockScreenMode(mLockScreenModeRow);
            }
        }
    }

    /**
@@ -392,6 +479,7 @@ public class KeyguardSliceView extends LinearLayout {
    @VisibleForTesting
    static class KeyguardSliceTextView extends TextView implements
            ConfigurationController.ConfigurationListener {
        private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;

        @StyleRes
        private static int sStyleId = R.style.TextAppearance_Keyguard_Secondary;
@@ -432,9 +520,16 @@ public class KeyguardSliceView extends LinearLayout {

        private void updatePadding() {
            boolean hasText = !TextUtils.isEmpty(getText());
            int horizontalPadding = (int) getContext().getResources()
            int padding = (int) getContext().getResources()
                    .getDimension(R.dimen.widget_horizontal_padding) / 2;
            setPadding(horizontalPadding, 0, horizontalPadding * (hasText ? 1 : -1), 0);
            if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
                // orientation is vertical, so add padding to top & bottom
                setPadding(0, padding, 0, padding * (hasText ? 1 : -1));
            } else {
                // oreintation is horizontal, so add padding to left & right
                setPadding(padding, 0, padding * (hasText ? 1 : -1), 0);
            }

            setCompoundDrawablePadding((int) mContext.getResources()
                    .getDimension(R.dimen.widget_icon_padding));
        }
@@ -461,5 +556,18 @@ public class KeyguardSliceView extends LinearLayout {
                }
            }
        }

        /**
         * Updates the lockscreen mode which may change the layout of this view.
         */
        public void setLockScreenMode(int mode) {
            mLockScreenMode = mode;
            if (mLockScreenMode == KeyguardUpdateMonitor.LOCK_SCREEN_MODE_LAYOUT_1) {
                setGravity(Gravity.START);
            } else {
                setGravity(Gravity.CENTER);
            }
            updatePadding();
        }
    }
}
+47 −47
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.android.systemui.keyguard.KeyguardSliceProvider;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.ViewController;

import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -55,10 +56,10 @@ import javax.inject.Inject;

/** Controller for a {@link KeyguardSliceView}. */
@KeyguardStatusViewScope
public class KeyguardSliceViewController implements Dumpable {
public class KeyguardSliceViewController extends ViewController<KeyguardSliceView> implements
        Dumpable {
    private static final String TAG = "KeyguardSliceViewCtrl";

    private final KeyguardSliceView mView;
    private final ActivityStarter mActivityStarter;
    private final ConfigurationController mConfigurationController;
    private final TunerService mTunerService;
@@ -68,41 +69,7 @@ public class KeyguardSliceViewController implements Dumpable {
    private Uri mKeyguardSliceUri;
    private Slice mSlice;
    private Map<View, PendingIntent> mClickActions;

    private final View.OnAttachStateChangeListener mOnAttachStateChangeListener =
            new View.OnAttachStateChangeListener() {

                @Override
                public void onViewAttachedToWindow(View v) {

                    Display display = mView.getDisplay();
                    if (display != null) {
                        mDisplayId = display.getDisplayId();
                    }
                    mTunerService.addTunable(mTunable, Settings.Secure.KEYGUARD_SLICE_URI);
                    // Make sure we always have the most current slice
                    if (mDisplayId == DEFAULT_DISPLAY && mLiveData != null) {
                        mLiveData.observeForever(mObserver);
                    }
                    mConfigurationController.addCallback(mConfigurationListener);
                    mDumpManager.registerDumpable(
                            TAG + "@" + Integer.toHexString(
                                    KeyguardSliceViewController.this.hashCode()),
                            KeyguardSliceViewController.this);
                }

                @Override
                public void onViewDetachedFromWindow(View v) {

                    // TODO(b/117344873) Remove below work around after this issue be fixed.
                    if (mDisplayId == DEFAULT_DISPLAY) {
                        mLiveData.removeObserver(mObserver);
                    }
                    mTunerService.removeTunable(mTunable);
                    mConfigurationController.removeCallback(mConfigurationListener);
                    mDumpManager.unregisterDumpable(TAG);
                }
            };
    private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;

    TunerService.Tunable mTunable = (key, newValue) -> setupUri(newValue);

@@ -133,24 +100,57 @@ public class KeyguardSliceViewController implements Dumpable {
    };

    @Inject
    public KeyguardSliceViewController(KeyguardSliceView keyguardSliceView,
    public KeyguardSliceViewController(
            KeyguardSliceView keyguardSliceView,
            ActivityStarter activityStarter,
            ConfigurationController configurationController, TunerService tunerService,
            ConfigurationController configurationController,
            TunerService tunerService,
            DumpManager dumpManager) {
        mView = keyguardSliceView;
        super(keyguardSliceView);
        mActivityStarter = activityStarter;
        mConfigurationController = configurationController;
        mTunerService = tunerService;
        mDumpManager = dumpManager;
    }

    /** Initialize the controller. */
    public void init() {
        if (mView.isAttachedToWindow()) {
            mOnAttachStateChangeListener.onViewAttachedToWindow(mView);
    @Override
    protected void onViewAttached() {
        Display display = mView.getDisplay();
        if (display != null) {
            mDisplayId = display.getDisplayId();
        }
        mView.addOnAttachStateChangeListener(mOnAttachStateChangeListener);
        mView.setOnClickListener(mOnClickListener);
        mTunerService.addTunable(mTunable, Settings.Secure.KEYGUARD_SLICE_URI);
        // Make sure we always have the most current slice
        if (mDisplayId == DEFAULT_DISPLAY && mLiveData != null) {
            mLiveData.observeForever(mObserver);
        }
        mConfigurationController.addCallback(mConfigurationListener);
        mDumpManager.registerDumpable(
                TAG + "@" + Integer.toHexString(
                        KeyguardSliceViewController.this.hashCode()),
                KeyguardSliceViewController.this);
        mView.updateLockScreenMode(mLockScreenMode);
    }

    @Override
    protected void onViewDetached() {
        // TODO(b/117344873) Remove below work around after this issue be fixed.
        if (mDisplayId == DEFAULT_DISPLAY) {
            mLiveData.removeObserver(mObserver);
        }
        mTunerService.removeTunable(mTunable);
        mConfigurationController.removeCallback(mConfigurationListener);
        mDumpManager.unregisterDumpable(
                TAG + "@" + Integer.toHexString(
                        KeyguardSliceViewController.this.hashCode()));
    }

    /**
     * Updates the lockscreen mode which may change the layout of the keyguard slice view.
     */
    public void updateLockScreenMode(int mode) {
        mLockScreenMode = mode;
        mView.updateLockScreenMode(mLockScreenMode);
    }

    /**
@@ -224,10 +224,10 @@ public class KeyguardSliceViewController implements Dumpable {
        Trace.endSection();
    }


    @Override
    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
        pw.println("  mSlice: " + mSlice);
        pw.println("  mClickActions: " + mClickActions);
        pw.println("  mLockScreenMode: " + mLockScreenMode);
    }
}
Loading