1377e7ad8dc0562c6f445594288e451c377824e4cJason Monk/* 2377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * Copyright (C) 2016 The Android Open Source Project 3377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * 4377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * except in compliance with the License. You may obtain a copy of the License at 6377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * 7377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * http://www.apache.org/licenses/LICENSE-2.0 8377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * 9377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * Unless required by applicable law or agreed to in writing, software distributed under the 10377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * KIND, either express or implied. See the License for the specific language governing 12377e7ad8dc0562c6f445594288e451c377824e4cJason Monk * permissions and limitations under the License. 13377e7ad8dc0562c6f445594288e451c377824e4cJason Monk */ 14377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 15377e7ad8dc0562c6f445594288e451c377824e4cJason Monkpackage com.android.systemui.qs; 16377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 17377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.animation.Animator; 18377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.animation.Animator.AnimatorListener; 19377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.animation.AnimatorListenerAdapter; 20377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.annotation.Nullable; 21377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.content.Context; 22377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.content.Intent; 23377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.content.res.Configuration; 24377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.graphics.drawable.Animatable; 25377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.util.AttributeSet; 26377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.util.SparseArray; 27377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.view.View; 28377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.view.ViewGroup; 29377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.view.accessibility.AccessibilityEvent; 30377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.widget.ImageView; 31377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.widget.LinearLayout; 32377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.widget.Switch; 33377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport android.widget.TextView; 3466448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen 35377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport com.android.internal.logging.MetricsLogger; 36377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport com.android.systemui.FontSizeUtils; 37377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport com.android.systemui.R; 38377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport com.android.systemui.qs.QSTile.DetailAdapter; 39589bb70a77767980b6241ae676491edb42dedef5Jason Monkimport com.android.systemui.statusbar.phone.BaseStatusBarHeader; 40377e7ad8dc0562c6f445594288e451c377824e4cJason Monkimport com.android.systemui.statusbar.phone.QSTileHost; 41377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 42377e7ad8dc0562c6f445594288e451c377824e4cJason Monkpublic class QSDetail extends LinearLayout { 43377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 44377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private static final String TAG = "QSDetail"; 45377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private static final long FADE_DURATION = 300; 46377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 47377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private final SparseArray<View> mDetailViews = new SparseArray<>(); 48377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 49377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private ViewGroup mDetailContent; 50377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private TextView mDetailSettingsButton; 51377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private TextView mDetailDoneButton; 52377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private QSDetailClipper mClipper; 53377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private DetailAdapter mDetailAdapter; 54377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private QSPanel mQsPanel; 55377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 56377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private View mQsDetailHeader; 57377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private TextView mQsDetailHeaderTitle; 58377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private Switch mQsDetailHeaderSwitch; 59377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private ImageView mQsDetailHeaderProgress; 60377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 61377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private QSTileHost mHost; 62377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 63377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private boolean mScanState; 64377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private boolean mClosingDetail; 65377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private boolean mFullyExpanded; 66589bb70a77767980b6241ae676491edb42dedef5Jason Monk private BaseStatusBarHeader mHeader; 6766448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen private boolean mTriggeredExpand; 6866448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen private int mOpenX; 6966448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen private int mOpenY; 7035a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk private boolean mAnimatingOpen; 7148e093e6dfceab58ea53f1f996d55e9a1dc51358Jason Monk private boolean mSwitchState; 72377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 73377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public QSDetail(Context context, @Nullable AttributeSet attrs) { 74377e7ad8dc0562c6f445594288e451c377824e4cJason Monk super(context, attrs); 75377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 76377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 77377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 78377e7ad8dc0562c6f445594288e451c377824e4cJason Monk protected void onConfigurationChanged(Configuration newConfig) { 79377e7ad8dc0562c6f445594288e451c377824e4cJason Monk super.onConfigurationChanged(newConfig); 80377e7ad8dc0562c6f445594288e451c377824e4cJason Monk FontSizeUtils.updateFontSize(mDetailDoneButton, R.dimen.qs_detail_button_text_size); 81377e7ad8dc0562c6f445594288e451c377824e4cJason Monk FontSizeUtils.updateFontSize(mDetailSettingsButton, R.dimen.qs_detail_button_text_size); 82377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 83377e7ad8dc0562c6f445594288e451c377824e4cJason Monk for (int i = 0; i < mDetailViews.size(); i++) { 84377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailViews.valueAt(i).dispatchConfigurationChanged(newConfig); 85377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 86377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 87377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 88377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 89377e7ad8dc0562c6f445594288e451c377824e4cJason Monk protected void onFinishInflate() { 90377e7ad8dc0562c6f445594288e451c377824e4cJason Monk super.onFinishInflate(); 91377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailContent = (ViewGroup) findViewById(android.R.id.content); 92377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailSettingsButton = (TextView) findViewById(android.R.id.button2); 93377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailDoneButton = (TextView) findViewById(android.R.id.button1); 94377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 95377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeader = findViewById(R.id.qs_detail_header); 96377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderTitle = (TextView) mQsDetailHeader.findViewById(android.R.id.title); 97377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderSwitch = (Switch) mQsDetailHeader.findViewById(android.R.id.toggle); 98377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderProgress = (ImageView) findViewById(R.id.qs_detail_header_progress); 99377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 100377e7ad8dc0562c6f445594288e451c377824e4cJason Monk updateDetailText(); 101377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 102377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mClipper = new QSDetailClipper(this); 103377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 104377e7ad8dc0562c6f445594288e451c377824e4cJason Monk final OnClickListener doneListener = new OnClickListener() { 105377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 106377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void onClick(View v) { 107377e7ad8dc0562c6f445594288e451c377824e4cJason Monk announceForAccessibility( 108377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mContext.getString(R.string.accessibility_desc_quick_settings)); 109377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsPanel.closeDetail(); 110377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 111377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }; 112377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailDoneButton.setOnClickListener(doneListener); 113377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 114377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 115589bb70a77767980b6241ae676491edb42dedef5Jason Monk public void setQsPanel(QSPanel panel, BaseStatusBarHeader header) { 116377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsPanel = panel; 117589bb70a77767980b6241ae676491edb42dedef5Jason Monk mHeader = header; 11866448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen mHeader.setCallback(mQsPanelCallback); 119377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsPanel.setCallback(mQsPanelCallback); 120377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 121377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 122377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void setHost(QSTileHost host) { 123377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mHost = host; 124377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 125377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public boolean isShowingDetail() { 126377e7ad8dc0562c6f445594288e451c377824e4cJason Monk return mDetailAdapter != null; 127377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 128377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 129377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void setFullyExpanded(boolean fullyExpanded) { 130377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mFullyExpanded = fullyExpanded; 131377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 132377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 13366448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen public void setExpanded(boolean qsExpanded) { 13466448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen if (!qsExpanded) { 13566448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen mTriggeredExpand = false; 13666448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen } 13766448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen } 13866448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen 139377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private void updateDetailText() { 140377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailDoneButton.setText(R.string.quick_settings_done); 141377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailSettingsButton.setText(R.string.quick_settings_more_settings); 142377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 143377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 144377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void updateResources() { 145377e7ad8dc0562c6f445594288e451c377824e4cJason Monk updateDetailText(); 146377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 147377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 148377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public boolean isClosingDetail() { 149377e7ad8dc0562c6f445594288e451c377824e4cJason Monk return mClosingDetail; 150377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 151377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 152377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private void handleShowingDetail(final QSTile.DetailAdapter adapter, int x, int y) { 153377e7ad8dc0562c6f445594288e451c377824e4cJason Monk final boolean showingDetail = adapter != null; 154377e7ad8dc0562c6f445594288e451c377824e4cJason Monk setClickable(showingDetail); 155377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (showingDetail) { 156377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderTitle.setText(adapter.getTitle()); 157377e7ad8dc0562c6f445594288e451c377824e4cJason Monk final Boolean toggleState = adapter.getToggleState(); 158377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (toggleState == null) { 159377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderSwitch.setVisibility(INVISIBLE); 160377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeader.setClickable(false); 161377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } else { 162377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderSwitch.setVisibility(VISIBLE); 16335a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk handleToggleStateChanged(toggleState, adapter.getToggleEnabled()); 164377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeader.setClickable(true); 165377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeader.setOnClickListener(new OnClickListener() { 166377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 167377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void onClick(View v) { 168377e7ad8dc0562c6f445594288e451c377824e4cJason Monk boolean checked = !mQsDetailHeaderSwitch.isChecked(); 169377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderSwitch.setChecked(checked); 170377e7ad8dc0562c6f445594288e451c377824e4cJason Monk adapter.setToggleState(checked); 171377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 172377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }); 173377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 17466448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen if (!mFullyExpanded) { 17566448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen mTriggeredExpand = true; 17666448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen mHost.animateToggleQSExpansion(); 17766448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen } else { 17866448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen mTriggeredExpand = false; 17966448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen } 18066448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen mOpenX = x; 18166448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen mOpenY = y; 18266448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen } else { 18366448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen // Ensure we collapse into the same point we opened from. 18466448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen x = mOpenX; 18566448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen y = mOpenY; 18666448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen if (mTriggeredExpand) { 18766448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen mHost.animateToggleQSExpansion(); 18866448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen mTriggeredExpand = false; 18966448936dc7cb981effb5a741caa080278bcd6efXiaohui Chen } 190377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 191377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 192377e7ad8dc0562c6f445594288e451c377824e4cJason Monk boolean visibleDiff = (mDetailAdapter != null) != (adapter != null); 193377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (!visibleDiff && mDetailAdapter == adapter) return; // already in right state 194377e7ad8dc0562c6f445594288e451c377824e4cJason Monk AnimatorListener listener = null; 195377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (adapter != null) { 196377e7ad8dc0562c6f445594288e451c377824e4cJason Monk int viewCacheIndex = adapter.getMetricsCategory(); 197377e7ad8dc0562c6f445594288e451c377824e4cJason Monk View detailView = adapter.createDetailView(mContext, mDetailViews.get(viewCacheIndex), 198377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailContent); 199377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (detailView == null) throw new IllegalStateException("Must return detail view"); 200377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 201377e7ad8dc0562c6f445594288e451c377824e4cJason Monk final Intent settingsIntent = adapter.getSettingsIntent(); 202377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailSettingsButton.setVisibility(settingsIntent != null ? VISIBLE : GONE); 203377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailSettingsButton.setOnClickListener(new OnClickListener() { 204377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 205377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void onClick(View v) { 206377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mHost.startActivityDismissingKeyguard(settingsIntent); 207377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 208377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }); 209377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 210377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailContent.removeAllViews(); 211377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailContent.addView(detailView); 212377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailViews.put(viewCacheIndex, detailView); 213377e7ad8dc0562c6f445594288e451c377824e4cJason Monk MetricsLogger.visible(mContext, adapter.getMetricsCategory()); 214377e7ad8dc0562c6f445594288e451c377824e4cJason Monk announceForAccessibility(mContext.getString( 215377e7ad8dc0562c6f445594288e451c377824e4cJason Monk R.string.accessibility_quick_settings_detail, 216377e7ad8dc0562c6f445594288e451c377824e4cJason Monk adapter.getTitle())); 217377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailAdapter = adapter; 218377e7ad8dc0562c6f445594288e451c377824e4cJason Monk listener = mHideGridContentWhenDone; 219377e7ad8dc0562c6f445594288e451c377824e4cJason Monk setVisibility(View.VISIBLE); 220377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } else { 221377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (mDetailAdapter != null) { 222377e7ad8dc0562c6f445594288e451c377824e4cJason Monk MetricsLogger.hidden(mContext, mDetailAdapter.getMetricsCategory()); 223377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 224377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mClosingDetail = true; 225377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailAdapter = null; 226377e7ad8dc0562c6f445594288e451c377824e4cJason Monk listener = mTeardownDetailWhenDone; 227589bb70a77767980b6241ae676491edb42dedef5Jason Monk mHeader.setVisibility(View.VISIBLE); 228377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsPanel.setGridContentVisibility(true); 229377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsPanelCallback.onScanStateChanged(false); 230377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 231377e7ad8dc0562c6f445594288e451c377824e4cJason Monk sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); 232377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (visibleDiff) { 23335a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk mAnimatingOpen = adapter != null; 234377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (mFullyExpanded || mDetailAdapter != null) { 235377e7ad8dc0562c6f445594288e451c377824e4cJason Monk setAlpha(1); 236377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mClipper.animateCircularClip(x, y, mDetailAdapter != null, listener); 237377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } else { 238377e7ad8dc0562c6f445594288e451c377824e4cJason Monk animate().alpha(0) 239377e7ad8dc0562c6f445594288e451c377824e4cJason Monk .setDuration(FADE_DURATION) 240377e7ad8dc0562c6f445594288e451c377824e4cJason Monk .setListener(listener) 241377e7ad8dc0562c6f445594288e451c377824e4cJason Monk .start(); 242377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 243377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 244377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 245377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 24635a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk private void handleToggleStateChanged(boolean state, boolean toggleEnabled) { 24748e093e6dfceab58ea53f1f996d55e9a1dc51358Jason Monk mSwitchState = state; 24835a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk if (mAnimatingOpen) { 24948e093e6dfceab58ea53f1f996d55e9a1dc51358Jason Monk return; 25048e093e6dfceab58ea53f1f996d55e9a1dc51358Jason Monk } 251377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderSwitch.setChecked(state); 252fac2538e463138a8a1a92bc94af3f310d28718b4Jason Monk mQsDetailHeader.setEnabled(toggleEnabled); 253fac2538e463138a8a1a92bc94af3f310d28718b4Jason Monk mQsDetailHeaderSwitch.setEnabled(toggleEnabled); 254377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 255377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 256377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private void handleScanStateChanged(boolean state) { 257377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (mScanState == state) return; 258377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mScanState = state; 259377e7ad8dc0562c6f445594288e451c377824e4cJason Monk final Animatable anim = (Animatable) mQsDetailHeaderProgress.getDrawable(); 260377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (state) { 261377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderProgress.animate().alpha(1f); 262377e7ad8dc0562c6f445594288e451c377824e4cJason Monk anim.start(); 263377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } else { 264377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsDetailHeaderProgress.animate().alpha(0f); 265377e7ad8dc0562c6f445594288e451c377824e4cJason Monk anim.stop(); 266377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 267377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 268377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 26948e093e6dfceab58ea53f1f996d55e9a1dc51358Jason Monk private void checkPendingAnimations() { 27035a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk handleToggleStateChanged(mSwitchState, 27135a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk mDetailAdapter != null && mDetailAdapter.getToggleEnabled()); 27248e093e6dfceab58ea53f1f996d55e9a1dc51358Jason Monk } 27348e093e6dfceab58ea53f1f996d55e9a1dc51358Jason Monk 274377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private final QSPanel.Callback mQsPanelCallback = new QSPanel.Callback() { 275377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 276377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void onToggleStateChanged(final boolean state) { 277377e7ad8dc0562c6f445594288e451c377824e4cJason Monk post(new Runnable() { 278377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 279377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void run() { 28035a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk handleToggleStateChanged(state, 28135a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk mDetailAdapter != null && mDetailAdapter.getToggleEnabled()); 282377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 283377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }); 284377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 285377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 286377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 287377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void onShowingDetail(final DetailAdapter detail, final int x, final int y) { 288377e7ad8dc0562c6f445594288e451c377824e4cJason Monk post(new Runnable() { 289377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 290377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void run() { 291377e7ad8dc0562c6f445594288e451c377824e4cJason Monk handleShowingDetail(detail, x, y); 292377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 293377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }); 294377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 295377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 296377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 297377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void onScanStateChanged(final boolean state) { 298377e7ad8dc0562c6f445594288e451c377824e4cJason Monk post(new Runnable() { 299377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 300377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void run() { 301377e7ad8dc0562c6f445594288e451c377824e4cJason Monk handleScanStateChanged(state); 302377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 303377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }); 304377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 305377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }; 306377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 307377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private final AnimatorListenerAdapter mHideGridContentWhenDone = new AnimatorListenerAdapter() { 308377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void onAnimationCancel(Animator animation) { 309377e7ad8dc0562c6f445594288e451c377824e4cJason Monk // If we have been cancelled, remove the listener so that onAnimationEnd doesn't get 310377e7ad8dc0562c6f445594288e451c377824e4cJason Monk // called, this will avoid accidentally turning off the grid when we don't want to. 311377e7ad8dc0562c6f445594288e451c377824e4cJason Monk animation.removeListener(this); 31235a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk mAnimatingOpen = false; 31348e093e6dfceab58ea53f1f996d55e9a1dc51358Jason Monk checkPendingAnimations(); 314377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }; 315377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 316377e7ad8dc0562c6f445594288e451c377824e4cJason Monk @Override 317377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void onAnimationEnd(Animator animation) { 318377e7ad8dc0562c6f445594288e451c377824e4cJason Monk // Only hide content if still in detail state. 319377e7ad8dc0562c6f445594288e451c377824e4cJason Monk if (mDetailAdapter != null) { 320377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mQsPanel.setGridContentVisibility(false); 321589bb70a77767980b6241ae676491edb42dedef5Jason Monk mHeader.setVisibility(View.INVISIBLE); 322377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 32335a9c14cc689e417d6dccbd4831c6fcadb0ecc8eJason Monk mAnimatingOpen = false; 32448e093e6dfceab58ea53f1f996d55e9a1dc51358Jason Monk checkPendingAnimations(); 325377e7ad8dc0562c6f445594288e451c377824e4cJason Monk } 326377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }; 327377e7ad8dc0562c6f445594288e451c377824e4cJason Monk 328377e7ad8dc0562c6f445594288e451c377824e4cJason Monk private final AnimatorListenerAdapter mTeardownDetailWhenDone = new AnimatorListenerAdapter() { 329377e7ad8dc0562c6f445594288e451c377824e4cJason Monk public void onAnimationEnd(Animator animation) { 330377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mDetailContent.removeAllViews(); 331377e7ad8dc0562c6f445594288e451c377824e4cJason Monk setVisibility(View.INVISIBLE); 332377e7ad8dc0562c6f445594288e451c377824e4cJason Monk mClosingDetail = false; 333377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }; 334377e7ad8dc0562c6f445594288e451c377824e4cJason Monk }; 335377e7ad8dc0562c6f445594288e451c377824e4cJason Monk} 336