diff options
author | Sandra Alfaro <sandraalfaro@google.com> | 2020-06-11 16:08:53 -0700 |
---|---|---|
committer | Rodrigo Lagos <rlagos@google.com> | 2020-06-12 19:35:16 +0000 |
commit | 9983a290a9711daeadb30109c2386cf908b7388b (patch) | |
tree | 71b1e5a4f0b86e4e118a19a3be025caf93d4df50 | |
parent | 7a347032b0c358bc3d7e3c3717a050c321ee678d (diff) | |
download | setupwizard-9983a290a9711daeadb30109c2386cf908b7388b.tar.gz |
Update SUW Lib with OEM customizable boolean for immersive mode
Bug: 155917872
Bug: 158754064
Test: atest CarSetupWizardUiUtilsTest
Change-Id: I91cb4325268fa037b3b86588c69b9c26056eb7e9
5 files changed, 283 insertions, 7 deletions
diff --git a/library/main/src/com/android/car/setupwizardlib/BaseSetupWizardActivity.java b/library/main/src/com/android/car/setupwizardlib/BaseSetupWizardActivity.java index cbf47f1..0fa8b01 100644 --- a/library/main/src/com/android/car/setupwizardlib/BaseSetupWizardActivity.java +++ b/library/main/src/com/android/car/setupwizardlib/BaseSetupWizardActivity.java @@ -28,6 +28,8 @@ import androidx.annotation.VisibleForTesting; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; +import com.android.car.setupwizardlib.partner.PartnerConfig; +import com.android.car.setupwizardlib.partner.PartnerConfigHelper; import com.android.car.setupwizardlib.util.CarDrivingStateMonitor; import com.android.car.setupwizardlib.util.CarSetupWizardUiUtils; import com.android.car.setupwizardlib.util.CarWizardManagerHelper; @@ -111,7 +113,9 @@ abstract class BaseSetupWizardActivity extends FragmentActivity { protected void onStart() { super.onStart(); // Must be done here so that the SystemUI is hidden when back button is clicked - CarSetupWizardUiUtils.hideSystemUI(this); + CarSetupWizardUiUtils.setWindowImmersiveMode(this.getWindow(), + PartnerConfigHelper.get(this).getString( + this, PartnerConfig.CONFIG_IMMERSIVE_MODE)); // Fragment commits are not allowed once the Activity's state has been saved. Once // onStart() has been called, the FragmentManager should now allow commits. mAllowFragmentCommits = true; @@ -156,7 +160,9 @@ abstract class BaseSetupWizardActivity extends FragmentActivity { public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); if (hasFocus) { - CarSetupWizardUiUtils.hideSystemUI(this); + CarSetupWizardUiUtils.setWindowImmersiveMode(this.getWindow(), + PartnerConfigHelper.get(this).getString( + this, PartnerConfig.CONFIG_IMMERSIVE_MODE)); } } diff --git a/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfig.java b/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfig.java index 8946b7a..00c0ea3 100644 --- a/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfig.java +++ b/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfig.java @@ -19,6 +19,9 @@ package com.android.car.setupwizardlib.partner; /** Resources that can be customized by partner overlay APK. */ public enum PartnerConfig { + CONFIG_IMMERSIVE_MODE( + PartnerConfigKey.KEY_IMMERSIVE_MODE, ResourceType.STRING), + CONFIG_TOOLBAR_BG_COLOR( PartnerConfigKey.KEY_TOOLBAR_BG_COLOR, ResourceType.COLOR), diff --git a/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfigKey.java b/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfigKey.java index de4aa9e..32caceb 100644 --- a/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfigKey.java +++ b/library/main/src/com/android/car/setupwizardlib/partner/PartnerConfigKey.java @@ -23,6 +23,7 @@ import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.SOURCE) @StringDef({ + PartnerConfigKey.KEY_IMMERSIVE_MODE, PartnerConfigKey.KEY_TOOLBAR_BG_COLOR, PartnerConfigKey.KEY_TOOLBAR_BUTTON_ICON_BACK, PartnerConfigKey.KEY_TOOLBAR_BUTTON_FONT_FAMILY, @@ -47,6 +48,8 @@ import java.lang.annotation.RetentionPolicy; /** Resource names that can be customized by partner overlay APK. */ public @interface PartnerConfigKey { + String KEY_IMMERSIVE_MODE = "suw_compat_immersive_mode"; + String KEY_TOOLBAR_BG_COLOR = "suw_compat_toolbar_bg_color"; String KEY_TOOLBAR_BUTTON_ICON_BACK = "suw_compat_toolbar_button_icon_back"; 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 3af842a..3611931 100644 --- a/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java +++ b/library/main/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtils.java @@ -17,14 +17,23 @@ package com.android.car.setupwizardlib.util; import android.app.Activity; +import android.content.Context; +import android.content.res.TypedArray; +import android.util.Log; import android.view.View; +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. + */ public final class CarSetupWizardUiUtils { private static final String TAG = CarSetupWizardUiUtils.class.getSimpleName(); + /** Key for immersive mode value pased to 1P apps */ + public static final String IMMERSIVE_MODE_TYPE = "immersiveModeType"; + /** Hide system UI */ public static void hideSystemUI(Activity activity) { maybeHideSystemUI(activity); @@ -35,15 +44,66 @@ public final class CarSetupWizardUiUtils { **/ @Deprecated public static void maybeHideSystemUI(Activity activity) { - Preconditions.checkNotNull(activity); + enableImmersiveMode(activity.getWindow()); + } + + /** + * Set the appropriate immersive mode according to immersiveModeValue + */ + public static void setWindowImmersiveMode(Window window, String immersiveModeValue) { + Preconditions.checkNotNull(window); + ImmersiveModeTypes immersiveModeType; + try { + immersiveModeType = ImmersiveModeTypes.valueOf(immersiveModeValue); + } catch (IllegalArgumentException | NullPointerException e) { + Log.w(TAG, "Immersive Mode value: " + immersiveModeValue + + " not valid, using IMMERSIVE"); + immersiveModeType = ImmersiveModeTypes.IMMERSIVE; + } + Log.v(TAG, "Enable " + immersiveModeType + " mode"); + switch (immersiveModeType) { + case IMMERSIVE: + enableImmersiveMode(window); + window.getDecorView().setOnSystemUiVisibilityChangeListener( + visibility -> enableImmersiveMode(window)); + break; + case IMMERSIVE_WITH_STATUS: + enableImmersiveModeWithStatus(window); + window.getDecorView().setOnSystemUiVisibilityChangeListener( + visibility -> enableImmersiveModeWithStatus(window)); + break; + case NON_IMMERSIVE: + disableImmersiveMode(window); + window.getDecorView().setOnSystemUiVisibilityChangeListener( + visibility -> disableImmersiveMode(window)); + break; + case SYSTEM_DEFAULT: + //SUW won't change the current immersive mode. + break; + } + } + + /** + * Enables immersive mode hiding system UI. + * + * @param window to apply immersive mode. + * + * @deprecated Use {@code setWindowImmersiveMode} + */ + @Deprecated + public static void enableImmersiveMode(Window window) { + if (Log.isLoggable(TAG, Log.INFO)) { + Log.i(TAG, "enableImmersiveMode"); + } + + Preconditions.checkNotNull(window); // See https://developer.android.com/training/system-ui/immersive#EnableFullscreen // Enables regular immersive mode. // For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE. // Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY - View decorView = activity.getWindow().getDecorView(); - decorView.setSystemUiVisibility( - View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY + window.getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_IMMERSIVE // Set the content to appear under the system bars so that the // content doesn't resize when the system bars hide and show. | View.SYSTEM_UI_FLAG_LAYOUT_STABLE @@ -54,6 +114,79 @@ public final class CarSetupWizardUiUtils { | View.SYSTEM_UI_FLAG_FULLSCREEN); } + /** + * Enables immersive mode hiding only navigation bar. + * + * @param window to apply immersive mode. + */ + private static void enableImmersiveModeWithStatus(Window window) { + if (Log.isLoggable(TAG, Log.INFO)) { + Log.i(TAG, "enableImmersiveModeWithStatus"); + } + + Preconditions.checkNotNull(window); + + // See https://developer.android.com/training/system-ui/immersive#EnableFullscreen + // Enables regular immersive mode. + window.getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_IMMERSIVE + // Set the content to appear under the system bars so that the + // content doesn't resize when the system bars hide and show. + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE + // Hide the nav bar + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); + } + + /** + * Disables immersive mode hiding system UI and restores the previous colors. + * + * @param window the current window instance. + * + * @deprecated Use {@code setWindowImmersiveMode} + */ + @Deprecated + public static void disableImmersiveMode(Window window) { + if (Log.isLoggable(TAG, Log.INFO)) { + Log.i(TAG, "disableImmersiveMode"); + } + + Preconditions.checkNotNull(window); + + // Restores the decor view flags to disable the immersive mode. + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); + + // Tries to restore colors for nav and status bar from resources. + Context context = window.getContext(); + if (context == null) { + if (Log.isLoggable(TAG, Log.WARN)) { + Log.w(TAG, "Can't restore colors for navigation and status bar."); + } + return; + } + + // Reads the colors for navigation and status bar from resources. + final TypedArray typedArray = + context.obtainStyledAttributes( + new int[]{ + android.R.attr.statusBarColor, + android.R.attr.navigationBarColor}); + int statusBarColor = typedArray.getColor(0, 0); + int navigationBarColor = typedArray.getColor(1, 0); + + window.setStatusBarColor(statusBarColor); + window.setNavigationBarColor(navigationBarColor); + + typedArray.recycle(); + } + + /** Types of Immersive Mode supported by SUW */ + public enum ImmersiveModeTypes { + IMMERSIVE, + IMMERSIVE_WITH_STATUS, + NON_IMMERSIVE, + SYSTEM_DEFAULT + } + private CarSetupWizardUiUtils() { } } diff --git a/library/main/tests/robotests/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtilsTest.java b/library/main/tests/robotests/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtilsTest.java new file mode 100644 index 0000000..8ba08f3 --- /dev/null +++ b/library/main/tests/robotests/src/com/android/car/setupwizardlib/util/CarSetupWizardUiUtilsTest.java @@ -0,0 +1,131 @@ +/* + * 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.app.Activity; +import android.graphics.Color; +import android.view.View; +import android.view.Window; + +import com.android.car.setupwizardlib.robotests.R; +import com.android.internal.util.XmlUtils; + +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 CarSetupWizardUiUtilsTest { + + private static final int IMMERSIVE_MODE_FLAGS = + View.SYSTEM_UI_FLAG_IMMERSIVE + | 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_VISIBLE; + + private static final int IMMERSIVE_WITH_STATUS_MODE_FLAGS = + View.SYSTEM_UI_FLAG_IMMERSIVE + | View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; + + private static final int[] RES_ID_NAV_AND_STATUS_BARS = new int[]{ + android.R.attr.statusBarColor, + android.R.attr.navigationBarColor}; + + // Note that these colors are defined in the test theme + private static final int TEST_THEME = R.style.NavAndStatusBarTestTheme; + private static final int EXPECTED_COLOR_STATUS_BAR = XmlUtils.convertValueToInt("#001", -1); + private static final int EXPECTED_COLOR_NAVIGATION_BAR = XmlUtils.convertValueToInt("#002", -1); + + private Activity mActivity; + private Window mWindow; + + @Before + public void setup() { + mActivity = Robolectric + .buildActivity(Activity.class) + .create() + .get(); + mActivity.setTheme(TEST_THEME); + mWindow = mActivity.getWindow(); + } + + @Test + public void maybeHideSystemUI() { + CarSetupWizardUiUtils.maybeHideSystemUI(mActivity); + assertThat(mWindow.getDecorView().getSystemUiVisibility()) + .isEqualTo(IMMERSIVE_MODE_FLAGS); + } + + @Test + public void enableImmersiveMode() { + CarSetupWizardUiUtils.enableImmersiveMode(mWindow); + assertThat(mWindow.getDecorView().getSystemUiVisibility()) + .isEqualTo(IMMERSIVE_MODE_FLAGS); + } + + @Test + public void disableImmersiveMode() { + // Resetting the status bar colors. + mWindow.setNavigationBarColor(Color.TRANSPARENT); + mWindow.setStatusBarColor(Color.TRANSPARENT); + + CarSetupWizardUiUtils.disableImmersiveMode(mWindow); + + assertThat(mWindow.getDecorView().getSystemUiVisibility()) + .isEqualTo(NON_IMMERSIVE_MODE_FLAGS); + assertThat(mWindow.getNavigationBarColor()) + .isEqualTo(EXPECTED_COLOR_NAVIGATION_BAR); + assertThat(mWindow.getStatusBarColor()) + .isEqualTo(EXPECTED_COLOR_STATUS_BAR); + } + + @Test + public void setWindow_Immersive() { + CarSetupWizardUiUtils.setWindowImmersiveMode(mWindow, + CarSetupWizardUiUtils.ImmersiveModeTypes.IMMERSIVE.toString()); + assertThat(mWindow.getDecorView().getSystemUiVisibility()) + .isEqualTo(IMMERSIVE_MODE_FLAGS); + } + + @Test + public void setWindow_ImmersiveWithStatus() { + CarSetupWizardUiUtils.setWindowImmersiveMode(mWindow, + CarSetupWizardUiUtils.ImmersiveModeTypes.IMMERSIVE_WITH_STATUS.toString()); + assertThat(mWindow.getDecorView().getSystemUiVisibility()) + .isEqualTo(IMMERSIVE_WITH_STATUS_MODE_FLAGS); + } + + + @Test + public void setWindow_NonImmersive() { + CarSetupWizardUiUtils.setWindowImmersiveMode(mWindow, + CarSetupWizardUiUtils.ImmersiveModeTypes.NON_IMMERSIVE.toString()); + assertThat(mWindow.getDecorView().getSystemUiVisibility()) + .isEqualTo(NON_IMMERSIVE_MODE_FLAGS); + } + +} |