• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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.animation.Animator;
20 import android.animation.AnimatorListenerAdapter;
21 import android.content.Context;
22 import android.content.res.Resources;
23 import android.os.ServiceManager;
24 import android.util.AttributeSet;
25 import android.util.Slog;
26 import android.view.animation.AccelerateInterpolator;
27 import android.view.Display;
28 import android.view.MotionEvent;
29 import android.view.View;
30 import android.view.ViewGroup;
31 import android.view.Surface;
32 import android.view.WindowManager;
33 import android.widget.LinearLayout;
34 
35 import com.android.internal.statusbar.IStatusBarService;
36 
37 import com.android.systemui.R;
38 
39 public class NavigationBarView extends LinearLayout {
40     final static boolean DEBUG = false;
41     final static String TAG = "PhoneStatusBar/NavigationBarView";
42 
43     final static boolean DEBUG_DEADZONE = false;
44 
45     final static boolean NAVBAR_ALWAYS_AT_RIGHT = true;
46 
47     final static boolean ANIMATE_HIDE_TRANSITION = false; // turned off because it introduces unsightly delay when videos goes to full screen
48 
49     protected IStatusBarService mBarService;
50     final Display mDisplay;
51     View mCurrentView = null;
52     View[] mRotatedViews = new View[4];
53 
54     int mBarSize;
55     boolean mVertical;
56 
57     boolean mHidden, mLowProfile, mShowMenu;
58     int mDisabledFlags = 0;
59 
getRecentsButton()60     public View getRecentsButton() {
61         return mCurrentView.findViewById(R.id.recent_apps);
62     }
63 
getMenuButton()64     public View getMenuButton() {
65         return mCurrentView.findViewById(R.id.menu);
66     }
67 
getBackButton()68     public View getBackButton() {
69         return mCurrentView.findViewById(R.id.back);
70     }
71 
getHomeButton()72     public View getHomeButton() {
73         return mCurrentView.findViewById(R.id.home);
74     }
75 
NavigationBarView(Context context, AttributeSet attrs)76     public NavigationBarView(Context context, AttributeSet attrs) {
77         super(context, attrs);
78 
79         mHidden = false;
80 
81         mDisplay = ((WindowManager)context.getSystemService(
82                 Context.WINDOW_SERVICE)).getDefaultDisplay();
83         mBarService = IStatusBarService.Stub.asInterface(
84                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
85 
86         final Resources res = mContext.getResources();
87         mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
88         mVertical = false;
89         mShowMenu = false;
90     }
91 
92     View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
93         @Override
94         public boolean onTouch(View v, MotionEvent ev) {
95             if (ev.getAction() == MotionEvent.ACTION_DOWN) {
96                 // even though setting the systemUI visibility below will turn these views
97                 // on, we need them to come up faster so that they can catch this motion
98                 // event
99                 setLowProfile(false, false, false);
100 
101                 try {
102                     mBarService.setSystemUiVisibility(0);
103                 } catch (android.os.RemoteException ex) {
104                 }
105             }
106             return false;
107         }
108     };
109 
setDisabledFlags(int disabledFlags)110     public void setDisabledFlags(int disabledFlags) {
111         setDisabledFlags(disabledFlags, false);
112     }
113 
setDisabledFlags(int disabledFlags, boolean force)114     public void setDisabledFlags(int disabledFlags, boolean force) {
115         if (!force && mDisabledFlags == disabledFlags) return;
116 
117         mDisabledFlags = disabledFlags;
118 
119         final boolean disableHome = ((disabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
120         final boolean disableRecent = ((disabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0);
121         final boolean disableBack = ((disabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0);
122 
123         getBackButton()   .setVisibility(disableBack       ? View.INVISIBLE : View.VISIBLE);
124         getHomeButton()   .setVisibility(disableHome       ? View.INVISIBLE : View.VISIBLE);
125         getRecentsButton().setVisibility(disableRecent     ? View.INVISIBLE : View.VISIBLE);
126     }
127 
setMenuVisibility(final boolean show)128     public void setMenuVisibility(final boolean show) {
129         setMenuVisibility(show, false);
130     }
131 
setMenuVisibility(final boolean show, final boolean force)132     public void setMenuVisibility(final boolean show, final boolean force) {
133         if (!force && mShowMenu == show) return;
134 
135         mShowMenu = show;
136 
137         getMenuButton().setVisibility(mShowMenu ? View.VISIBLE : View.INVISIBLE);
138     }
139 
setLowProfile(final boolean lightsOut)140     public void setLowProfile(final boolean lightsOut) {
141         setLowProfile(lightsOut, true, false);
142     }
143 
setLowProfile(final boolean lightsOut, final boolean animate, final boolean force)144     public void setLowProfile(final boolean lightsOut, final boolean animate, final boolean force) {
145         if (!force && lightsOut == mLowProfile) return;
146 
147         mLowProfile = lightsOut;
148 
149         if (DEBUG) Slog.d(TAG, "setting lights " + (lightsOut?"out":"on"));
150 
151         final View navButtons = mCurrentView.findViewById(R.id.nav_buttons);
152         final View lowLights = mCurrentView.findViewById(R.id.lights_out);
153 
154         // ok, everyone, stop it right there
155         navButtons.animate().cancel();
156         lowLights.animate().cancel();
157 
158         if (!animate) {
159             navButtons.setAlpha(lightsOut ? 0f : 1f);
160 
161             lowLights.setAlpha(lightsOut ? 1f : 0f);
162             lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE);
163         } else {
164             navButtons.animate()
165                 .alpha(lightsOut ? 0f : 1f)
166                 .setDuration(lightsOut ? 600 : 200)
167                 .start();
168 
169             lowLights.setOnTouchListener(mLightsOutListener);
170             if (lowLights.getVisibility() == View.GONE) {
171                 lowLights.setAlpha(0f);
172                 lowLights.setVisibility(View.VISIBLE);
173             }
174             lowLights.animate()
175                 .alpha(lightsOut ? 1f : 0f)
176                 .setStartDelay(lightsOut ? 500 : 0)
177                 .setDuration(lightsOut ? 1000 : 300)
178                 .setInterpolator(new AccelerateInterpolator(2.0f))
179                 .setListener(lightsOut ? null : new AnimatorListenerAdapter() {
180                     @Override
181                     public void onAnimationEnd(Animator _a) {
182                         lowLights.setVisibility(View.GONE);
183                     }
184                 })
185                 .start();
186         }
187     }
188 
setHidden(final boolean hide)189     public void setHidden(final boolean hide) {
190         if (hide == mHidden) return;
191 
192         mHidden = hide;
193         Slog.d(TAG,
194             (hide ? "HIDING" : "SHOWING") + " navigation bar");
195 
196         // bring up the lights no matter what
197         setLowProfile(false);
198     }
199 
onFinishInflate()200     public void onFinishInflate() {
201         mRotatedViews[Surface.ROTATION_0] =
202         mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
203 
204         mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);
205 
206         mRotatedViews[Surface.ROTATION_270] = NAVBAR_ALWAYS_AT_RIGHT
207                                                 ? findViewById(R.id.rot90)
208                                                 : findViewById(R.id.rot270);
209 
210         for (View v : mRotatedViews) {
211             // this helps avoid drawing artifacts with glowing navigation keys
212             ViewGroup group = (ViewGroup) v.findViewById(R.id.nav_buttons);
213             group.setMotionEventSplittingEnabled(false);
214         }
215         mCurrentView = mRotatedViews[Surface.ROTATION_0];
216     }
217 
reorient()218     public void reorient() {
219         final int rot = mDisplay.getRotation();
220         for (int i=0; i<4; i++) {
221             mRotatedViews[i].setVisibility(View.GONE);
222         }
223         mCurrentView = mRotatedViews[rot];
224         mCurrentView.setVisibility(View.VISIBLE);
225         mVertical = (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270);
226 
227         // force the low profile & disabled states into compliance
228         setLowProfile(mLowProfile, false, true /* force */);
229         setDisabledFlags(mDisabledFlags, true /* force */);
230         setMenuVisibility(mShowMenu, true /* force */);
231 
232         if (DEBUG_DEADZONE) {
233             mCurrentView.findViewById(R.id.deadzone).setBackgroundColor(0x808080FF);
234         }
235 
236         if (DEBUG) {
237             Slog.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
238         }
239     }
240 }
241