NavigationBarTransitions.java revision ea56251d92050e9a672d1f66d0d4621e4dd4136e
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 || mode == MODE_TRANSPARENT)) {
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
86        applyBackButtonQuiescentAlpha(mode, animate);
87
88        // apply to lights out
89        applyLightsOut(mode == MODE_LIGHTS_OUT, animate, force);
90    }
91
92    private float alphaForMode(int mode) {
93        final boolean isOpaque = mode == MODE_OPAQUE || mode == MODE_LIGHTS_OUT;
94        return isOpaque ? KeyButtonView.DEFAULT_QUIESCENT_ALPHA : 1f;
95    }
96
97    public void applyBackButtonQuiescentAlpha(int mode, boolean animate) {
98        float backAlpha = 0;
99        backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getSearchLight());
100        backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getHomeButton());
101        backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getRecentsButton());
102        backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getMenuButton());
103        if (backAlpha > 0) {
104            setKeyButtonViewQuiescentAlpha(mView.getBackButton(), backAlpha, animate);
105        }
106    }
107
108    private static float maxVisibleQuiescentAlpha(float max, View v) {
109        if ((v instanceof KeyButtonView) && v.isShown()) {
110            return Math.max(max, ((KeyButtonView)v).getQuiescentAlpha());
111        }
112        return max;
113    }
114
115    @Override
116    public void setContentVisible(boolean visible) {
117        final float alpha = visible ? 1 : 0;
118        fadeContent(mView.getBackButton(), alpha);
119        fadeContent(mView.getSearchLight(), alpha);
120    }
121
122    private void fadeContent(View v, float alpha) {
123        if (v != null) {
124            v.animate().alpha(alpha).setDuration(CONTENT_FADE_DURATION);
125        }
126    }
127
128    private void setKeyButtonViewQuiescentAlpha(View button, float alpha, boolean animate) {
129        if (button instanceof KeyButtonView) {
130            ((KeyButtonView) button).setQuiescentAlpha(alpha, animate);
131        }
132    }
133
134    private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
135        if (!force && lightsOut == mLightsOut) return;
136
137        mLightsOut = lightsOut;
138
139        final View navButtons = mView.getCurrentView().findViewById(R.id.nav_buttons);
140        final View lowLights = mView.getCurrentView().findViewById(R.id.lights_out);
141
142        // ok, everyone, stop it right there
143        navButtons.animate().cancel();
144        lowLights.animate().cancel();
145
146        final float navButtonsAlpha = lightsOut ? 0f : 1f;
147        final float lowLightsAlpha = lightsOut ? 1f : 0f;
148
149        if (!animate) {
150            navButtons.setAlpha(navButtonsAlpha);
151            lowLights.setAlpha(lowLightsAlpha);
152            lowLights.setVisibility(lightsOut ? View.VISIBLE : View.GONE);
153        } else {
154            final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION;
155            navButtons.animate()
156                .alpha(navButtonsAlpha)
157                .setDuration(duration)
158                .start();
159
160            lowLights.setOnTouchListener(mLightsOutListener);
161            if (lowLights.getVisibility() == View.GONE) {
162                lowLights.setAlpha(0f);
163                lowLights.setVisibility(View.VISIBLE);
164            }
165            lowLights.animate()
166                .alpha(lowLightsAlpha)
167                .setDuration(duration)
168                .setInterpolator(new AccelerateInterpolator(2.0f))
169                .setListener(lightsOut ? null : new AnimatorListenerAdapter() {
170                    @Override
171                    public void onAnimationEnd(Animator _a) {
172                        lowLights.setVisibility(View.GONE);
173                    }
174                })
175                .start();
176        }
177    }
178
179    private final View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
180        @Override
181        public boolean onTouch(View v, MotionEvent ev) {
182            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
183                // even though setting the systemUI visibility below will turn these views
184                // on, we need them to come up faster so that they can catch this motion
185                // event
186                applyLightsOut(false, false, false);
187
188                try {
189                    mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE);
190                } catch (android.os.RemoteException ex) {
191                }
192            }
193            return false;
194        }
195    };
196}
197