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