1 /*
2  * Copyright (C) 2012 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.phone;
18 
19 import android.content.Context;
20 import android.util.AttributeSet;
21 import android.util.Log;
22 import android.view.MotionEvent;
23 import android.view.View;
24 import android.widget.FrameLayout;
25 
26 public abstract class PanelBar extends FrameLayout {
27     public static final boolean DEBUG = false;
28     public static final String TAG = PanelBar.class.getSimpleName();
29     private static final boolean SPEW = false;
30     private boolean mBouncerShowing;
31     private boolean mExpanded;
32 
LOG(String fmt, Object... args)33     public static final void LOG(String fmt, Object... args) {
34         if (!DEBUG) return;
35         Log.v(TAG, String.format(fmt, args));
36     }
37 
38     public static final int STATE_CLOSED = 0;
39     public static final int STATE_OPENING = 1;
40     public static final int STATE_OPEN = 2;
41 
42     PanelView mPanel;
43     private int mState = STATE_CLOSED;
44     private boolean mTracking;
45 
go(int state)46     public void go(int state) {
47         if (DEBUG) LOG("go state: %d -> %d", mState, state);
48         mState = state;
49     }
50 
getState()51     public int getState() {
52         return mState;
53     }
54 
PanelBar(Context context, AttributeSet attrs)55     public PanelBar(Context context, AttributeSet attrs) {
56         super(context, attrs);
57     }
58 
59     @Override
onFinishInflate()60     protected void onFinishInflate() {
61         super.onFinishInflate();
62     }
63 
setPanel(PanelView pv)64     public void setPanel(PanelView pv) {
65         mPanel = pv;
66         pv.setBar(this);
67     }
68 
setBouncerShowing(boolean showing)69     public void setBouncerShowing(boolean showing) {
70         mBouncerShowing = showing;
71         int important = showing ? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
72                 : IMPORTANT_FOR_ACCESSIBILITY_AUTO;
73 
74         setImportantForAccessibility(important);
75         updateVisibility();
76 
77         if (mPanel != null) mPanel.setImportantForAccessibility(important);
78     }
79 
updateVisibility()80     private void updateVisibility() {
81         mPanel.setVisibility(mExpanded || mBouncerShowing ? VISIBLE : INVISIBLE);
82     }
83 
panelEnabled()84     public boolean panelEnabled() {
85         return true;
86     }
87 
88     @Override
onTouchEvent(MotionEvent event)89     public boolean onTouchEvent(MotionEvent event) {
90         // Allow subclasses to implement enable/disable semantics
91         if (!panelEnabled()) {
92             if (event.getAction() == MotionEvent.ACTION_DOWN) {
93                 Log.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)",
94                         (int) event.getX(), (int) event.getY()));
95             }
96             return false;
97         }
98 
99         if (event.getAction() == MotionEvent.ACTION_DOWN) {
100             final PanelView panel = mPanel;
101             if (panel == null) {
102                 // panel is not there, so we'll eat the gesture
103                 Log.v(TAG, String.format("onTouch: no panel for touch at (%d,%d)",
104                         (int) event.getX(), (int) event.getY()));
105                 return true;
106             }
107             boolean enabled = panel.isEnabled();
108             if (DEBUG) LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %s %s", mState, panel,
109                     (enabled ? "" : " (disabled)"));
110             if (!enabled) {
111                 // panel is disabled, so we'll eat the gesture
112                 Log.v(TAG, String.format(
113                         "onTouch: panel (%s) is disabled, ignoring touch at (%d,%d)",
114                         panel, (int) event.getX(), (int) event.getY()));
115                 return true;
116             }
117         }
118         return mPanel == null || mPanel.onTouchEvent(event);
119     }
120 
panelScrimMinFractionChanged(float minFraction)121     public abstract void panelScrimMinFractionChanged(float minFraction);
122 
123     /**
124      * @param frac the fraction from the expansion in [0, 1]
125      * @param expanded whether the panel is currently expanded; this is independent from the
126      *                 fraction as the panel also might be expanded if the fraction is 0
127      */
panelExpansionChanged(float frac, boolean expanded)128     public void panelExpansionChanged(float frac, boolean expanded) {
129         boolean fullyClosed = true;
130         boolean fullyOpened = false;
131         if (SPEW) LOG("panelExpansionChanged: start state=%d", mState);
132         PanelView pv = mPanel;
133         mExpanded = expanded;
134         updateVisibility();
135         // adjust any other panels that may be partially visible
136         if (expanded) {
137             if (mState == STATE_CLOSED) {
138                 go(STATE_OPENING);
139                 onPanelPeeked();
140             }
141             fullyClosed = false;
142             final float thisFrac = pv.getExpandedFraction();
143             if (SPEW) LOG("panelExpansionChanged:  -> %s: f=%.1f", pv.getName(), thisFrac);
144             fullyOpened = thisFrac >= 1f;
145         }
146         if (fullyOpened && !mTracking) {
147             go(STATE_OPEN);
148             onPanelFullyOpened();
149         } else if (fullyClosed && !mTracking && mState != STATE_CLOSED) {
150             go(STATE_CLOSED);
151             onPanelCollapsed();
152         }
153 
154         if (SPEW) LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
155                 fullyOpened?" fullyOpened":"", fullyClosed?" fullyClosed":"");
156     }
157 
collapsePanel(boolean animate, boolean delayed, float speedUpFactor)158     public void collapsePanel(boolean animate, boolean delayed, float speedUpFactor) {
159         boolean waiting = false;
160         PanelView pv = mPanel;
161         if (animate && !pv.isFullyCollapsed()) {
162             pv.collapse(delayed, speedUpFactor);
163             waiting = true;
164         } else {
165             pv.resetViews();
166             pv.setExpandedFraction(0); // just in case
167             pv.cancelPeek();
168         }
169         if (DEBUG) LOG("collapsePanel: animate=%s waiting=%s", animate, waiting);
170         if (!waiting && mState != STATE_CLOSED) {
171             // it's possible that nothing animated, so we replicate the termination
172             // conditions of panelExpansionChanged here
173             go(STATE_CLOSED);
174             onPanelCollapsed();
175         }
176     }
177 
onPanelPeeked()178     public void onPanelPeeked() {
179         if (DEBUG) LOG("onPanelPeeked");
180     }
181 
isClosed()182     public boolean isClosed() {
183         return mState == STATE_CLOSED;
184     }
185 
onPanelCollapsed()186     public void onPanelCollapsed() {
187         if (DEBUG) LOG("onPanelCollapsed");
188     }
189 
onPanelFullyOpened()190     public void onPanelFullyOpened() {
191         if (DEBUG) LOG("onPanelFullyOpened");
192     }
193 
onTrackingStarted()194     public void onTrackingStarted() {
195         mTracking = true;
196     }
197 
onTrackingStopped(boolean expand)198     public void onTrackingStopped(boolean expand) {
199         mTracking = false;
200     }
201 
onExpandingFinished()202     public void onExpandingFinished() {
203         if (DEBUG) LOG("onExpandingFinished");
204     }
205 
onClosingFinished()206     public void onClosingFinished() {
207 
208     }
209 }
210