136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam/*
236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * Copyright (C) 2015 The Android Open Source Project
336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam *
436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * Licensed under the Apache License, Version 2.0 (the "License");
536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * you may not use this file except in compliance with the License.
636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * You may obtain a copy of the License at
736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam *
836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam *      http://www.apache.org/licenses/LICENSE-2.0
936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam *
1036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * Unless required by applicable law or agreed to in writing, software
1136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * distributed under the License is distributed on an "AS IS" BASIS,
1236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * See the License for the specific language governing permissions and
1436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * limitations under the License.
1536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam */
1636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
1736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lampackage com.android.setupwizardlib.util;
1836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
19b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lamimport android.annotation.SuppressLint;
2036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport android.annotation.TargetApi;
2136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport android.app.Dialog;
2236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport android.content.Context;
23b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lamimport android.os.Build.VERSION;
24b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lamimport android.os.Build.VERSION_CODES;
2536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport android.os.Handler;
2636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport android.view.View;
2736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport android.view.ViewGroup;
2836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport android.view.Window;
2936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport android.view.WindowInsets;
3036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport android.view.WindowManager;
3136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
3236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lamimport com.android.setupwizardlib.R;
3336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
3436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam/**
3536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * A helper class to manage the system navigation bar and status bar. This will add various
3636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * systemUiVisibility flags to the given Window or View to make them follow the Setup Wizard style.
3736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam *
3836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * When the useImmersiveMode intent extra is true, a screen in Setup Wizard should hide the system
3936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * bars using methods from this class. For Lollipop, {@link #hideSystemBars(android.view.Window)}
4036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * will completely hide the system navigation bar and change the status bar to transparent, and
4136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam * layout the screen contents (usually the illustration) behind it.
4236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam */
4336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lampublic class SystemBarHelper {
4436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
45b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam    @SuppressLint("InlinedApi")
4636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    private static final int DEFAULT_IMMERSIVE_FLAGS =
4736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
4836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
4936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
5036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION;
5136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
526be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam    @SuppressLint("InlinedApi")
536be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam    private static final int DIALOG_IMMERSIVE_FLAGS =
546be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam            View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
556be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam            | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
566be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam
5736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
5836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * Needs to be equal to View.STATUS_BAR_DISABLE_BACK
5936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
6036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    private static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
6136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
6236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
6336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * Hide the navigation bar for a dialog.
64b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam     *
65b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam     * This will only take effect in versions Lollipop or above. Otherwise this is a no-op.
6636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
6736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    public static void hideSystemBars(final Dialog dialog) {
68b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
69b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            final Window window = dialog.getWindow();
70b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            temporarilyDisableDialogFocus(window);
716be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam            addImmersiveFlagsToWindow(window, DIALOG_IMMERSIVE_FLAGS);
726be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam            addImmersiveFlagsToDecorView(window, new Handler(), DIALOG_IMMERSIVE_FLAGS);
73b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        }
7436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
7536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
7636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
7736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * Hide the navigation bar, and make the color of the status and navigation bars transparent,
7836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * and specify the LAYOUT_FULLSCREEN flag so that the content is laid-out behind the transparent
7936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * status bar. This is commonly used with Activity.getWindow() to make the navigation and status
8036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * bars follow the Setup Wizard style.
81b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam     *
82b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam     * This will only take effect in versions Lollipop or above. Otherwise this is a no-op.
8336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
8436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    public static void hideSystemBars(final Window window) {
85b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
866be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam            addImmersiveFlagsToWindow(window, DEFAULT_IMMERSIVE_FLAGS);
876be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam            addImmersiveFlagsToDecorView(window, new Handler(), DEFAULT_IMMERSIVE_FLAGS);
88b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        }
8936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
9036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
9136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
9236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * Convenience method to add a visibility flag in addition to the existing ones.
9336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
9436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    public static void addVisibilityFlag(final View view, final int flag) {
95b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
96b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            final int vis = view.getSystemUiVisibility();
97b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            view.setSystemUiVisibility(vis | flag);
98b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        }
9936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
10036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
10136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
10236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * Convenience method to add a visibility flag in addition to the existing ones.
10336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
10436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    public static void addVisibilityFlag(final Window window, final int flag) {
105b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
106b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            WindowManager.LayoutParams attrs = window.getAttributes();
107b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            attrs.systemUiVisibility |= flag;
108b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            window.setAttributes(attrs);
109b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        }
11036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
11136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
11236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
11336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * Convenience method to remove a visibility flag from the view, leaving other flags that are
11436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * not specified intact.
11536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
11636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    public static void removeVisibilityFlag(final View view, final int flag) {
117b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
118b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            final int vis = view.getSystemUiVisibility();
119b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            view.setSystemUiVisibility(vis & ~flag);
120b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        }
12136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
12236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
12336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
12436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * Convenience method to remove a visibility flag from the window, leaving other flags that are
12536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * not specified intact.
12636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
12736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    public static void removeVisibilityFlag(final Window window, final int flag) {
128b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
129b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            WindowManager.LayoutParams attrs = window.getAttributes();
130b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            attrs.systemUiVisibility &= ~flag;
131b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            window.setAttributes(attrs);
132b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        }
13336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
13436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
13536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    public static void setBackButtonVisible(final Window window, final boolean visible) {
136b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB) {
137b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            if (visible) {
138b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam                removeVisibilityFlag(window, STATUS_BAR_DISABLE_BACK);
139e96ec75d23e82b352ab1393dbac8d6372ceb62d7Maurice Lam            } else {
140e96ec75d23e82b352ab1393dbac8d6372ceb62d7Maurice Lam                addVisibilityFlag(window, STATUS_BAR_DISABLE_BACK);
141b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            }
14236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        }
14336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
14436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
14536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
14636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * Set a view to be resized when the keyboard is shown. This will set the bottom margin of the
14736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * view to be immediately above the keyboard, and assumes that the view sits immediately above
14836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * the navigation bar.
14936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     *
1508fc85be65673f6ec8b3202d8b3fc644a3adeededMaurice Lam     * Note that you must set windowSoftInputMode to adjustResize for this class to work. Otherwise
1518fc85be65673f6ec8b3202d8b3fc644a3adeededMaurice Lam     * window insets are not dispatched and this method will have no effect.
1528fc85be65673f6ec8b3202d8b3fc644a3adeededMaurice Lam     *
153b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam     * This will only take effect in versions Lollipop or above. Otherwise this is a no-op.
154b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam     *
15536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * @param view The view to be resized when the keyboard is shown.
15636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
15736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    public static void setImeInsetView(final View view) {
158b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
159b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam            view.setOnApplyWindowInsetsListener(new WindowInsetsListener(view.getContext()));
160b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam        }
16136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
16236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
16336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
16436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN only takes effect when it is added a view instead of
16536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * the window.
16636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
167b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam    @TargetApi(VERSION_CODES.LOLLIPOP)
1686be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam    private static void addImmersiveFlagsToDecorView(final Window window, final Handler handler,
1696be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam            final int vis) {
17036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        // Use peekDecorView instead of getDecorView so that clients can still set window features
17136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        // after calling this method.
17236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        final View decorView = window.peekDecorView();
17336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        if (decorView != null) {
1746be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam            addVisibilityFlag(decorView, vis);
17536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        } else {
17636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            // If the decor view is not installed yet, try again in the next loop.
17736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            handler.post(new Runnable() {
17836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                @Override
17936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                public void run() {
1806be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam                    addImmersiveFlagsToDecorView(window, handler, vis);
18136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                }
18236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            });
18336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        }
18436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
18536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
186b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam    @TargetApi(VERSION_CODES.LOLLIPOP)
1876be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam    private static void addImmersiveFlagsToWindow(final Window window, final int vis) {
18836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        WindowManager.LayoutParams attrs = window.getAttributes();
1896be36beb1bdcd9211c504bbb1647d1f610ba2185Maurice Lam        attrs.systemUiVisibility |= vis;
19036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        window.setAttributes(attrs);
19136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
19236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        // Also set the navigation bar and status bar to transparent color. Note that this doesn't
19336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        // work on some devices.
19436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        window.setNavigationBarColor(0);
19536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        window.setStatusBarColor(0);
19636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
19736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
19836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    /**
19936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * Apply a hack to temporarily set the window to not focusable, so that the navigation bar
20036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     * will not show up during the transition.
20136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam     */
20236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    private static void temporarilyDisableDialogFocus(final Window window) {
20336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        window.setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
20436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
20535ef4eb340353962f23cab81a33b2ddbdfce1da7Maurice Lam        // Add the SOFT_INPUT_IS_FORWARD_NAVIGATION_FLAG. This is normally done by the system when
20635ef4eb340353962f23cab81a33b2ddbdfce1da7Maurice Lam        // FLAG_NOT_FOCUSABLE is not set. Setting this flag allows IME to be shown automatically
20735ef4eb340353962f23cab81a33b2ddbdfce1da7Maurice Lam        // if the dialog has editable text fields.
20835ef4eb340353962f23cab81a33b2ddbdfce1da7Maurice Lam        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION);
20936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        new Handler().post(new Runnable() {
21036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            @Override
21136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            public void run() {
21236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
21336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            }
21436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        });
21536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
21636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
217b8f3330e8be7da2f141b65967ecf3a2bad4e02a4Maurice Lam    @TargetApi(VERSION_CODES.LOLLIPOP)
21836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    private static class WindowInsetsListener implements View.OnApplyWindowInsetsListener {
21936ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
22036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        private int mNavigationBarHeight;
22136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
22236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        public WindowInsetsListener(Context context) {
22336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            mNavigationBarHeight =
22436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                    context.getResources().getDimensionPixelSize(R.dimen.suw_navbar_height);
22536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        }
22636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
22736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        @Override
22836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) {
2293c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam            int bottomInset = insets.getSystemWindowInsetBottom();
23036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
23136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            final int bottomMargin = Math.max(
23236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                    insets.getSystemWindowInsetBottom() - mNavigationBarHeight, 0);
23336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
2343c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam            final ViewGroup.MarginLayoutParams lp =
2353c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam                    (ViewGroup.MarginLayoutParams) view.getLayoutParams();
2363c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam            // Check that we have enough space to apply the bottom margins before applying it.
2373c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam            // Otherwise the framework may think that the view is empty and exclude it from layout.
2383c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam            if (bottomMargin < lp.bottomMargin + view.getHeight()) {
2393c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam                lp.setMargins(lp.leftMargin, lp.topMargin, lp.rightMargin, bottomMargin);
2403c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam                view.setLayoutParams(lp);
2413c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam                bottomInset = 0;
2423c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam            }
2433c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam
24436ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam
24536ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            return insets.replaceSystemWindowInsets(
24636ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                    insets.getSystemWindowInsetLeft(),
24736ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                    insets.getSystemWindowInsetTop(),
24836ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam                    insets.getSystemWindowInsetRight(),
2493c154790e7c6668c60237bcde0fc6f5fa22884b0Maurice Lam                    bottomInset
25036ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam            );
25136ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam        }
25236ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam    }
25336ef34ddf66b59ff1bbe96c0f4633fb0b2af4fadMaurice Lam}
254