summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/layout/qs_detail.xml35
-rw-r--r--packages/SystemUI/res/layout/qs_detail_header.xml1
-rw-r--r--packages/SystemUI/res/layout/qs_panel.xml2
-rw-r--r--packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml8
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainer.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSDetail.java287
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java183
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java137
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java3
11 files changed, 357 insertions, 319 deletions
diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index ddff0f031fb6..bed8f1be54fe 100644
--- a/packages/SystemUI/res/layout/qs_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -14,12 +14,35 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<!-- Extends LinearLayout -->
+<com.android.systemui.qs.QSDetail
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/qs_detail_background"
+ android:paddingBottom="8dp"
+ android:clickable="true"
+ android:visibility="invisible"
+ android:orientation="vertical">
+
+ <include
+ android:id="@+id/qs_detail_header"
+ layout="@layout/qs_detail_header"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="28dp"
+ />
+
+ <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="match_parent"
- android:background="@drawable/qs_detail_background"
- android:paddingBottom="8dp"
- android:orientation="vertical">
+ android:layout_height="wrap_content"
+ systemui:hasOverlappingRendering="false"
+ />
<FrameLayout
android:id="@android:id/content"
@@ -53,4 +76,4 @@
android:focusable="true"/>
</LinearLayout>
-</LinearLayout>
+</com.android.systemui.qs.QSDetail>
diff --git a/packages/SystemUI/res/layout/qs_detail_header.xml b/packages/SystemUI/res/layout/qs_detail_header.xml
index 153e35f1f675..df46271b5d64 100644
--- a/packages/SystemUI/res/layout/qs_detail_header.xml
+++ b/packages/SystemUI/res/layout/qs_detail_header.xml
@@ -19,7 +19,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingEnd="@dimen/qs_panel_padding"
- android:visibility="invisible"
android:background="@drawable/btn_borderless_rect"
android:gravity="center">
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 45236a075e72..9f90af231b20 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -30,4 +30,6 @@
<include layout="@layout/quick_status_bar_expanded_header" />
+ <include android:id="@+id/qs_detail" layout="@layout/qs_detail" />
+
</com.android.systemui.qs.QSContainer>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 07ac6a58e351..84df0d643e58 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -159,14 +159,6 @@
android:clipChildren="false"
android:clipToPadding="false" />
- <include
- android:id="@+id/qs_detail_header"
- layout="@layout/qs_detail_header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="28dp"
- />
-
<com.android.systemui.statusbar.AlphaOptimizedImageView
android:id="@+id/qs_detail_header_progress"
android:src="@drawable/indeterminate_anim"
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index 32eeb0787113..34dfd6c55abd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -40,6 +40,7 @@ public class QSContainer extends FrameLayout {
private int mHeightOverride = -1;
private QSPanel mQSPanel;
+ private QSDetail mQSDetail;
protected BaseStatusBarHeader mHeader;
private float mQsExpansion;
private boolean mQsExpanded;
@@ -57,6 +58,8 @@ public class QSContainer extends FrameLayout {
protected void onFinishInflate() {
super.onFinishInflate();
mQSPanel = (QSPanel) findViewById(R.id.quick_settings_panel);
+ mQSDetail = (QSDetail) findViewById(R.id.qs_detail);
+ mQSDetail.setQsPanel(mQSPanel);
mHeader = (BaseStatusBarHeader) findViewById(R.id.header);
}
@@ -82,7 +85,7 @@ public class QSContainer extends FrameLayout {
* during closing the detail panel, this already returns the smaller height.
*/
public int getDesiredHeight() {
- if (mQSPanel.isClosingDetail()) {
+ if (mQSDetail.isClosingDetail()) {
return mQSPanel.getGridHeight() + mHeader.getCollapsedHeight() + getPaddingBottom();
} else {
return getMeasuredHeight();
@@ -94,6 +97,7 @@ public class QSContainer extends FrameLayout {
int height = (int) (mQsExpansion * (heightOverride - mHeader.getCollapsedHeight()))
+ mHeader.getCollapsedHeight();
setBottom(getTop() + height);
+ mQSDetail.setBottom(getTop() + height);
}
private void updateQsState() {
@@ -115,6 +119,10 @@ public class QSContainer extends FrameLayout {
return mQSPanel;
}
+ public boolean isShowingDetail() {
+ return mQSPanel.isShowingCustomize() || mQSDetail.isShowingDetail();
+ }
+
public void setHeaderClickable(boolean clickable) {
if (DEBUG) Log.d(TAG, "setHeaderClickable " + clickable);
mHeader.setClickable(clickable);
@@ -154,6 +162,7 @@ public class QSContainer extends FrameLayout {
}
mHeader.setExpansion(mKeyguardShowing ? 1 : expansion);
mQSPanel.setTranslationY(translationScaleY * mQSPanel.getHeight());
+ mQSDetail.setFullyExpanded(expansion == 1);
updateBottom();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
new file mode 100644
index 000000000000..50c0cca8d8e7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetail.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2016 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.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.drawable.Animatable;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.Switch;
+import android.widget.TextView;
+import com.android.internal.logging.MetricsLogger;
+import com.android.systemui.FontSizeUtils;
+import com.android.systemui.R;
+import com.android.systemui.qs.QSTile.DetailAdapter;
+import com.android.systemui.statusbar.phone.QSTileHost;
+
+public class QSDetail extends LinearLayout {
+
+ private static final String TAG = "QSDetail";
+ private static final long FADE_DURATION = 300;
+
+ private final SparseArray<View> mDetailViews = new SparseArray<>();
+
+ private ViewGroup mDetailContent;
+ private TextView mDetailSettingsButton;
+ private TextView mDetailDoneButton;
+ private QSDetailClipper mClipper;
+ private DetailAdapter mDetailAdapter;
+ private QSPanel mQsPanel;
+
+ private View mQsDetailHeader;
+ private TextView mQsDetailHeaderTitle;
+ private Switch mQsDetailHeaderSwitch;
+ private ImageView mQsDetailHeaderProgress;
+
+ private QSTileHost mHost;
+
+ private boolean mScanState;
+ private boolean mClosingDetail;
+ private boolean mFullyExpanded;
+ private View mQsDetailHeaderBack;
+
+ public QSDetail(Context context, @Nullable AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ FontSizeUtils.updateFontSize(mDetailDoneButton, R.dimen.qs_detail_button_text_size);
+ FontSizeUtils.updateFontSize(mDetailSettingsButton, R.dimen.qs_detail_button_text_size);
+
+ for (int i = 0; i < mDetailViews.size(); i++) {
+ mDetailViews.valueAt(i).dispatchConfigurationChanged(newConfig);
+ }
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mDetailContent = (ViewGroup) findViewById(android.R.id.content);
+ mDetailSettingsButton = (TextView) findViewById(android.R.id.button2);
+ mDetailDoneButton = (TextView) findViewById(android.R.id.button1);
+
+ mQsDetailHeader = findViewById(R.id.qs_detail_header);
+ mQsDetailHeaderBack = mQsDetailHeader.findViewById(com.android.internal.R.id.up);
+ 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);
+
+ updateDetailText();
+
+ mClipper = new QSDetailClipper(this);
+
+ final OnClickListener doneListener = new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ announceForAccessibility(
+ mContext.getString(R.string.accessibility_desc_quick_settings));
+ mQsPanel.closeDetail();
+ }
+ };
+ mQsDetailHeaderBack.setOnClickListener(doneListener);
+ mDetailDoneButton.setOnClickListener(doneListener);
+ }
+
+ public void setQsPanel(QSPanel panel) {
+ mQsPanel = panel;
+ mQsPanel.setCallback(mQsPanelCallback);
+ }
+
+ public void setHost(QSTileHost host) {
+ mHost = host;
+ }
+ public boolean isShowingDetail() {
+ return mDetailAdapter != null;
+ }
+
+ public void setFullyExpanded(boolean fullyExpanded) {
+ mFullyExpanded = fullyExpanded;
+ }
+
+ private void updateDetailText() {
+ mDetailDoneButton.setText(R.string.quick_settings_done);
+ mDetailSettingsButton.setText(R.string.quick_settings_more_settings);
+ }
+
+ public void updateResources() {
+ updateDetailText();
+ }
+
+ public boolean isClosingDetail() {
+ return mClosingDetail;
+ }
+
+ private void handleShowingDetail(final QSTile.DetailAdapter adapter, int x, int y) {
+ final boolean showingDetail = adapter != null;
+ setClickable(showingDetail);
+ if (showingDetail) {
+ mQsDetailHeaderTitle.setText(adapter.getTitle());
+ final Boolean toggleState = adapter.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);
+ adapter.setToggleState(checked);
+ }
+ });
+ }
+ }
+
+ boolean visibleDiff = (mDetailAdapter != null) != (adapter != null);
+ if (!visibleDiff && mDetailAdapter == adapter) return; // already in right state
+ AnimatorListener listener = null;
+ if (adapter != null) {
+ int viewCacheIndex = adapter.getMetricsCategory();
+ View detailView = adapter.createDetailView(mContext, mDetailViews.get(viewCacheIndex),
+ mDetailContent);
+ if (detailView == null) throw new IllegalStateException("Must return detail view");
+
+ final Intent settingsIntent = adapter.getSettingsIntent();
+ mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE);
+ mDetailSettingsButton.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mHost.startActivityDismissingKeyguard(settingsIntent);
+ }
+ });
+
+ mDetailContent.removeAllViews();
+ mDetailContent.addView(detailView);
+ mDetailViews.put(viewCacheIndex, detailView);
+ MetricsLogger.visible(mContext, adapter.getMetricsCategory());
+ announceForAccessibility(mContext.getString(
+ R.string.accessibility_quick_settings_detail,
+ adapter.getTitle()));
+ mDetailAdapter = adapter;
+ listener = mHideGridContentWhenDone;
+ setVisibility(View.VISIBLE);
+ } else {
+ if (mDetailAdapter != null) {
+ MetricsLogger.hidden(mContext, mDetailAdapter.getMetricsCategory());
+ }
+ mClosingDetail = true;
+ mDetailAdapter = null;
+ listener = mTeardownDetailWhenDone;
+ mQsPanel.setGridContentVisibility(true);
+ mQsPanelCallback.onScanStateChanged(false);
+ }
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ if (visibleDiff) {
+ if (mFullyExpanded || mDetailAdapter != null) {
+ setAlpha(1);
+ mClipper.animateCircularClip(x, y, mDetailAdapter != null, listener);
+ } else {
+ animate().alpha(0)
+ .setDuration(FADE_DURATION)
+ .setListener(listener)
+ .start();
+ }
+ }
+ }
+
+ 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 final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() {
+ @Override
+ public void onToggleStateChanged(final boolean state) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ handleToggleStateChanged(state);
+ }
+ });
+ }
+
+ @Override
+ public void onShowingDetail(final DetailAdapter detail, final int x, final int y) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ handleShowingDetail(detail, x, y);
+ }
+ });
+ }
+
+ @Override
+ public void onScanStateChanged(final boolean state) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ handleScanStateChanged(state);
+ }
+ });
+ }
+ };
+
+ private final AnimatorListenerAdapter mHideGridContentWhenDone = new AnimatorListenerAdapter() {
+ public void onAnimationCancel(Animator animation) {
+ // If we have been cancelled, remove the listener so that onAnimationEnd doesn't get
+ // called, this will avoid accidentally turning off the grid when we don't want to.
+ animation.removeListener(this);
+ };
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ // Only hide content if still in detail state.
+ if (mDetailAdapter != null) {
+ mQsPanel.setGridContentVisibility(false);
+ }
+ }
+ };
+
+ private final AnimatorListenerAdapter mTeardownDetailWhenDone = new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator animation) {
+ mDetailContent.removeAllViews();
+ setVisibility(View.INVISIBLE);
+ mClosingDetail = false;
+ };
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 4ffa527c6a42..53abe37d4752 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -16,12 +16,8 @@
package com.android.systemui.qs;
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.AnimatorListenerAdapter;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Handler;
@@ -29,16 +25,11 @@ import android.os.Message;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
-import android.view.ViewGroup;
-import android.view.accessibility.AccessibilityEvent;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
-import android.widget.TextView;
-
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.qs.QSTile.DetailAdapter;
import com.android.systemui.qs.customize.QSCustomizer;
@@ -60,21 +51,14 @@ public class QSPanel extends FrameLayout implements Tunable {
protected final Context mContext;
protected final ArrayList<TileRecord> mRecords = new ArrayList<TileRecord>();
- private final View mDetail;
- private final ViewGroup mDetailContent;
- private final TextView mDetailSettingsButton;
- private final TextView mDetailDoneButton;
protected final View mBrightnessView;
- private final QSDetailClipper mClipper;
private final H mHandler = new H();
private int mPanelPaddingBottom;
private int mBrightnessPaddingTop;
private boolean mExpanded;
private boolean mListening;
- private boolean mClosingDetail;
- private Record mDetailRecord;
private Callback mCallback;
private BrightnessController mBrightnessController;
protected QSTileHost mHost;
@@ -86,6 +70,7 @@ public class QSPanel extends FrameLayout implements Tunable {
protected QSTileLayout mTileLayout;
private QSCustomizer mCustomizePanel;
+ private Record mDetailRecord;
public QSPanel(Context context) {
this(context, null);
@@ -95,14 +80,6 @@ public class QSPanel extends FrameLayout implements Tunable {
super(context, attrs);
mContext = context;
- mDetail = LayoutInflater.from(context).inflate(R.layout.qs_detail, this, false);
- mDetailContent = (ViewGroup) mDetail.findViewById(android.R.id.content);
- mDetailSettingsButton = (TextView) mDetail.findViewById(android.R.id.button2);
- mDetailDoneButton = (TextView) mDetail.findViewById(android.R.id.button1);
- updateDetailText();
- mDetail.setVisibility(GONE);
- mDetail.setClickable(true);
- addView(mDetail);
mQsContainer = new LinearLayout(mContext);
mQsContainer.setOrientation(LinearLayout.VERTICAL);
@@ -132,21 +109,16 @@ public class QSPanel extends FrameLayout implements Tunable {
mFooter = new QSFooter(this, context);
mQsContainer.addView(mFooter.getView());
- mClipper = new QSDetailClipper(mDetail);
updateResources();
mBrightnessController = new BrightnessController(getContext(),
(ImageView) findViewById(R.id.brightness_icon),
(ToggleSlider) findViewById(R.id.brightness_slider));
- mDetailDoneButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- announceForAccessibility(
- mContext.getString(R.string.accessibility_desc_quick_settings));
- closeDetail();
- }
- });
+ }
+
+ public boolean isShowingCustomize() {
+ return mCustomizePanel != null && mCustomizePanel.isCustomizing();
}
@Override
@@ -189,11 +161,6 @@ public class QSPanel extends FrameLayout implements Tunable {
mCustomizePanel.setHost(mHost);
}
- private void updateDetailText() {
- mDetailDoneButton.setText(R.string.quick_settings_done);
- mDetailSettingsButton.setText(R.string.quick_settings_more_settings);
- }
-
public void setBrightnessMirror(BrightnessMirrorController c) {
super.onFinishInflate();
ToggleSlider brightnessSlider = (ToggleSlider) findViewById(R.id.brightness_slider);
@@ -227,7 +194,6 @@ public class QSPanel extends FrameLayout implements Tunable {
if (mListening) {
refreshAllTiles();
}
- updateDetailText();
if (mTileLayout != null) {
mTileLayout.updateResources();
}
@@ -236,18 +202,6 @@ public class QSPanel extends FrameLayout implements Tunable {
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- FontSizeUtils.updateFontSize(mDetailDoneButton, R.dimen.qs_detail_button_text_size);
- FontSizeUtils.updateFontSize(mDetailSettingsButton, R.dimen.qs_detail_button_text_size);
-
- // We need to poke the detail views as well as they might not be attached to the view
- // hierarchy but reused at a later point.
- int count = mRecords.size();
- for (int i = 0; i < count; i++) {
- View detailView = mRecords.get(i).detailView;
- if (detailView != null) {
- detailView.dispatchConfigurationChanged(newConfig);
- }
- }
mFooter.onConfigurationChanged();
}
@@ -295,7 +249,7 @@ public class QSPanel extends FrameLayout implements Tunable {
public void showDetailAdapter(boolean show, DetailAdapter adapter, int[] locationInWindow) {
int xInWindow = locationInWindow[0];
int yInWindow = locationInWindow[1];
- mDetail.getLocationInWindow(locationInWindow);
+ ((View) getParent()).getLocationInWindow(locationInWindow);
Record r = new Record();
r.detailAdapter = adapter;
@@ -320,9 +274,6 @@ public class QSPanel extends FrameLayout implements Tunable {
for (QSTile<?> tile : tiles) {
addTile(tile);
}
- if (isShowingDetail()) {
- mDetail.bringToFront();
- }
}
private void drawTile(TileRecord r, QSTile.State state) {
@@ -340,9 +291,7 @@ public class QSPanel extends FrameLayout implements Tunable {
final QSTile.Callback callback = new QSTile.Callback() {
@Override
public void onStateChanged(QSTile.State state) {
- if (!r.openingDetail) {
- drawTile(r, state);
- }
+ drawTile(r, state);
}
@Override
@@ -417,11 +366,6 @@ public class QSPanel extends FrameLayout implements Tunable {
tile.click();
}
- public boolean isShowingDetail() {
- return mDetailRecord != null
- || (mCustomizePanel != null && mCustomizePanel.isCustomizing());
- }
-
public void closeDetail() {
if (mCustomizePanel != null && mCustomizePanel.isCustomizing()) {
// Treat this as a detail panel for now, to make things easy.
@@ -431,10 +375,6 @@ public class QSPanel extends FrameLayout implements Tunable {
showDetail(false, mDetailRecord);
}
- public boolean isClosingDetail() {
- return mClosingDetail;
- }
-
public int getGridHeight() {
return mQsContainer.getMeasuredHeight();
}
@@ -465,58 +405,25 @@ public class QSPanel extends FrameLayout implements Tunable {
}
r.tile.setDetailListening(show);
int x = r.tileView.getLeft() + r.tileView.getWidth() / 2;
- int y = r.tileView.getTop() + mTileLayout.getOffsetTop(r) + r.tileView.getHeight() / 2;
+ int y = r.tileView.getTop() + mTileLayout.getOffsetTop(r) + r.tileView.getHeight() / 2
+ + getTop();
handleShowDetailImpl(r, show, x, y);
}
private void handleShowDetailImpl(Record r, boolean show, int x, int y) {
- boolean visibleDiff = (mDetailRecord != null) != show;
- if (!visibleDiff && mDetailRecord == r) return; // already in right state
- DetailAdapter detailAdapter = null;
- AnimatorListener listener = null;
- if (show) {
- detailAdapter = r.detailAdapter;
- r.detailView = detailAdapter.createDetailView(mContext, r.detailView, mDetailContent);
- if (r.detailView == null) throw new IllegalStateException("Must return detail view");
-
- final Intent settingsIntent = detailAdapter.getSettingsIntent();
- mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE);
- mDetailSettingsButton.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mHost.startActivityDismissingKeyguard(settingsIntent);
- }
- });
-
- mDetailContent.removeAllViews();
- mDetail.bringToFront();
- mDetailContent.addView(r.detailView);
- MetricsLogger.visible(mContext, detailAdapter.getMetricsCategory());
- announceForAccessibility(mContext.getString(
- R.string.accessibility_quick_settings_detail,
- detailAdapter.getTitle()));
- setDetailRecord(r);
- listener = mHideGridContentWhenDone;
- if (r instanceof TileRecord && visibleDiff) {
- ((TileRecord) r).openingDetail = true;
- }
- } else {
- if (mDetailRecord != null) {
- MetricsLogger.hidden(mContext, mDetailRecord.detailAdapter.getMetricsCategory());
- }
- mClosingDetail = true;
- setGridContentVisibility(true);
- listener = mTeardownDetailWhenDone;
- fireScanStateChanged(false);
- }
- sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- fireShowingDetail(show ? detailAdapter : null);
- if (visibleDiff) {
- mClipper.animateCircularClip(x, y, show, listener);
- }
+ setDetailRecord(show ? r : null);
+ fireShowingDetail(show ? r.detailAdapter : null, x, y);
}
- private void setGridContentVisibility(boolean visible) {
+ private void setDetailRecord(Record r) {
+ if (r == mDetailRecord) return;
+ mDetailRecord = r;
+ final boolean scanState = mDetailRecord instanceof TileRecord
+ && ((TileRecord) mDetailRecord).scanState;
+ fireScanStateChanged(scanState);
+ }
+
+ void setGridContentVisibility(boolean visible) {
int newVis = visible ? VISIBLE : INVISIBLE;
mQsContainer.setVisibility(newVis);
if (mGridContentVisible != visible) {
@@ -532,9 +439,9 @@ public class QSPanel extends FrameLayout implements Tunable {
}
}
- private void fireShowingDetail(QSTile.DetailAdapter detail) {
+ private void fireShowingDetail(DetailAdapter detail, int x, int y) {
if (mCallback != null) {
- mCallback.onShowingDetail(detail);
+ mCallback.onShowingDetail(detail, x, y);
}
}
@@ -550,14 +457,6 @@ public class QSPanel extends FrameLayout implements Tunable {
}
}
- private void setDetailRecord(Record r) {
- if (r == mDetailRecord) return;
- mDetailRecord = r;
- final boolean scanState = mDetailRecord instanceof TileRecord
- && ((TileRecord) mDetailRecord).scanState;
- fireScanStateChanged(scanState);
- }
-
public void clickTile(ComponentName tile) {
final String spec = CustomTile.toSpec(tile);
final int N = mRecords.size();
@@ -581,7 +480,6 @@ public class QSPanel extends FrameLayout implements Tunable {
}
protected static class Record {
- View detailView;
DetailAdapter detailAdapter;
int x;
int y;
@@ -591,45 +489,10 @@ public class QSPanel extends FrameLayout implements Tunable {
public QSTile<?> tile;
public QSTileBaseView tileView;
public boolean scanState;
- public boolean openingDetail;
}
- private final AnimatorListenerAdapter mTeardownDetailWhenDone = new AnimatorListenerAdapter() {
- public void onAnimationEnd(Animator animation) {
- mDetailContent.removeAllViews();
- setDetailRecord(null);
- mClosingDetail = false;
- };
- };
-
- private final AnimatorListenerAdapter mHideGridContentWhenDone = new AnimatorListenerAdapter() {
- public void onAnimationCancel(Animator animation) {
- // If we have been cancelled, remove the listener so that onAnimationEnd doesn't get
- // called, this will avoid accidentally turning off the grid when we don't want to.
- animation.removeListener(this);
- redrawTile();
- };
-
- @Override
- public void onAnimationEnd(Animator animation) {
- // Only hide content if still in detail state.
- if (mDetailRecord != null) {
- setGridContentVisibility(false);
- redrawTile();
- }
- }
-
- private void redrawTile() {
- if (mDetailRecord instanceof TileRecord) {
- final TileRecord tileRecord = (TileRecord) mDetailRecord;
- tileRecord.openingDetail = false;
- drawTile(tileRecord, tileRecord.tile.getState());
- }
- }
- };
-
public interface Callback {
- void onShowingDetail(QSTile.DetailAdapter detail);
+ void onShowingDetail(DetailAdapter detail, int x, int y);
void onToggleStateChanged(boolean state);
void onScanStateChanged(boolean state);
}
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 8f0f51f502b7..88a78430e679 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1975,7 +1975,7 @@ public class NotificationPanelView extends PanelView implements
}
public boolean isQsDetailShowing() {
- return mQsContainer.getQsPanel().isShowingDetail();
+ return mQsContainer.isShowingDetail();
}
public void closeQsDetail() {
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 17e43c406288..3aa576ffc0a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -69,7 +69,6 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.Vibrator;
@@ -89,7 +88,6 @@ import android.view.ThreadedRenderer;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
-import android.view.ViewParent;
import android.view.ViewStub;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
@@ -97,7 +95,6 @@ import android.view.animation.AccelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.TextView;
-
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.NotificationVisibility;
@@ -118,6 +115,7 @@ import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import com.android.systemui.qs.QSDetail;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.recents.events.EventBus;
@@ -176,7 +174,6 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.TreeSet;
import static android.app.StatusBarManager.NAVIGATION_HINT_BACK_ALT;
import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
@@ -875,6 +872,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mBrightnessMirrorController = new BrightnessMirrorController(mStatusBarWindow);
mQSPanel.setBrightnessMirror(mBrightnessMirrorController);
mHeader.setQSPanel(mQSPanel);
+ QSDetail qsDetail = (QSDetail) mStatusBarWindow.findViewById(R.id.qs_detail);
+ qsDetail.setHost(qsh);
qsh.addCallback(new QSTileHost.Callback() {
@Override
public void onTilesChanged() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
index fe463855020a..11d99ffe97dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java
@@ -21,14 +21,12 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Rect;
-import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.RippleDrawable;
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.keyguard.KeyguardStatusView;
@@ -50,17 +48,12 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements
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 ViewGroup mDateTimeGroup;
private View mEmergencyOnly;
@@ -101,13 +94,6 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements
mAlarmStatus = (TextView) findViewById(R.id.alarm_status);
mAlarmStatus.setOnClickListener(this);
- mQsDetailHeader = findViewById(R.id.qs_detail_header);
- mQsDetailHeader.setAlpha(0);
- mQsDetailHeaderBack = mQsDetailHeader.findViewById(com.android.internal.R.id.up);
- 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);
-
mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
mMultiUserAvatar = (ImageView) mMultiUserSwitch.findViewById(R.id.multi_user_avatar);
@@ -179,7 +165,6 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements
private void updateVisibilities() {
mAlarmStatus.setVisibility(mAlarmShowing ? View.VISIBLE : View.GONE);
- mQsDetailHeader.setVisibility(mExpanded && mShowingDetail ? View.VISIBLE : View.INVISIBLE);
mEmergencyOnly.setVisibility(mExpanded && mShowEmergencyCallsOnly
? View.VISIBLE : View.INVISIBLE);
mSettingsContainer.findViewById(R.id.tuner_icon).setVisibility(
@@ -188,10 +173,6 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements
: View.GONE);
}
- private boolean hasMultiUsers() {
- return false;
- }
-
private void updateListeners() {
if (mListening) {
mNextAlarmController.addStateChangedCallback(this);
@@ -210,7 +191,6 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements
mQsPanel = qsPanel;
setupHost(qsPanel.getHost());
if (mQsPanel != null) {
- mQsPanel.setCallback(mQsPanelCallback);
mMultiUserSwitch.setQsPanel(qsPanel);
}
}
@@ -290,121 +270,4 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements
}
}
}
-
- 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(mDateTimeGroup, !showingDetail);
- 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);
- }
- });
- }
- mQsDetailHeaderBack.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- v.getLocationInWindow(mTmpInt2);
- mTmpInt2[0] += v.getWidth() / 2;
- mTmpInt2[1] += v.getHeight() / 2;
- mQsPanel.showDetailAdapter(false, null, mTmpInt2);
- }
- });
- } 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 d2f1ca9630e2..3e3b16922f7a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -46,6 +46,7 @@ import com.android.systemui.FontSizeUtils;
import com.android.systemui.R;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.QSTile;
+import com.android.systemui.qs.QSTile.DetailAdapter;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.NetworkControllerImpl.EmergencyListener;
import com.android.systemui.statusbar.policy.NextAlarmController;
@@ -742,7 +743,7 @@ public class StatusBarHeaderView extends BaseStatusBarHeader implements View.OnC
}
@Override
- public void onShowingDetail(final QSTile.DetailAdapter detail) {
+ public void onShowingDetail(final DetailAdapter detail, int x, int y) {
mDetailTransitioning = true;
post(new Runnable() {
@Override