1/* 2 * Copyright (C) 2013 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 17package com.android.systemui.statusbar.phone; 18 19import android.animation.Animator; 20import android.animation.AnimatorListenerAdapter; 21import android.content.Context; 22import android.os.ServiceManager; 23import android.view.MotionEvent; 24import android.view.View; 25import android.view.animation.AccelerateInterpolator; 26 27import com.android.internal.statusbar.IStatusBarService; 28import com.android.systemui.R; 29import com.android.systemui.statusbar.policy.KeyButtonView; 30 31public final class NavigationBarTransitions extends BarTransitions { 32 33 private static final int CONTENT_FADE_DURATION = 200; 34 35 private final NavigationBarView mView; 36 private final IStatusBarService mBarService; 37 38 private boolean mLightsOut; 39 private boolean mVertical; 40 private int mRequestedMode; 41 42 public NavigationBarTransitions(NavigationBarView view) { 43 super(view, R.drawable.nav_background); 44 mView = view; 45 mBarService = IStatusBarService.Stub.asInterface( 46 ServiceManager.getService(Context.STATUS_BAR_SERVICE)); 47 } 48 49 public void init(boolean isVertical) { 50 setVertical(isVertical); 51 applyModeBackground(-1, getMode(), false /*animate*/); 52 applyMode(getMode(), false /*animate*/, true /*force*/); 53 } 54 55 public void setVertical(boolean isVertical) { 56 mVertical = isVertical; 57 transitionTo(mRequestedMode, false /*animate*/); 58 } 59 60 @Override 61 public void transitionTo(int mode, boolean animate) { 62 mRequestedMode = mode; 63 if (mVertical && (mode == MODE_TRANSLUCENT || mode == MODE_TRANSPARENT)) { 64 // translucent mode not allowed when vertical 65 mode = MODE_OPAQUE; 66 } 67 super.transitionTo(mode, animate); 68 } 69 70 @Override 71 protected void onTransition(int oldMode, int newMode, boolean animate) { 72 super.onTransition(oldMode, newMode, animate); 73 applyMode(newMode, animate, false /*force*/); 74 } 75 76 private void applyMode(int mode, boolean animate, boolean force) { 77 // apply to key buttons 78 final float alpha = alphaForMode(mode); 79 setKeyButtonViewQuiescentAlpha(mView.getHomeButton(), alpha, animate); 80 setKeyButtonViewQuiescentAlpha(mView.getRecentsButton(), alpha, animate); 81 setKeyButtonViewQuiescentAlpha(mView.getMenuButton(), alpha, animate); 82 setKeyButtonViewQuiescentAlpha(mView.getImeSwitchButton(), alpha, animate); 83 84 applyBackButtonQuiescentAlpha(mode, animate); 85 86 // apply to lights out 87 applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force); 88 } 89 90 private float alphaForMode(int mode) { 91 final boolean isOpaque = mode == MODE_OPAQUE || mode == MODE_LIGHTS_OUT; 92 return isOpaque ? KeyButtonView.DEFAULT_QUIESCENT_ALPHA : 1f; 93 } 94 95 public void applyBackButtonQuiescentAlpha(int mode, boolean animate) { 96 float backAlpha = 0; 97 backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getHomeButton()); 98 backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getRecentsButton()); 99 backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getMenuButton()); 100 backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getImeSwitchButton()); 101 if (backAlpha > 0) { 102 setKeyButtonViewQuiescentAlpha(mView.getBackButton(), backAlpha, animate); 103 } 104 } 105 106 private static float maxVisibleQuiescentAlpha(float max, View v) { 107 if ((v instanceof KeyButtonView) && v.isShown()) { 108 return Math.max(max, ((KeyButtonView)v).getQuiescentAlpha()); 109 } 110 return max; 111 } 112 113 private void setKeyButtonViewQuiescentAlpha(View button, float alpha, boolean animate) { 114 if (button instanceof KeyButtonView) { 115 ((KeyButtonView) button).setQuiescentAlpha(alpha, animate); 116 } 117 } 118 119 private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) { 120 if (!force && lightsOut == mLightsOut) return; 121 122 mLightsOut = lightsOut; 123 124 final View navButtons = mView.getCurrentView().findViewById(R.id.nav_buttons); 125 final View lowLights = mView.getCurrentView().findViewById(R.id.lights_out); 126 127 // ok, everyone, stop it right there 128 navButtons.animate().cancel(); 129 lowLights.animate().cancel(); 130 131 final float navButtonsAlpha = lightsOut ? 0f : 1f; 132 final float lowLightsAlpha = lightsOut ? 1f : 0f; 133 134 if (!animate) { 135 navButtons.setAlpha(navButtonsAlpha); 136 lowLights.setAlpha(lowLightsAlpha); 137 lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE); 138 } else { 139 final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION; 140 navButtons.animate() 141 .alpha(navButtonsAlpha) 142 .setDuration(duration) 143 .start(); 144 145 lowLights.setOnTouchListener(mLightsOutListener); 146 if (lowLights.getVisibility() == View.GONE) { 147 lowLights.setAlpha(0f); 148 lowLights.setVisibility(View.VISIBLE); 149 } 150 lowLights.animate() 151 .alpha(lowLightsAlpha) 152 .setDuration(duration) 153 .setInterpolator(new AccelerateInterpolator(2.0f)) 154 .setListener(lightsOut ? null : new AnimatorListenerAdapter() { 155 @Override 156 public void onAnimationEnd(Animator _a) { 157 lowLights.setVisibility(View.GONE); 158 } 159 }) 160 .start(); 161 } 162 } 163 164 private final View.OnTouchListener mLightsOutListener = new View.OnTouchListener() { 165 @Override 166 public boolean onTouch(View v, MotionEvent ev) { 167 if (ev.getAction() == MotionEvent.ACTION_DOWN) { 168 // even though setting the systemUI visibility below will turn these views 169 // on, we need them to come up faster so that they can catch this motion 170 // event 171 applyLightsOut(false, false, false); 172 173 try { 174 mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE); 175 } catch (android.os.RemoteException ex) { 176 } 177 } 178 return false; 179 } 180 }; 181} 182