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

Commit 92934201 authored by Dave Kessler's avatar Dave Kessler Committed by Steve Kondik
Browse files

Status Bar Clock: rewrite for lollipop and add left clock (1/2)

We only get one instance of clock now instead of one per location.
Also, add in left side clock.

[mikeioannina]: Adapt for CyanogenMod

Change-Id: Idbf22eb19b9a2addf8bfb570d9e9cbd7d90c9650
parent 9f1be623
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -3212,6 +3212,28 @@ public final class Settings {
         */
        public static final String EGG_MODE = "egg_mode";

        /**
         * Whether to hide the clock, show it in the right or left
         * position or show it in the center
         * 0: don't show the clock
         * 1: show the clock in the right position (LTR)
         * 2: show the clock in the center
         * 3: show the clock in the left position (LTR)
         * default: 1
         * @hide
         */
        public static final String STATUS_BAR_CLOCK = "status_bar_clock";

        /**
         * Display style of AM/PM next to clock in status bar
         * 0: Normal display (Eclair stock)
         * 1: Small display (Froyo stock)
         * 2: No display (Gingerbread/ICS stock)
         * default: 2
         * @hide
         */
        public static final String STATUS_BAR_AM_PM = "status_bar_am_pm";

        /**
         * Display style of the status bar battery information
         * 0: Display the battery an icon in portrait mode
+32 −1
Original line number Diff line number Diff line
@@ -62,6 +62,18 @@
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                >

                <TextView
                    android:id="@+id/left_clock"
                    android:textAppearance="@style/TextAppearance.StatusBar.Clock"
                    android:layout_width="wrap_content"
                    android:layout_height="fill_parent"
                    android:singleLine="true"
                    android:paddingEnd="6dip"
                    android:gravity="center"
                    android:visibility="gone"
                    />

                <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon"
                    android:layout_width="@dimen/status_bar_icon_size"
                    android:layout_height="match_parent"
@@ -93,7 +105,7 @@
                android:textColor="#ffffff"
                android:textSize="@dimen/battery_level_text_size" />

            <com.android.systemui.statusbar.policy.Clock
            <TextView
                android:id="@+id/clock"
                android:textAppearance="@style/TextAppearance.StatusBar.Clock"
                android:layout_width="wrap_content"
@@ -105,6 +117,25 @@
        </com.android.keyguard.AlphaOptimizedLinearLayout>
    </LinearLayout>

    <com.android.keyguard.AlphaOptimizedLinearLayout
        android:id="@+id/center_clock_layout"
        android:gravity="center"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <TextView
            android:id="@+id/center_clock"
            android:textAppearance="@style/TextAppearance.StatusBar.Clock"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:singleLine="true"
            android:gravity="center"
            android:visibility="gone"
            />
    </com.android.keyguard.AlphaOptimizedLinearLayout>

    <ViewStub
        android:id="@+id/ticker_stub"
        android:inflatedId="@+id/ticker"
+18 −1
Original line number Diff line number Diff line
@@ -22,12 +22,14 @@ import android.view.View;
import android.widget.LinearLayout;

import com.android.systemui.R;
import com.android.systemui.statusbar.policy.Clock;

public class IconMerger extends LinearLayout {
    private static final String TAG = "IconMerger";
    private static final boolean DEBUG = false;

    private int mIconSize;
    private int mClockLocation;
    private View mMoreView;

    public IconMerger(Context context, AttributeSet attrs) {
@@ -50,6 +52,10 @@ public class IconMerger extends LinearLayout {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // we need to constrain this to an integral multiple of our children
        int width = getMeasuredWidth();
        if (mClockLocation == Clock.STYLE_CLOCK_CENTER) {
            int totalWidth = mContext.getResources().getDisplayMetrics().widthPixels;
            width = totalWidth / 2 - mIconSize * 2;
        }
        setMeasuredDimension(width - (width % mIconSize), getMeasuredHeight());
    }

@@ -69,7 +75,14 @@ public class IconMerger extends LinearLayout {
        }
        final boolean overflowShown = (mMoreView.getVisibility() == View.VISIBLE);
        // let's assume we have one more slot if the more icon is already showing
        if (overflowShown) visibleChildren --;
        if (overflowShown) {
            int totalWidth = mContext.getResources().getDisplayMetrics().widthPixels;
            if ((mClockLocation != Clock.STYLE_CLOCK_CENTER &&
                    mClockLocation != Clock.STYLE_CLOCK_LEFT) ||
                    (visibleChildren > (totalWidth / mIconSize / 2 + 1))) {
                visibleChildren--;
            }
        }
        final boolean moreRequired = visibleChildren * mIconSize > width;
        if (moreRequired != overflowShown) {
            post(new Runnable() {
@@ -80,4 +93,8 @@ public class IconMerger extends LinearLayout {
            });
        }
    }

    public void setClockAndDateStatus(int mode) {
        mClockLocation = mode;
    }
}
+74 −12
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChang
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
import com.android.systemui.statusbar.policy.BrightnessMirrorController;
import com.android.systemui.statusbar.policy.CastControllerImpl;
import com.android.systemui.statusbar.policy.Clock;
import com.android.systemui.statusbar.policy.FlashlightController;
import com.android.systemui.statusbar.policy.HeadsUpNotificationView;
import com.android.systemui.statusbar.policy.HotspotControllerImpl;
@@ -321,6 +322,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,

    // [+>
    View mMoreIcon;
    TextView mClockView;
    Clock mClockController;
    private int mClockLocation;

    // expanded notifications
    NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -441,6 +445,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
                    Settings.System.STATUS_BAR_BRIGHTNESS_CONTROL), false, this);
            resolver.registerContentObserver(Settings.System.getUriFor(
                    Settings.System.SCREEN_BRIGHTNESS_MODE), false, this);
            resolver.registerContentObserver(Settings.System.getUriFor(
                    Settings.System.STATUS_BAR_CLOCK), false, this);
            update();
        }

@@ -459,6 +465,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            mBrightnessControl = Settings.System.getInt(
                    resolver, Settings.System.STATUS_BAR_BRIGHTNESS_CONTROL, 0) == 1;

            mClockLocation = Settings.System.getInt(
                    resolver, Settings.System.STATUS_BAR_CLOCK, Clock.STYLE_CLOCK_RIGHT);
            updateClockView();

            if (mNavigationBarView != null) {
                boolean navLeftInLandscape = Settings.System.getInt(resolver,
                        Settings.System.NAVBAR_LEFT_IN_LANDSCAPE, 0) == 1;
@@ -467,6 +477,39 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        }
    }

    void updateClockView() {
        mClockView.setVisibility(View.GONE);

        switch (mClockLocation) {
            default:
            case Clock.STYLE_HIDE_CLOCK:
                mClockView = (TextView) mStatusBarView.findViewById(R.id.clock);
                // Don't set visibility here...
                break;
            case Clock.STYLE_CLOCK_RIGHT:
                mClockView = (TextView) mStatusBarView.findViewById(R.id.clock);
                mClockView.setVisibility(View.VISIBLE);
                break;
            case Clock.STYLE_CLOCK_CENTER:
                mClockView = (TextView) mStatusBarView.findViewById(R.id.center_clock);
                mClockView.setVisibility(View.VISIBLE);
                break;
            case Clock.STYLE_CLOCK_LEFT:
                mClockView = (TextView) mStatusBarView.findViewById(R.id.left_clock);
                mClockView.setVisibility(View.VISIBLE);
                break;
        }

        setClockAndDateStatus();
        mClockController.updateClockView(mClockView);
    }

    public void setClockAndDateStatus() {
        if (mNotificationIcons != null) {
            mNotificationIcons.setClockAndDateStatus(mClockLocation);
        }
    }

    class DevForceNavbarObserver extends ContentObserver {
        DevForceNavbarObserver(Handler handler) {
            super(handler);
@@ -905,6 +948,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        mNotificationIcons.setOverflowIndicator(mMoreIcon);
        mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);

        mClockView = (TextView) mStatusBarView.findViewById(R.id.clock);
        mClockLocation = Settings.System.getInt(mContext.getContentResolver(),
                Settings.System.STATUS_BAR_CLOCK, Clock.STYLE_CLOCK_RIGHT);
        if (mClockController == null) mClockController = new Clock(mContext, mClockView);
        updateClockView();

        mStackScroller = (NotificationStackScrollLayout) mStatusBarWindowContent.findViewById(
                R.id.notification_stack_scroller);
        mStackScroller.setLongPressListener(getNotificationLongClicker());
@@ -2031,6 +2080,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        updateCarrierLabelVisibility(false);
    }

    public void showClock(boolean show) {
        mClockView.setVisibility(show ? View.VISIBLE : View.GONE);
    }

    public void findAndUpdateMediaNotifications() {
        boolean metaDataChanged = false;

@@ -2284,14 +2337,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
        }
    }

    public void showClock(boolean show) {
        if (mStatusBarView == null) return;
        View clock = mStatusBarView.findViewById(R.id.clock);
        if (clock != null) {
            clock.setVisibility(show ? View.VISIBLE : View.GONE);
        }
    }

    private int adjustDisableFlags(int state) {
        if (!mLaunchTransitionFadingAway
                && (mExpandedVisible || mBouncerShowing || mWaitingForKeyguardExit)) {
@@ -2341,9 +2386,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,

        if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
            mSystemIconArea.animate().cancel();
            mClockView.animate().cancel();
            if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
                if (mClockLocation == Clock.STYLE_CLOCK_CENTER
                        || mClockLocation == Clock.STYLE_CLOCK_LEFT) {
                    animateStatusBarHide(mClockView, animate);
                }
                animateStatusBarHide(mSystemIconArea, animate);
            } else {
                if (mClockLocation == Clock.STYLE_CLOCK_CENTER
                        || mClockLocation == Clock.STYLE_CLOCK_LEFT) {
                    animateStatusBarShow(mClockView, animate);
                }
                animateStatusBarShow(mSystemIconArea, animate);
            }
        }
@@ -3239,19 +3293,25 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
            if (!mTickerEnabled) return;
            mTicking = true;
            mStatusBarContents.setVisibility(View.GONE);
            mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out,
                    null));
            mTickerView.setVisibility(View.VISIBLE);
            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
            mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
            mClockView.setVisibility(View.GONE);
            mClockView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
        }

        @Override
        public void tickerDone() {
            if (!mTickerEnabled) return;
            mStatusBarContents.setVisibility(View.VISIBLE);
            mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in,
                    null));
            mTickerView.setVisibility(View.GONE);
            mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
                    mTickingDoneListener));
            mClockView.setVisibility(View.VISIBLE);
            mClockView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
        }

        public void tickerHalting() {
@@ -3260,13 +3320,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
                mStatusBarContents.setVisibility(View.VISIBLE);
                mStatusBarContents
                        .startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
                mClockView.setVisibility(View.VISIBLE);
                mClockView.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
            }
            mTickerView.setVisibility(View.GONE);
            // we do not animate the ticker away at this point, just get rid of it (b/6992707)
        }
    }

    Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {;
    Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {
        public void onAnimationEnd(Animation animation) {
            mTicking = false;
        }
+112 −52
Original line number Diff line number Diff line
@@ -18,18 +18,20 @@ package com.android.systemui.statusbar.policy;

import android.app.ActivityManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.database.ContentObserver;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
import android.text.style.CharacterStyle;
import android.text.style.RelativeSizeSpan;
import android.util.AttributeSet;
import android.widget.TextView;

import com.android.systemui.DemoMode;
@@ -45,43 +47,57 @@ import libcore.icu.LocaleData;
/**
 * Digital clock for the status bar.
 */
public class Clock extends TextView implements DemoMode {
    private boolean mAttached;
    private Calendar mCalendar;
    private String mClockFormatString;
    private SimpleDateFormat mClockFormat;
    private Locale mLocale;
public class Clock implements DemoMode {

    private static final int AM_PM_STYLE_NORMAL  = 0;
    private static final int AM_PM_STYLE_SMALL   = 1;
    private static final int AM_PM_STYLE_GONE    = 2;

    private final int mAmPmStyle;
    public static final int STYLE_HIDE_CLOCK    = 0;
    public static final int STYLE_CLOCK_RIGHT   = 1;
    public static final int STYLE_CLOCK_CENTER  = 2;
    public static final int STYLE_CLOCK_LEFT    = 3;

    public Clock(Context context) {
        this(context, null);
    }
    private static final char MAGIC1 = '\uEF00';
    private static final char MAGIC2 = '\uEF01';

    Context mContext;
    private TextView mClockView;
    private Calendar mCalendar;
    private Locale mLocale;
    private String mClockFormatString;
    private SimpleDateFormat mClockFormat;
    private SettingsObserver settingsObserver;

    private int mAmPmStyle = AM_PM_STYLE_GONE;
    private boolean mDemoMode;
    private boolean mAttached;

    public Clock(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    class SettingsObserver extends ContentObserver {
        SettingsObserver(Handler handler) {
            super(handler);
        }

    public Clock(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        TypedArray a = context.getTheme().obtainStyledAttributes(
                attrs,
                R.styleable.Clock,
                0, 0);
        try {
            mAmPmStyle = a.getInt(R.styleable.Clock_amPmStyle, AM_PM_STYLE_GONE);
        } finally {
            a.recycle();
        void observe() {
            ContentResolver resolver = mContext.getContentResolver();
            resolver.registerContentObserver(Settings.System.getUriFor(
                    Settings.System.STATUS_BAR_AM_PM), false, this);
            updateSettings();
        }

        void unobserve() {
            mContext.getContentResolver().unregisterContentObserver(this);
        }

        @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        public void onChange(boolean selfChange) {
            updateSettings();
        }
    }

    public Clock(Context context, TextView v) {
        mContext = context;
        mClockView = v;

        if (!mAttached) {
            mAttached = true;
@@ -93,8 +109,8 @@ public class Clock extends TextView implements DemoMode {
            filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
            filter.addAction(Intent.ACTION_USER_SWITCHED);

            getContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter,
                    null, getHandler());
            mContext().registerReceiverAsUser(mIntentReceiver, UserHandle.ALL, filter,
                    null, new Handler());
        }

        // NOTE: It's safe to do these after registering the receiver since the receiver always runs
@@ -104,16 +120,12 @@ public class Clock extends TextView implements DemoMode {
        mCalendar = Calendar.getInstance(TimeZone.getDefault());

        // Make sure we update to the current time
        if (settingsObserver == null) {
            settingsObserver = new SettingsObserver(new Handler());
            settingsObserver.observe();
        } else {
            updateClock();
        }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (mAttached) {
            getContext().unregisterReceiver(mIntentReceiver);
            mAttached = false;
        }
    }

    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -127,7 +139,7 @@ public class Clock extends TextView implements DemoMode {
                    mClockFormat.setTimeZone(mCalendar.getTimeZone());
                }
            } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
                final Locale newLocale = getResources().getConfiguration().locale;
                final Locale newLocale = mContext.getResources().getConfiguration().locale;
                if (! newLocale.equals(mLocale)) {
                    mLocale = newLocale;
                    mClockFormatString = ""; // force refresh
@@ -137,16 +149,9 @@ public class Clock extends TextView implements DemoMode {
        }
    };

    final void updateClock() {
        if (mDemoMode) return;
        mCalendar.setTimeInMillis(System.currentTimeMillis());
        setText(getSmallTime());
    }

    private final CharSequence getSmallTime() {
        Context context = getContext();
        boolean is24 = DateFormat.is24HourFormat(context, ActivityManager.getCurrentUser());
        LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale);
        boolean is24 = DateFormat.is24HourFormat(mContext, ActivityManager.getCurrentUser());
        LocaleData d = LocaleData.get(mContext.getResources().getConfiguration().locale);

        final char MAGIC1 = '\uEF00';
        final char MAGIC2 = '\uEF01';
@@ -212,10 +217,66 @@ public class Clock extends TextView implements DemoMode {
        }

        return result;
    }

    SimpleDateFormat updateFormatString(String format) {
        SimpleDateFormat sdf = mClockFormat;

        if (!format.equals(mClockFormatString)) {

            if (mAmPmStyle != AM_PM_STYLE_NORMAL) {
                int a = -1;
                boolean quoted = false;
                for (int i = 0; i < format.length(); i++) {
                    char c = format.charAt(i);

                    if (c == '\'') {
                        quoted = !quoted;
                    }
                    if (!quoted && c == 'a') {
                        a = i;
                        break;
                    }
                }

    private boolean mDemoMode;
                if (a >= 0) {
                    // Move a back so any whitespace before AM/PM is also in the alternate size.
                    final int b = a;
                    while (a > 0 && Character.isWhitespace(format.charAt(a-1))) {
                        a--;
                    }
                    format = format.substring(0, a) + MAGIC1 + format.substring(a, b)
                        + "a" + MAGIC2 + format.substring(b + 1);
                }
            }
            mClockFormat = sdf = new SimpleDateFormat(format);
            mClockFormatString = format;
        } else {
            sdf = mClockFormat;
        }
        return sdf;

    }

    void updateClock() {
        if (mDemoMode || mCalendar == null) return;
        mCalendar.setTimeInMillis(System.currentTimeMillis());
        mClockView.setText(getSmallTime());
    }

    public void updateClockView(TextView v) {
        mClockView = v;
        updateSettings();
    }

    void updateSettings() {
        ContentResolver resolver = mContext.getContentResolver();
        mAmPmStyle = (Settings.System.getInt(resolver,
                Settings.System.STATUS_BAR_AM_PM, 2));
        mClockFormatString = "";

        updateClock();
    }

    @Override
    public void dispatchDemoCommand(String command, Bundle args) {
@@ -235,8 +296,7 @@ public class Clock extends TextView implements DemoMode {
                mCalendar.set(Calendar.HOUR, hh);
                mCalendar.set(Calendar.MINUTE, mm);
            }
            setText(getSmallTime());
            mClockView.setText(getSmallTime());
        }
    }
}