From eca20d733dec826374879e73c91eab8ea8706ac9 Mon Sep 17 00:00:00 2001 From: Marcello Albano Date: Mon, 4 May 2020 14:26:12 -0700 Subject: Created ImmersiveModeHelper The immersive mode helper changes the static approach of CarSetupWizardUiUtils offering the same functionalities. It allows to enable/disable the window immersive mode handling the colors for nav and status bar. Bug: 153369700 Test: `atest ImmersiveModeHelperTest` Change-Id: Id8e22898053d803630b3113d2eb277693ed1e842 Merged-In: Id8e22898053d803630b3113d2eb277693ed1e842 --- .../setupwizardlib/util/CarSetupWizardUiUtils.java | 8 +- .../setupwizardlib/util/ImmersiveModeHelper.java | 98 ++++++++++++++++++++++ .../util/ImmersiveModeHelperTest.java | 98 ++++++++++++++++++++++ 3 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 library/main/src/com/android/car/setupwizardlib/util/ImmersiveModeHelper.java create mode 100644 library/main/tests/robotests/src/com/android/car/setupwizardlib/util/ImmersiveModeHelperTest.java diff --git a/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java b/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java index b459c4e..0e56893 100644 --- a/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java +++ b/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java @@ -23,7 +23,13 @@ import android.view.Window; import androidx.core.util.Preconditions; -/** Utilities to aid in UI for car setup wizard flow. */ +/** + * Utilities to aid in UI for car setup wizard flow. + * + * @deprecated This class has been deprecated in favour of {@link ImmersiveModeHelper} that offers + * the same functionalities without the static approach. + */ +@Deprecated public final class CarSetupWizardUiUtils { private static final String TAG = CarSetupWizardUiUtils.class.getSimpleName(); diff --git a/library/main/src/com/android/car/setupwizardlib/util/ImmersiveModeHelper.java b/library/main/src/com/android/car/setupwizardlib/util/ImmersiveModeHelper.java new file mode 100644 index 0000000..fd6aad3 --- /dev/null +++ b/library/main/src/com/android/car/setupwizardlib/util/ImmersiveModeHelper.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.car.setupwizardlib.util; + +import android.graphics.Color; +import android.util.Log; +import android.view.View; +import android.view.Window; + +import androidx.core.util.Preconditions; + +import java.lang.ref.WeakReference; + +/** + * Immersive mode helper handles the immersive mode for a given window. + * Internally it applies the flag specified at + * https://developer.android.com/training/system-ui/immersive#EnableFullscreen and sets + * window navigation and status bar colors to transparent when applying immersive mode. + * Disabling immersive mode restores the previous colors. + */ +public class ImmersiveModeHelper { + + private static final String TAG = ImmersiveModeHelper.class.getSimpleName(); + + private WeakReference mWindowWeakRef; + private int mNavigationBarColor; + private int mStatusBarColor; + + /** + * Constructor. + * + * @param window to apply immersive mode to. + */ + public ImmersiveModeHelper(Window window) { + Preconditions.checkNotNull(window); + this.mWindowWeakRef = new WeakReference<>(window); + this.mNavigationBarColor = window.getNavigationBarColor(); + this.mStatusBarColor = window.getStatusBarColor(); + } + + /** + * Enables immersive mode hiding system UI. This function also sets navigation and status bar + * colors as transparent. + */ + public void enable() { + Window window = mWindowWeakRef.get(); + if (window == null) { + Log.w(TAG, "Can't enable immersive move. Window reference is lost."); + return; + } + + window.getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN); + + // Workaround for the issue, StatusBar background hides the buttons (b/154227638). + window.setNavigationBarColor(Color.TRANSPARENT); + window.setStatusBarColor(Color.TRANSPARENT); + } + + /** + * Disables immersive mode hiding system UI and restores the previous colors. + */ + public void disable() { + Window window = mWindowWeakRef.get(); + if (window == null) { + Log.w(TAG, "Can't disable immersive move. Window reference is lost."); + return; + } + + window.getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); + + // Restores the original window colors. + window.setNavigationBarColor(mNavigationBarColor); + window.setStatusBarColor(mStatusBarColor); + } +} diff --git a/library/main/tests/robotests/src/com/android/car/setupwizardlib/util/ImmersiveModeHelperTest.java b/library/main/tests/robotests/src/com/android/car/setupwizardlib/util/ImmersiveModeHelperTest.java new file mode 100644 index 0000000..fb3a21d --- /dev/null +++ b/library/main/tests/robotests/src/com/android/car/setupwizardlib/util/ImmersiveModeHelperTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.car.setupwizardlib.util; + +import static com.google.common.truth.Truth.assertThat; + +import android.graphics.Color; +import android.view.View; +import android.view.Window; + +import com.android.car.setupwizardlib.BaseDesignActivity; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.RobolectricTestRunner; + +@RunWith(RobolectricTestRunner.class) +public class ImmersiveModeHelperTest { + + private static final int IMMERSIVE_MODE_FLAGS = + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_FULLSCREEN; + + private static final int NON_IMMERSIVE_MODE_FLAGS = + View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + + private Window mWindow; + private ImmersiveModeHelper mHelper; + + @Before + public void setup() { + this.mWindow = Robolectric + .buildActivity(BaseDesignActivity.class) + .create() + .get() + .getWindow(); + this.mHelper = new ImmersiveModeHelper(mWindow); + } + + @Test + public void enable_shouldSetImmersiveModeFlagsAndWindowBarsColors() { + mHelper.enable(); + assertThat(mWindow.getDecorView().getSystemUiVisibility()).isEqualTo(IMMERSIVE_MODE_FLAGS); + assertThat(mWindow.getNavigationBarColor()).isEqualTo(Color.TRANSPARENT); + assertThat(mWindow.getStatusBarColor()).isEqualTo(Color.TRANSPARENT); + } + + @Test + public void disable_shouldSetNonImmersiveModeFlagsAndKeepWindowBarsColors() { + int navigationBarColor = mWindow.getNavigationBarColor(); + int statusBarColor = mWindow.getStatusBarColor(); + + mHelper.disable(); + + assertThat(mWindow.getDecorView().getSystemUiVisibility()) + .isEqualTo(NON_IMMERSIVE_MODE_FLAGS); + assertThat(mWindow.getNavigationBarColor()) + .isEqualTo(navigationBarColor); + assertThat(mWindow.getStatusBarColor()) + .isEqualTo(statusBarColor); + } + + @Test + public void enablingAndDisablingImmersiveMode_shouldPreserveColors() { + int navigationBarColor = mWindow.getNavigationBarColor(); + int statusBarColor = mWindow.getStatusBarColor(); + + mHelper.enable(); + assertThat(mWindow.getNavigationBarColor()).isEqualTo(Color.TRANSPARENT); + assertThat(mWindow.getStatusBarColor()).isEqualTo(Color.TRANSPARENT); + + mHelper.disable(); + assertThat(mWindow.getNavigationBarColor()).isEqualTo(navigationBarColor); + assertThat(mWindow.getStatusBarColor()).isEqualTo(statusBarColor); + } +} -- cgit v1.2.3