17edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock/*
27edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock * Copyright (C) 2013 The Android Open Source Project
37edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock *
47edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock * Licensed under the Apache License, Version 2.0 (the "License");
57edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock * you may not use this file except in compliance with the License.
67edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock * You may obtain a copy of the License at
77edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock *
87edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock *      http://www.apache.org/licenses/LICENSE-2.0
97edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock *
107edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock * Unless required by applicable law or agreed to in writing, software
117edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock * distributed under the License is distributed on an "AS IS" BASIS,
127edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock * See the License for the specific language governing permissions and
147edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock * limitations under the License.
157edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock */
167edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
177edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlockpackage com.android.systemui.statusbar.phone;
187edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
197edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlockimport android.content.Context;
202044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monkimport android.os.Handler;
212044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monkimport android.os.RemoteException;
227edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlockimport android.os.ServiceManager;
2340db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggiimport android.util.SparseArray;
242044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monkimport android.view.Display;
252044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monkimport android.view.IWallpaperVisibilityListener;
262044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monkimport android.view.IWindowManager;
277edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlockimport android.view.MotionEvent;
287edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlockimport android.view.View;
290e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monkimport android.view.View.OnLayoutChangeListener;
307edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
317edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlockimport com.android.internal.statusbar.IStatusBarService;
322044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monkimport com.android.systemui.Dependency;
337edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlockimport com.android.systemui.R;
347edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
357edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlockpublic final class NavigationBarTransitions extends BarTransitions {
367edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
377edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    private final NavigationBarView mView;
387edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    private final IStatusBarService mBarService;
3940db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi    private final LightBarTransitionsController mLightTransitionsController;
403107d99e54795a4fadc5448014ffe2a1f8de7ce3Matthew Ng    private final boolean mAllowAutoDimWallpaperNotVisible;
412044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk    private boolean mWallpaperVisible;
427edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
437edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    private boolean mLightsOut;
44c2beef51306e8916f481218c449b9759ce017c09Jason Monk    private boolean mAutoDim;
450e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk    private View mNavButtons;
467edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
477edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    public NavigationBarTransitions(NavigationBarView view) {
487057d2c3a9a88f1d221bc69780385bd20c5b4999John Spurlock        super(view, R.drawable.nav_background);
497edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        mView = view;
507edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        mBarService = IStatusBarService.Stub.asInterface(
517edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
52aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk        mLightTransitionsController = new LightBarTransitionsController(view.getContext(),
53aa573e9e8632552d1fa8bdd6b0ee408ff9a93a6bJason Monk                this::applyDarkIntensity);
543107d99e54795a4fadc5448014ffe2a1f8de7ce3Matthew Ng        mAllowAutoDimWallpaperNotVisible = view.getContext().getResources()
553107d99e54795a4fadc5448014ffe2a1f8de7ce3Matthew Ng                .getBoolean(R.bool.config_navigation_bar_enable_auto_dim_no_visible_wallpaper);
562044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk
572044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk        IWindowManager windowManagerService = Dependency.get(IWindowManager.class);
582044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk        Handler handler = Handler.getMain();
592044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk        try {
602044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk            mWallpaperVisible = windowManagerService.registerWallpaperVisibilityListener(
612044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk                new IWallpaperVisibilityListener.Stub() {
622044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk                    @Override
632044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk                    public void onWallpaperVisibilityChanged(boolean newVisibility,
642044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk                            int displayId) throws RemoteException {
652044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk                        mWallpaperVisible = newVisibility;
662044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk                        handler.post(() -> applyLightsOut(true, false));
672044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk                    }
682044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk                }, Display.DEFAULT_DISPLAY);
692044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk        } catch (RemoteException e) {
702044e6e3770ac3dd70b07ade58a7b8db19905a0fJason Monk        }
710e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk        mView.addOnLayoutChangeListener(
720e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk                (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
730e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk                    View currentView = mView.getCurrentView();
740e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk                    if (currentView != null) {
750e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk                        mNavButtons = currentView.findViewById(R.id.nav_buttons);
760e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk                        applyLightsOut(false, true);
770e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk                    }
780e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk                });
790e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk        View currentView = mView.getCurrentView();
800e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk        if (currentView != null) {
810e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk            mNavButtons = currentView.findViewById(R.id.nav_buttons);
820e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk        }
837edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    }
847edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
858a8ffd4e9b15a04d2af0909205658f08c76bd6b2Adrian Roos    public void init() {
86e631b41d8be2952db48df5838c6fb5d8df4645d1John Spurlock        applyModeBackground(-1, getMode(), false /*animate*/);
87c2beef51306e8916f481218c449b9759ce017c09Jason Monk        applyLightsOut(false /*animate*/, true /*force*/);
88c2beef51306e8916f481218c449b9759ce017c09Jason Monk    }
89c2beef51306e8916f481218c449b9759ce017c09Jason Monk
90c2beef51306e8916f481218c449b9759ce017c09Jason Monk    @Override
91c2beef51306e8916f481218c449b9759ce017c09Jason Monk    public void setAutoDim(boolean autoDim) {
92c2beef51306e8916f481218c449b9759ce017c09Jason Monk        if (mAutoDim == autoDim) return;
93c2beef51306e8916f481218c449b9759ce017c09Jason Monk        mAutoDim = autoDim;
94c2beef51306e8916f481218c449b9759ce017c09Jason Monk        applyLightsOut(true, false);
95c2beef51306e8916f481218c449b9759ce017c09Jason Monk    }
96c2beef51306e8916f481218c449b9759ce017c09Jason Monk
97c2beef51306e8916f481218c449b9759ce017c09Jason Monk    @Override
98c2beef51306e8916f481218c449b9759ce017c09Jason Monk    protected boolean isLightsOut(int mode) {
993107d99e54795a4fadc5448014ffe2a1f8de7ce3Matthew Ng        return super.isLightsOut(mode) || (mAllowAutoDimWallpaperNotVisible && mAutoDim
1003107d99e54795a4fadc5448014ffe2a1f8de7ce3Matthew Ng                && !mWallpaperVisible && mode != MODE_WARNING);
1017edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    }
1027edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
10340db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi    public LightBarTransitionsController getLightTransitionsController() {
10440db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi        return mLightTransitionsController;
10540db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi    }
10640db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi
1077edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    @Override
1087edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    protected void onTransition(int oldMode, int newMode, boolean animate) {
1097edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        super.onTransition(oldMode, newMode, animate);
110c2beef51306e8916f481218c449b9759ce017c09Jason Monk        applyLightsOut(animate, false /*force*/);
1117edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    }
1127edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
113c2beef51306e8916f481218c449b9759ce017c09Jason Monk    private void applyLightsOut(boolean animate, boolean force) {
1147edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        // apply to lights out
115c2beef51306e8916f481218c449b9759ce017c09Jason Monk        applyLightsOut(isLightsOut(getMode()), animate, force);
1167edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    }
1177edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
1187edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    private void applyLightsOut(boolean lightsOut, boolean animate, boolean force) {
1197edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        if (!force && lightsOut == mLightsOut) return;
1207edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
1217edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        mLightsOut = lightsOut;
1220e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk        if (mNavButtons == null) return;
1237edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
1247edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        // ok, everyone, stop it right there
1250e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk        mNavButtons.animate().cancel();
1267edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
127cdec5ff9f496e345d1e2e40f3d36d66938ace5f6Jason Monk        // Bump percentage by 10% if dark.
128cdec5ff9f496e345d1e2e40f3d36d66938ace5f6Jason Monk        float darkBump = mLightTransitionsController.getCurrentDarkIntensity() / 10;
129cdec5ff9f496e345d1e2e40f3d36d66938ace5f6Jason Monk        final float navButtonsAlpha = lightsOut ? 0.6f + darkBump : 1f;
1307edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
1317edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        if (!animate) {
1320e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk            mNavButtons.setAlpha(navButtonsAlpha);
1337edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        } else {
1347edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock            final int duration = lightsOut ? LIGHTS_OUT_DURATION : LIGHTS_IN_DURATION;
1350e3aab29ec7d05e58524b454eed2c8ebd64ee4daJason Monk            mNavButtons.animate()
1367edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                .alpha(navButtonsAlpha)
1377edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                .setDuration(duration)
1387edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                .start();
1397edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        }
1407edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    }
1417edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
14240db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi    public void reapplyDarkIntensity() {
14340db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi        applyDarkIntensity(mLightTransitionsController.getCurrentDarkIntensity());
14440db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi    }
14540db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi
14640db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi    public void applyDarkIntensity(float darkIntensity) {
14740db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi        SparseArray<ButtonDispatcher> buttonDispatchers = mView.getButtonDispatchers();
14840db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi        for (int i = buttonDispatchers.size() - 1; i >= 0; i--) {
14940db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi            buttonDispatchers.valueAt(i).setDarkIntensity(darkIntensity);
15040db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi        }
151cdec5ff9f496e345d1e2e40f3d36d66938ace5f6Jason Monk        if (mAutoDim) {
152cdec5ff9f496e345d1e2e40f3d36d66938ace5f6Jason Monk            applyLightsOut(false, true);
153cdec5ff9f496e345d1e2e40f3d36d66938ace5f6Jason Monk        }
154a8f2426df625915553c3d85af8e6241f47fdf160Matthew Ng        mView.onDarkIntensityChange(darkIntensity);
15540db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi    }
15640db029cfeb263b5b672ca687c347e58ed2ad2aeJorim Jaggi
1577edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    private final View.OnTouchListener mLightsOutListener = new View.OnTouchListener() {
1587edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        @Override
1597edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        public boolean onTouch(View v, MotionEvent ev) {
1607edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock            if (ev.getAction() == MotionEvent.ACTION_DOWN) {
1617edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                // even though setting the systemUI visibility below will turn these views
1627edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                // on, we need them to come up faster so that they can catch this motion
1637edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                // event
1647edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                applyLightsOut(false, false, false);
1657edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock
1667edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                try {
16753f28eccc546504cb1e894c02176ecce3139264eAdrian Roos                    mBarService.setSystemUiVisibility(0, View.SYSTEM_UI_FLAG_LOW_PROFILE,
16853f28eccc546504cb1e894c02176ecce3139264eAdrian Roos                            "LightsOutListener");
1697edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                } catch (android.os.RemoteException ex) {
1707edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock                }
1717edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock            }
1727edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock            return false;
1737edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock        }
1747edfbca5d00cbc376fda790b50a3fedb9c6070abJohn Spurlock    };
175af638c4f9daa74b4c8e0905f07e11290f6845abeJim Miller}
176