Quick prototype of new header
- Has first 4 quick tiles shown in collapsed mode
- Shows date + settings gear in expanded mode
- Still has a few gaps (alarms probably don't work)
- Fix issue with placement of cell data type indicator
Change-Id: I629798b96f4f088fde47c7b67feea304dcc8450c
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
new file mode 100644
index 0000000..d778c98
--- /dev/null
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 2015, 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.
+-->
+
+<!-- Extends RelativeLayout -->
+<com.android.systemui.statusbar.phone.QuickStatusBarHeader
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/header"
+ android:layout_width="@dimen/notification_panel_width"
+ android:layout_height="@dimen/status_bar_header_height"
+ android:layout_gravity="@integer/notification_panel_layout_gravity"
+ android:baselineAligned="false"
+ android:elevation="4dp"
+ android:background="@drawable/notification_header_bg"
+ android:clickable="true"
+ android:focusable="true"
+ >
+
+ <LinearLayout
+ android:id="@+id/expanded_group"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingEnd="12dp"
+ android:orientation="horizontal">
+
+ <com.android.systemui.statusbar.AlphaOptimizedButton android:id="@+id/alarm_status"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
+ android:drawablePadding="6dp"
+ android:drawableStart="@drawable/ic_access_alarms_small"
+ android:textColor="#64ffffff"
+ android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
+ android:paddingEnd="6dp"
+ android:paddingStart="6dp"
+ android:paddingTop="16dp"
+ android:paddingBottom="16dp"
+ android:background="?android:attr/selectableItemBackground"
+ android:visibility="gone"
+ />
+
+ <com.android.systemui.statusbar.policy.DateView android:id="@+id/date"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="16dp"
+ android:singleLine="true"
+ android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Date"
+ android:layout_below="@id/clock"
+ systemui:datePattern="EEE"
+ android:gravity="center_vertical"
+ android:textSize="20sp"
+ android:paddingTop="16dp"
+ android:layout_marginBottom="@dimen/clock_collapsed_bottom_margin" />
+
+ <include layout="@layout/split_clock_view"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginStart="16dp"
+ android:layout_marginTop="16dp"
+ android:id="@+id/clock"
+ />
+
+ <Space
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+
+ <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
+ android:id="@+id/settings_button_container"
+ android:layout_width="48dp"
+ android:layout_height="@dimen/status_bar_header_height"
+ android:clipChildren="false"
+ android:clipToPadding="false">
+
+ <com.android.systemui.statusbar.phone.SettingsButton android:id="@+id/settings_button"
+ style="@android:style/Widget.Material.Button.Borderless"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/ripple_drawable"
+ android:src="@drawable/ic_settings"
+ android:contentDescription="@string/accessibility_desc_settings" />
+ <com.android.systemui.statusbar.AlphaOptimizedImageView android:id="@+id/tuner_icon"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:paddingStart="36dp"
+ android:tint="#4DFFFFFF"
+ android:tintMode="src_in"
+ android:visibility="invisible"
+ android:src="@drawable/tuner" />
+
+ </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
+ </LinearLayout>
+
+ <include
+ android:id="@+id/qs_detail_header"
+ layout="@layout/qs_detail_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ />
+
+ <com.android.systemui.qs.QuickQSPanel
+ android:id="@+id/quick_qs_panel"
+ android:background="#0000"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/qs_detail_header_progress"
+ android:src="@drawable/indeterminate_anim"
+ android:alpha="0"
+ android:background="@color/qs_detail_progress_track"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_alignParentBottom="true"
+ systemui:hasOverlappingRendering="false"
+ />
+
+ <TextView
+ android:id="@+id/header_debug_info"
+ android:visibility="invisible"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:fontFamily="sans-serif-condensed"
+ android:textSize="11dp"
+ android:textStyle="bold"
+ android:textColor="#00A040"
+ android:padding="2dp"
+ />
+
+</com.android.systemui.statusbar.phone.QuickStatusBarHeader>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index f7bbce0..a64dbbd 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -98,7 +98,12 @@
layout="@layout/keyguard_bottom_area"
android:visibility="gone" />
- <include layout="@layout/status_bar_expanded_header" />
+ <ViewStub
+ android:id="@+id/status_bar_header"
+ android:layout_width="@dimen/notification_panel_width"
+ android:layout_height="@dimen/status_bar_header_height"
+ android:layout_marginStart="@dimen/notification_side_padding"
+ android:layout_marginEnd="@dimen/notification_side_padding" />
<com.android.systemui.statusbar.AlphaOptimizedView
android:id="@+id/qs_navbar_scrim"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 5eca471..dd75dbf 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -23,8 +23,6 @@
android:layout_width="@dimen/notification_panel_width"
android:layout_height="@dimen/status_bar_header_height"
android:layout_gravity="@integer/notification_panel_layout_gravity"
- android:paddingStart="@dimen/notification_side_padding"
- android:paddingEnd="@dimen/notification_side_padding"
android:baselineAligned="false"
android:elevation="4dp"
android:background="@drawable/notification_header_bg"
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index abfd863..5661657 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -556,4 +556,7 @@
<dimen name="fab_margin">16dp</dimen>
<dimen name="fab_elevation">12dp</dimen>
<dimen name="fab_press_translation_z">9dp</dimen>
+
+ <!-- TODO: Remove this -->
+ <dimen name="qs_header_neg_padding">-8dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d567e97..a525fbb 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1156,7 +1156,7 @@
<!-- Option to show brightness bar in quick settings [CHAR LIMIT=60] -->
<string name="show_brightness">Show brightness in Quick Settings</string>
<!-- Option to use new paging layout in quick settings [CHAR LIMIT=60] -->
- <string name="qs_paging">Use paging in Quick Settings</string>
+ <string name="qs_paging" translatable="false">Use the new Quick Settings</string>
<!-- Category in the System UI Tuner settings, where new/experimental
settings are -->
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index 07e7688d..5980108 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -37,10 +37,6 @@
android:key="qs_paged_panel"
android:title="@string/qs_paging" />
- <com.android.systemui.tuner.TunerSwitch
- android:key="qs_allow_customize"
- android:title="@string/qs_customize" />
-
</PreferenceCategory>
</PreferenceScreen>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 18af35e..c6bcfc4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -34,7 +34,6 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
-
import com.android.internal.logging.MetricsLogger;
import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
@@ -54,8 +53,7 @@
public class QSPanel extends FrameLayout implements Tunable {
public static final String QS_SHOW_BRIGHTNESS = "qs_show_brightness";
- public static final String QS_PAGED_PANEL = "qs_paged_panel";
- public static final String QS_ALLOW_CUSTOMIZE = "qs_allow_customize";
+ public static final String QS_THE_NEW_QS = "qs_paged_panel";
protected final Context mContext;
protected final ArrayList<TileRecord> mRecords = new ArrayList<TileRecord>();
@@ -135,8 +133,7 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- TunerService.get(mContext).addTunable(this,
- QS_SHOW_BRIGHTNESS, QS_PAGED_PANEL, QS_ALLOW_CUSTOMIZE);
+ TunerService.get(mContext).addTunable(this, QS_SHOW_BRIGHTNESS, QS_THE_NEW_QS);
}
@Override
@@ -150,14 +147,15 @@
if (QS_SHOW_BRIGHTNESS.equals(key)) {
mBrightnessView.setVisibility(newValue == null || Integer.parseInt(newValue) != 0
? VISIBLE : GONE);
- } else if (QS_PAGED_PANEL.equals(key)) {
+ } else if (QS_THE_NEW_QS.equals(key)) {
+ boolean theNewQs = newValue != null && Integer.parseInt(newValue) != 0;
if (mTileLayout != null) {
for (int i = 0; i < mRecords.size(); i++) {
mTileLayout.removeTile(mRecords.get(i));
}
mQsContainer.removeView((View) mTileLayout);
}
- int layout = newValue != null && Integer.parseInt(newValue) != 0
+ int layout = theNewQs
? R.layout.qs_paged_tile_layout : R.layout.qs_tile_layout;
mTileLayout =
(QSTileLayout) LayoutInflater.from(mContext).inflate(layout, mQsContainer, false);
@@ -165,8 +163,7 @@
for (int i = 0; i < mRecords.size(); i++) {
mTileLayout.addTile(mRecords.get(i));
}
- } else if (QS_ALLOW_CUSTOMIZE.equals(key)) {
- if (newValue != null && Integer.parseInt(newValue) != 0) {
+ if (theNewQs) {
mCustomizePanel = (QSCustomizer) LayoutInflater.from(mContext)
.inflate(R.layout.qs_customize_panel, null);
mCustomizePanel.setHost(mHost);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index e575923..d914beb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -267,7 +267,7 @@
final int w = MeasureSpec.getSize(widthMeasureSpec);
final int h = MeasureSpec.getSize(heightMeasureSpec);
final int iconSpec = exactly(mIconSizePx);
- mIcon.measure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY), iconSpec);
+ mIcon.measure(MeasureSpec.makeMeasureSpec(w, getIconMeasureMode()), iconSpec);
switch (mType) {
case QS_TYPE_QUICK:
mCircle.measure(
@@ -287,6 +287,10 @@
setMeasuredDimension(w, h);
}
+ protected int getIconMeasureMode() {
+ return MeasureSpec.EXACTLY;
+ }
+
private static int exactly(int size) {
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
new file mode 100644
index 0000000..53d0402
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2015 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.qs;
+
+import android.content.Context;
+import android.content.res.ColorStateList;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import com.android.systemui.R;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Version of QSPanel that only shows 4 Quick Tiles in the QS Header.
+ */
+public class QuickQSPanel extends QSPanel {
+
+ public QuickQSPanel(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ if (mTileLayout != null) {
+ for (int i = 0; i < mRecords.size(); i++) {
+ mTileLayout.removeTile(mRecords.get(i));
+ }
+ mQsContainer.removeView((View) mTileLayout);
+ }
+ mTileLayout = new HeaderTileLayout(context);
+ mQsContainer.addView((View) mTileLayout, 1 /* Between brightness and footer */);
+ }
+
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ // No tunings for you.
+ if (key.equals(QS_SHOW_BRIGHTNESS)) {
+ // No Brightness for you.
+ super.onTuningChanged(key, "0");
+ }
+ }
+
+ @Override
+ public void setTiles(Collection<QSTile<?>> tiles) {
+ ArrayList<QSTile<?>> quickTiles = new ArrayList<>();
+ for (QSTile<?> tile : tiles) {
+ if (tile.getTileType() == QSTileView.QS_TYPE_QUICK) {
+ quickTiles.add(tile);
+ }
+ if (quickTiles.size() == 4) {
+ break;
+ }
+ }
+ super.setTiles(quickTiles);
+ }
+
+ private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {
+
+ public HeaderTileLayout(Context context) {
+ super(context);
+ setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
+ int qsCompensation = (int)
+ context.getResources().getDimension(R.dimen.qs_header_neg_padding);
+ setPadding(0, qsCompensation, 0, 0);
+ ImageView downArrow = new ImageView(context);
+ downArrow.setImageResource(R.drawable.ic_expand_more);
+ downArrow.setImageTintList(ColorStateList.valueOf(context.getResources().getColor(
+ android.R.color.white, null)));
+ downArrow.setLayoutParams(generateLayoutParams());
+ downArrow.setPadding(0, -qsCompensation, 0, 0);
+ addView(downArrow);
+ setOrientation(LinearLayout.HORIZONTAL);
+ }
+
+ @Override
+ public void addTile(TileRecord tile) {
+ tile.tileView.setLayoutParams(generateLayoutParams());
+ // These shouldn't be normal tiles, but they will be for now so that the circles don't
+ // show up.
+ tile.tileView.setType(QSTileView.QS_TYPE_NORMAL);
+ addView(tile.tileView, getChildCount() - 1 /* Leave icon at end */);
+ }
+
+ private LayoutParams generateLayoutParams() {
+ LayoutParams lp = new LayoutParams(0, LayoutParams.MATCH_PARENT);
+ lp.weight = 1;
+ return lp;
+ }
+
+ @Override
+ public void removeTile(TileRecord tile) {
+ removeView(tile.tileView);
+ }
+
+ @Override
+ public void setTileVisibility(TileRecord tile, int visibility) {
+ tile.tileView.setVisibility(visibility);
+ }
+
+ @Override
+ public int getOffsetTop(TileRecord tile) {
+ return 0;
+ }
+
+ @Override
+ public void updateResources() {
+ // No resources here.
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
index 9ac7944..a2e1296 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/SignalTileView.java
@@ -83,6 +83,11 @@
layoutIndicator(mOut);
}
+ @Override
+ protected int getIconMeasureMode() {
+ return MeasureSpec.AT_MOST;
+ }
+
private void layoutIndicator(View indicator) {
boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL;
int left, right;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 3453652..79701ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -35,6 +35,7 @@
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
+import android.view.ViewStub;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.accessibility.AccessibilityEvent;
@@ -43,7 +44,6 @@
import android.view.animation.PathInterpolator;
import android.widget.FrameLayout;
import android.widget.TextView;
-
import com.android.internal.logging.MetricsLogger;
import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.DejankUtils;
@@ -64,6 +64,7 @@
import com.android.systemui.statusbar.policy.KeyguardUserSwitcher;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackStateAnimator;
+import com.android.systemui.tuner.TunerService;
import java.util.List;
@@ -71,7 +72,7 @@
ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,
View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener,
- HeadsUpManager.OnHeadsUpChangedListener {
+ HeadsUpManager.OnHeadsUpChangedListener, TunerService.Tunable {
private static final boolean DEBUG = false;
@@ -219,10 +220,13 @@
private final Interpolator mTouchResponseInterpolator =
new PathInterpolator(0.3f, 0f, 0.1f, 1f);
+ private boolean mNewQs;
+
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
setWillNotDraw(!DEBUG);
mFalsingManager = FalsingManager.getInstance(context);
+ TunerService.get(context).addTunable(this, QSPanel.QS_THE_NEW_QS);
}
public void setStatusBar(PhoneStatusBar bar) {
@@ -230,9 +234,27 @@
}
@Override
+ public void onTuningChanged(String key, String newValue) {
+ if (QSPanel.QS_THE_NEW_QS.equals(key)) {
+ boolean b = newValue != null && Integer.parseInt(newValue) != 0;
+ if (mNewQs != b) {
+ if (mHeader != null) {
+ // We are too late, no good way to re-initialize yet, just die and come back up.
+ android.os.Process.killProcess(android.os.Process.myPid());
+ } else {
+ mNewQs = b;
+ }
+ }
+ }
+ }
+
+ @Override
protected void onFinishInflate() {
super.onFinishInflate();
- mHeader = (BaseStatusBarHeader) findViewById(R.id.header);
+ ViewStub stub = (ViewStub) findViewById(R.id.status_bar_header);
+ stub.setLayoutResource(mNewQs
+ ? R.layout.quick_status_bar_expanded_header : R.layout.status_bar_expanded_header);
+ mHeader = (BaseStatusBarHeader) stub.inflate();
mHeader.setOnClickListener(this);
mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header);
mKeyguardStatusView = (KeyguardStatusView) findViewById(R.id.keyguard_status_view);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 05e8488..1c1a1d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -868,13 +868,15 @@
(SignalClusterView) mHeader.findViewById(R.id.signal_cluster);
mNetworkController.addSignalCallback(signalCluster);
mNetworkController.addSignalCallback(signalClusterKeyguard);
- mNetworkController.addSignalCallback(signalClusterQs);
signalCluster.setSecurityController(mSecurityController);
signalCluster.setNetworkController(mNetworkController);
signalClusterKeyguard.setSecurityController(mSecurityController);
signalClusterKeyguard.setNetworkController(mNetworkController);
- signalClusterQs.setSecurityController(mSecurityController);
- signalClusterQs.setNetworkController(mNetworkController);
+ if (signalClusterQs != null) {
+ mNetworkController.addSignalCallback(signalClusterQs);
+ signalClusterQs.setSecurityController(mSecurityController);
+ signalClusterQs.setNetworkController(mNetworkController);
+ }
final boolean isAPhone = mNetworkController.hasVoiceCallingFeature();
if (isAPhone) {
mNetworkController.addEmergencyListener(mHeader);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 6ec9494..6906a52 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -97,6 +97,10 @@
TunerService.get(mContext).addTunable(this, TILES_SETTING);
}
+ PhoneStatusBar getPhoneStatusBar() {
+ return mStatusBar;
+ }
+
public void destroy() {
TunerService.get(mContext).removeTunable(this);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
new file mode 100644
index 0000000..01f0667
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -0,0 +1,343 @@
+/*
+ * Copyright (C) 2015 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.phone;
+
+import android.app.AlarmManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.drawable.Animatable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.Switch;
+import android.widget.TextView;
+import android.widget.Toast;
+import com.android.systemui.R;
+import com.android.systemui.qs.QSPanel;
+import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.NextAlarmController;
+import com.android.systemui.statusbar.policy.UserInfoController;
+import com.android.systemui.tuner.TunerService;
+
+public class QuickStatusBarHeader extends BaseStatusBarHeader implements
+ NextAlarmController.NextAlarmChangeCallback, View.OnClickListener {
+
+ private ActivityStarter mActivityStarter;
+ private NextAlarmController mNextAlarmController;
+ private SettingsButton mSettingsButton;
+ private View mSettingsContainer;
+ private TextView mAlarmStatus;
+ private View mQsDetailHeader;
+
+ private ImageView mQsDetailHeaderProgress;
+ private QSPanel mQsPanel;
+ private Switch mQsDetailHeaderSwitch;
+
+ private boolean mExpanded;
+ private boolean mAlarmShowing;
+ private boolean mShowingDetail;
+
+ private boolean mDetailTransitioning;
+ private ViewGroup mExpandedGroup;
+ private TextView mQsDetailHeaderTitle;
+ private boolean mListening;
+ private AlarmManager.AlarmClockInfo mNextAlarm;
+
+ private QSPanel mHeaderQsPanel;
+
+ public QuickStatusBarHeader(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ mExpandedGroup = (ViewGroup) findViewById(R.id.expanded_group);
+
+ mHeaderQsPanel = (QSPanel) findViewById(R.id.quick_qs_panel);
+
+ mSettingsButton = (SettingsButton) findViewById(R.id.settings_button);
+ mSettingsContainer = findViewById(R.id.settings_button_container);
+ mSettingsButton.setOnClickListener(this);
+
+ mAlarmStatus = (TextView) findViewById(R.id.alarm_status);
+ mAlarmStatus.setOnClickListener(this);
+
+ mQsDetailHeader = findViewById(R.id.qs_detail_header);
+ mQsDetailHeader.setAlpha(0);
+ mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title);
+ mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle);
+ mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress);
+ }
+
+ @Override
+ public int getCollapsedHeight() {
+ return getHeight();
+ }
+
+ @Override
+ public int getExpandedHeight() {
+ return getHeight();
+ }
+
+ @Override
+ public void setExpanded(boolean expanded) {
+ mExpanded = expanded;
+ }
+
+ @Override
+ public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
+ mNextAlarm = nextAlarm;
+ if (nextAlarm != null) {
+ // TODO:...
+// mAlarmStatus.setText(KeyguardStatusView.formatNextAlarm(getContext(), nextAlarm));
+ }
+ mAlarmShowing = nextAlarm != null;
+ updateEverything();
+ }
+
+ @Override
+ public void setExpansion(float headerExpansionFraction) {
+ float offset = getHeight() * headerExpansionFraction;
+ mExpandedGroup.setTranslationY(offset - getHeight());
+ mHeaderQsPanel.setTranslationY(offset);
+ }
+
+ public void setListening(boolean listening) {
+ if (listening == mListening) {
+ return;
+ }
+ mHeaderQsPanel.setListening(listening);
+ mListening = listening;
+ updateListeners();
+ }
+
+ @Override
+ public void updateEverything() {
+ updateVisibilities();
+ }
+
+ private void updateVisibilities() {
+ mAlarmStatus.setVisibility(mExpanded && mAlarmShowing ? View.VISIBLE : View.GONE);
+ mQsDetailHeader.setVisibility(mExpanded && mShowingDetail ? View.VISIBLE : View.INVISIBLE);
+ mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
+ TunerService.isTunerEnabled(mContext) ? View.VISIBLE : View.INVISIBLE);
+ }
+
+ private void updateListeners() {
+ if (mListening) {
+ mNextAlarmController.addStateChangedCallback(this);
+ } else {
+ mNextAlarmController.removeStateChangedCallback(this);
+ }
+ }
+
+ @Override
+ public void setActivityStarter(ActivityStarter activityStarter) {
+ mActivityStarter = activityStarter;
+ }
+
+ @Override
+ public void setQSPanel(final QSPanel qsPanel) {
+ mQsPanel = qsPanel;
+ setupHost(qsPanel.getHost());
+ if (mQsPanel != null) {
+ mQsPanel.setCallback(mQsPanelCallback);
+ }
+ }
+
+ public void setupHost(QSTileHost host) {
+ final QSTileHost myHost = new QSTileHost(host.getContext(), host.getPhoneStatusBar(),
+ host.getBluetoothController(), host.getLocationController(),
+ host.getRotationLockController(), host.getNetworkController(),
+ host.getZenModeController(), host.getHotspotController(),
+ host.getCastController(), host.getFlashlightController(),
+ host.getUserSwitcherController(), host.getUserInfoController(),
+ host.getKeyguardMonitor(), host.getSecurityController(),
+ host.getBatteryController());
+ mHeaderQsPanel.setHost(myHost);
+ mHeaderQsPanel.setTiles(myHost.getTiles());
+ myHost.setCallback(new QSTile.Host.Callback() {
+ @Override
+ public void onTilesChanged() {
+ mHeaderQsPanel.setTiles(myHost.getTiles());
+ }
+ });
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v == mSettingsButton) {
+ if (mSettingsButton.isTunerClick()) {
+ if (TunerService.isTunerEnabled(mContext)) {
+ TunerService.showResetRequest(mContext, new Runnable() {
+ @Override
+ public void run() {
+ // Relaunch settings so that the tuner disappears.
+ startSettingsActivity();
+ }
+ });
+ } else {
+ Toast.makeText(getContext(), R.string.tuner_toast, Toast.LENGTH_LONG).show();
+ TunerService.setTunerEnabled(mContext, true);
+ }
+ }
+ startSettingsActivity();
+ } else if (v == mAlarmStatus && mNextAlarm != null) {
+ PendingIntent showIntent = mNextAlarm.getShowIntent();
+ if (showIntent != null && showIntent.isActivity()) {
+ mActivityStarter.startActivity(showIntent.getIntent(), true /* dismissShade */);
+ }
+ }
+ }
+
+ private void startSettingsActivity() {
+ mActivityStarter.startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS),
+ true /* dismissShade */);
+ }
+
+ @Override
+ public void setNextAlarmController(NextAlarmController nextAlarmController) {
+ mNextAlarmController = nextAlarmController;
+ }
+
+ @Override
+ public void setBatteryController(BatteryController batteryController) {
+ // Don't care
+ }
+
+ @Override
+ public void setUserInfoController(UserInfoController userInfoController) {
+ // Don't care.
+ }
+
+ @Override
+ public void setEmergencyCallsOnly(boolean emergencyOnly) {
+ // Don't care.
+ }
+
+ private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
+ private boolean mScanState;
+
+ @Override
+ public void onShowingDetail(final QSTile.DetailAdapter detail) {
+ mDetailTransitioning = true;
+ post(new Runnable() {
+ @Override
+ public void run() {
+ handleShowingDetail(detail);
+ }
+ });
+ }
+
+ @Override
+ public void onToggleStateChanged(final boolean state) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ handleToggleStateChanged(state);
+ }
+ });
+
+ }
+
+ @Override
+ public void onScanStateChanged(final boolean state) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ handleScanStateChanged(state);
+ }
+ });
+ }
+
+ private void handleToggleStateChanged(boolean state) {
+ mQsDetailHeaderSwitch.setChecked(state);
+ }
+
+ private void handleScanStateChanged(boolean state) {
+ if (mScanState == state) return;
+ mScanState = state;
+ final Animatable anim = (Animatable) mQsDetailHeaderProgress.getDrawable();
+ if (state) {
+ mQsDetailHeaderProgress.animate().alpha(1f);
+ anim.start();
+ } else {
+ mQsDetailHeaderProgress.animate().alpha(0f);
+ anim.stop();
+ }
+ }
+
+ private void handleShowingDetail(final QSTile.DetailAdapter detail) {
+ final boolean showingDetail = detail != null;
+ transition(mExpandedGroup, !showingDetail);
+ if (mAlarmShowing) {
+ transition(mAlarmStatus, !showingDetail);
+ }
+ transition(mQsDetailHeader, showingDetail);
+ mShowingDetail = showingDetail;
+ if (showingDetail) {
+ mQsDetailHeaderTitle.setText(detail.getTitle());
+ final Boolean toggleState = detail.getToggleState();
+ if (toggleState == null) {
+ mQsDetailHeaderSwitch.setVisibility(INVISIBLE);
+ mQsDetailHeader.setClickable(false);
+ } else {
+ mQsDetailHeaderSwitch.setVisibility(VISIBLE);
+ mQsDetailHeaderSwitch.setChecked(toggleState);
+ mQsDetailHeader.setClickable(true);
+ mQsDetailHeader.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ boolean checked = !mQsDetailHeaderSwitch.isChecked();
+ mQsDetailHeaderSwitch.setChecked(checked);
+ detail.setToggleState(checked);
+ }
+ });
+ }
+ } else {
+ mQsDetailHeader.setClickable(false);
+ }
+ }
+
+ private void transition(final View v, final boolean in) {
+ if (in) {
+ v.bringToFront();
+ v.setVisibility(VISIBLE);
+ }
+ if (v.hasOverlappingRendering()) {
+ v.animate().withLayer();
+ }
+ v.animate()
+ .alpha(in ? 1 : 0)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ if (!in) {
+ v.setVisibility(INVISIBLE);
+ }
+ mDetailTransitioning = false;
+ }
+ })
+ .start();
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 7f5ffaf..65d84e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -237,7 +237,7 @@
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- TunerService.get(mContext).addTunable(this, QSPanel.QS_PAGED_PANEL);
+ TunerService.get(mContext).addTunable(this, QSPanel.QS_THE_NEW_QS);
}
@Override
@@ -248,7 +248,7 @@
@Override
public void onTuningChanged(String key, String newValue) {
- if (QSPanel.QS_PAGED_PANEL.equals(key)) {
+ if (QSPanel.QS_THE_NEW_QS.equals(key)) {
mAllowExpand = newValue == null || Integer.parseInt(newValue) == 0;
if (!mAllowExpand) {
setExpanded(false);
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
index 9a78b6c..911d6a2 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerFragment.java
@@ -101,7 +101,7 @@
}
}).show();
}
- TunerService.get(getContext()).addTunable(mQsPaging, QSPanel.QS_PAGED_PANEL);
+ TunerService.get(getContext()).addTunable(mQsPaging, QSPanel.QS_THE_NEW_QS);
}
@Override