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