Home | History | Annotate | Download | only in stack
      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