1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.systemui.statusbar.stack; 18 19 import android.content.Context; 20 import android.view.View; 21 22 import com.android.systemui.R; 23 import com.android.systemui.statusbar.ActivatableNotificationView; 24 import com.android.systemui.statusbar.ExpandableNotificationRow; 25 import com.android.systemui.statusbar.ExpandableView; 26 import com.android.systemui.statusbar.NotificationData; 27 import com.android.systemui.statusbar.NotificationShelf; 28 import com.android.systemui.statusbar.StatusBarState; 29 import com.android.systemui.statusbar.policy.HeadsUpManager; 30 31 import java.util.ArrayList; 32 import java.util.Collection; 33 34 /** 35 * A global state to track all input states for the algorithm. 36 */ 37 public class AmbientState { 38 private ArrayList<View> mDraggedViews = new ArrayList<View>(); 39 private int mScrollY; 40 private boolean mDimmed; 41 private ActivatableNotificationView mActivatedChild; 42 private float mOverScrollTopAmount; 43 private float mOverScrollBottomAmount; 44 private int mSpeedBumpIndex = -1; 45 private boolean mDark; 46 private boolean mHideSensitive; 47 private HeadsUpManager mHeadsUpManager; 48 private float mStackTranslation; 49 private int mLayoutHeight; 50 private int mTopPadding; 51 private boolean mShadeExpanded; 52 private float mMaxHeadsUpTranslation; 53 private boolean mDismissAllInProgress; 54 private int mLayoutMinHeight; 55 private NotificationShelf mShelf; 56 private int mZDistanceBetweenElements; 57 private int mBaseZHeight; 58 private int mMaxLayoutHeight; 59 private ActivatableNotificationView mLastVisibleBackgroundChild; 60 private float mCurrentScrollVelocity; 61 private int mStatusBarState; 62 private float mExpandingVelocity; 63 private boolean mPanelTracking; 64 private boolean mExpansionChanging; 65 private boolean mPanelFullWidth; 66 private Collection<HeadsUpManager.HeadsUpEntry> mPulsing; 67 private boolean mUnlockHintRunning; 68 private boolean mQsCustomizerShowing; 69 private int mIntrinsicPadding; 70 71 public AmbientState(Context context) { 72 reload(context); 73 } 74 75 /** 76 * Reload the dimens e.g. if the density changed. 77 */ 78 public void reload(Context context) { 79 mZDistanceBetweenElements = Math.max(1, context.getResources() 80 .getDimensionPixelSize(R.dimen.z_distance_between_notifications)); 81 mBaseZHeight = 4 * mZDistanceBetweenElements; 82 } 83 84 /** 85 * @return the basic Z height on which notifications remain. 86 */ 87 public int getBaseZHeight() { 88 return mBaseZHeight; 89 } 90 91 /** 92 * @return the distance in Z between two overlaying notifications. 93 */ 94 public int getZDistanceBetweenElements() { 95 return mZDistanceBetweenElements; 96 } 97 98 public int getScrollY() { 99 return mScrollY; 100 } 101 102 public void setScrollY(int scrollY) { 103 this.mScrollY = scrollY; 104 } 105 106 public void onBeginDrag(View view) { 107 mDraggedViews.add(view); 108 } 109 110 public void onDragFinished(View view) { 111 mDraggedViews.remove(view); 112 } 113 114 public ArrayList<View> getDraggedViews() { 115 return mDraggedViews; 116 } 117 118 /** 119 * @param dimmed Whether we are in a dimmed state (on the lockscreen), where the backgrounds are 120 * translucent and everything is scaled back a bit. 121 */ 122 public void setDimmed(boolean dimmed) { 123 mDimmed = dimmed; 124 } 125 126 /** In dark mode, we draw as little as possible, assuming a black background */ 127 public void setDark(boolean dark) { 128 mDark = dark; 129 } 130 131 public void setHideSensitive(boolean hideSensitive) { 132 mHideSensitive = hideSensitive; 133 } 134 135 /** 136 * In dimmed mode, a child can be activated, which happens on the first tap of the double-tap 137 * interaction. This child is then scaled normally and its background is fully opaque. 138 */ 139 public void setActivatedChild(ActivatableNotificationView activatedChild) { 140 mActivatedChild = activatedChild; 141 } 142 143 public boolean isDimmed() { 144 return mDimmed; 145 } 146 147 public boolean isDark() { 148 return mDark; 149 } 150 151 public boolean isHideSensitive() { 152 return mHideSensitive; 153 } 154 155 public ActivatableNotificationView getActivatedChild() { 156 return mActivatedChild; 157 } 158 159 public void setOverScrollAmount(float amount, boolean onTop) { 160 if (onTop) { 161 mOverScrollTopAmount = amount; 162 } else { 163 mOverScrollBottomAmount = amount; 164 } 165 } 166 167 public float getOverScrollAmount(boolean top) { 168 return top ? mOverScrollTopAmount : mOverScrollBottomAmount; 169 } 170 171 public int getSpeedBumpIndex() { 172 return mSpeedBumpIndex; 173 } 174 175 public void setSpeedBumpIndex(int shelfIndex) { 176 mSpeedBumpIndex = shelfIndex; 177 } 178 179 public void setHeadsUpManager(HeadsUpManager headsUpManager) { 180 mHeadsUpManager = headsUpManager; 181 } 182 183 public float getStackTranslation() { 184 return mStackTranslation; 185 } 186 187 public void setStackTranslation(float stackTranslation) { 188 mStackTranslation = stackTranslation; 189 } 190 191 public void setLayoutHeight(int layoutHeight) { 192 mLayoutHeight = layoutHeight; 193 } 194 195 public float getTopPadding() { 196 return mTopPadding; 197 } 198 199 public void setTopPadding(int topPadding) { 200 mTopPadding = topPadding; 201 } 202 203 public int getInnerHeight() { 204 return Math.max(Math.min(mLayoutHeight, mMaxLayoutHeight) - mTopPadding, mLayoutMinHeight); 205 } 206 207 public boolean isShadeExpanded() { 208 return mShadeExpanded; 209 } 210 211 public void setShadeExpanded(boolean shadeExpanded) { 212 mShadeExpanded = shadeExpanded; 213 } 214 215 public void setMaxHeadsUpTranslation(float maxHeadsUpTranslation) { 216 mMaxHeadsUpTranslation = maxHeadsUpTranslation; 217 } 218 219 public float getMaxHeadsUpTranslation() { 220 return mMaxHeadsUpTranslation; 221 } 222 223 public void setDismissAllInProgress(boolean dismissAllInProgress) { 224 mDismissAllInProgress = dismissAllInProgress; 225 } 226 227 public boolean isDismissAllInProgress() { 228 return mDismissAllInProgress; 229 } 230 231 public void setLayoutMinHeight(int layoutMinHeight) { 232 mLayoutMinHeight = layoutMinHeight; 233 } 234 235 public void setShelf(NotificationShelf shelf) { 236 mShelf = shelf; 237 } 238 239 public NotificationShelf getShelf() { 240 return mShelf; 241 } 242 243 public void setLayoutMaxHeight(int maxLayoutHeight) { 244 mMaxLayoutHeight = maxLayoutHeight; 245 } 246 247 /** 248 * Sets the last visible view of the host layout, that has a background, i.e the very last 249 * view in the shade, without the clear all button. 250 */ 251 public void setLastVisibleBackgroundChild( 252 ActivatableNotificationView lastVisibleBackgroundChild) { 253 mLastVisibleBackgroundChild = lastVisibleBackgroundChild; 254 } 255 256 public ActivatableNotificationView getLastVisibleBackgroundChild() { 257 return mLastVisibleBackgroundChild; 258 } 259 260 public void setCurrentScrollVelocity(float currentScrollVelocity) { 261 mCurrentScrollVelocity = currentScrollVelocity; 262 } 263 264 public float getCurrentScrollVelocity() { 265 return mCurrentScrollVelocity; 266 } 267 268 public boolean isOnKeyguard() { 269 return mStatusBarState == StatusBarState.KEYGUARD; 270 } 271 272 public void setStatusBarState(int statusBarState) { 273 mStatusBarState = statusBarState; 274 } 275 276 public void setExpandingVelocity(float expandingVelocity) { 277 mExpandingVelocity = expandingVelocity; 278 } 279 280 public void setExpansionChanging(boolean expansionChanging) { 281 mExpansionChanging = expansionChanging; 282 } 283 284 public boolean isExpansionChanging() { 285 return mExpansionChanging; 286 } 287 288 public float getExpandingVelocity() { 289 return mExpandingVelocity; 290 } 291 292 public void setPanelTracking(boolean panelTracking) { 293 mPanelTracking = panelTracking; 294 } 295 296 public boolean hasPulsingNotifications() { 297 return mPulsing != null; 298 } 299 300 public void setPulsing(Collection<HeadsUpManager.HeadsUpEntry> hasPulsing) { 301 mPulsing = hasPulsing; 302 } 303 304 public boolean isPulsing(NotificationData.Entry entry) { 305 if (mPulsing == null) { 306 return false; 307 } 308 for (HeadsUpManager.HeadsUpEntry e : mPulsing) { 309 if (e.entry == entry) { 310 return true; 311 } 312 } 313 return false; 314 } 315 316 public boolean isPanelTracking() { 317 return mPanelTracking; 318 } 319 320 public boolean isPanelFullWidth() { 321 return mPanelFullWidth; 322 } 323 324 public void setPanelFullWidth(boolean panelFullWidth) { 325 mPanelFullWidth = panelFullWidth; 326 } 327 328 public void setUnlockHintRunning(boolean unlockHintRunning) { 329 mUnlockHintRunning = unlockHintRunning; 330 } 331 332 public boolean isUnlockHintRunning() { 333 return mUnlockHintRunning; 334 } 335 336 public boolean isQsCustomizerShowing() { 337 return mQsCustomizerShowing; 338 } 339 340 public void setQsCustomizerShowing(boolean qsCustomizerShowing) { 341 mQsCustomizerShowing = qsCustomizerShowing; 342 } 343 344 public void setIntrinsicPadding(int intrinsicPadding) { 345 mIntrinsicPadding = intrinsicPadding; 346 } 347 348 public int getIntrinsicPadding() { 349 return mIntrinsicPadding; 350 } 351 352 /** 353 * Similar to the normal is above shelf logic but doesn't allow it to be above in AOD1. 354 * 355 * @param expandableView the view to check 356 */ 357 public boolean isAboveShelf(ExpandableView expandableView) { 358 if (!(expandableView instanceof ExpandableNotificationRow)) { 359 return expandableView.isAboveShelf(); 360 } 361 ExpandableNotificationRow row = (ExpandableNotificationRow) expandableView; 362 return row.isAboveShelf() && !isDozingAndNotPulsing(row); 363 } 364 365 /** 366 * @return whether a view is dozing and not pulsing right now 367 */ 368 public boolean isDozingAndNotPulsing(ExpandableView view) { 369 if (view instanceof ExpandableNotificationRow) { 370 return isDozingAndNotPulsing((ExpandableNotificationRow) view); 371 } 372 return false; 373 } 374 375 /** 376 * @return whether a row is dozing and not pulsing right now 377 */ 378 public boolean isDozingAndNotPulsing(ExpandableNotificationRow row) { 379 return isDark() && !isPulsing(row.getEntry()); 380 } 381 } 382