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