Adds RearDisplay education dialog to SysUI
To accompany the rear display API's to allow apps to move their content to the cover screen on a foldable device, to use the powerful rear cameras for selfies, there needs to be a consisten educational dialog to let users know what is going to happen. This will be shown for all apps that use the rear display jetpack API's, to keep consistency and remove any knowledge an app would have to know about the device they are on. Bug: 207686851 Test: Manual RearDisplay flow testing Change-Id: Ib9e2b286c0d84e2411f19f7cf0b0397486e4d4b1
This commit is contained in:
@@ -126,6 +126,9 @@
|
||||
<uses-permission android:name="android.permission.ALLOW_SLIPPERY_TOUCHES" />
|
||||
<uses-permission android:name="android.permission.INPUT_CONSUMER" />
|
||||
|
||||
<!-- DeviceStateManager -->
|
||||
<uses-permission android:name="android.permission.CONTROL_DEVICE_STATE" />
|
||||
|
||||
<!-- DreamManager -->
|
||||
<uses-permission android:name="android.permission.READ_DREAM_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_DREAM_STATE" />
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2022 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.
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center" >
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardElevation="0dp"
|
||||
app:cardCornerRadius="28dp"
|
||||
app:cardBackgroundColor="@color/rear_display_overlay_animation_background_color">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/rear_display_folded_animation"
|
||||
android:layout_width="@dimen/rear_display_animation_width"
|
||||
android:layout_height="@dimen/rear_display_animation_height"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="fitXY"
|
||||
app:lottie_rawRes="@raw/rear_display_folded"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_repeatMode="reverse"/>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/rear_display_fold_bottom_sheet_title"
|
||||
android:textAppearance="@style/TextAppearance.Dialog.Title"
|
||||
android:lineSpacingExtra="2sp"
|
||||
android:paddingTop="@dimen/rear_display_title_top_padding"
|
||||
android:paddingBottom="@dimen/rear_display_title_bottom_padding"
|
||||
android:gravity="center_horizontal|center_vertical"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/rear_display_bottom_sheet_description"
|
||||
android:textAppearance="@style/TextAppearance.Dialog.Body"
|
||||
android:lineSpacingExtra="2sp"
|
||||
android:translationY="-1.24sp"
|
||||
android:gravity="center_horizontal|top"
|
||||
/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2022 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center" >
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:cardElevation="0dp"
|
||||
app:cardCornerRadius="28dp"
|
||||
app:cardBackgroundColor="@color/rear_display_overlay_animation_background_color">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/rear_display_folded_animation"
|
||||
android:layout_width="@dimen/rear_display_animation_width"
|
||||
android:layout_height="@dimen/rear_display_animation_height"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="fitXY"
|
||||
app:lottie_rawRes="@raw/rear_display_turnaround"
|
||||
app:lottie_autoPlay="true"
|
||||
app:lottie_repeatMode="reverse"/>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/rear_display_unfold_bottom_sheet_title"
|
||||
android:textAppearance="@style/TextAppearance.Dialog.Title"
|
||||
android:lineSpacingExtra="2sp"
|
||||
android:paddingTop="@dimen/rear_display_title_top_padding"
|
||||
android:paddingBottom="@dimen/rear_display_title_bottom_padding"
|
||||
android:gravity="center_horizontal|center_vertical"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/rear_display_bottom_sheet_description"
|
||||
android:textAppearance="@style/TextAppearance.Dialog.Body"
|
||||
android:lineSpacingExtra="2sp"
|
||||
android:translationY="-1.24sp"
|
||||
android:gravity="center_horizontal|top"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rear_display_warning_text_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/rear_display_bottom_sheet_warning"
|
||||
android:textAppearance="@style/TextAppearance.Dialog.Body"
|
||||
android:lineSpacingExtra="2sp"
|
||||
android:gravity="center_horizontal|top"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
1
packages/SystemUI/res/raw/rear_display_folded.json
Normal file
1
packages/SystemUI/res/raw/rear_display_folded.json
Normal file
File diff suppressed because one or more lines are too long
1
packages/SystemUI/res/raw/rear_display_turnaround.json
Normal file
1
packages/SystemUI/res/raw/rear_display_turnaround.json
Normal file
File diff suppressed because one or more lines are too long
@@ -247,4 +247,8 @@
|
||||
<color name="dream_overlay_clock_ambient_text_shadow_color">#4D000000</color>
|
||||
<color name="dream_overlay_status_bar_key_text_shadow_color">#66000000</color>
|
||||
<color name="dream_overlay_status_bar_ambient_text_shadow_color">#59000000</color>
|
||||
|
||||
<!-- Rear Display Education -->
|
||||
<color name="rear_display_overlay_animation_background_color">#1E1B17</color>
|
||||
<color name="rear_display_overlay_dialog_background_color">#1E1B17</color>
|
||||
</resources>
|
||||
|
||||
@@ -1592,4 +1592,10 @@
|
||||
<dimen name="config_rounded_mask_size">0px</dimen>
|
||||
<dimen name="config_rounded_mask_size_top">0px</dimen>
|
||||
<dimen name="config_rounded_mask_size_bottom">0px</dimen>
|
||||
|
||||
<!-- Rear Display Education dimens -->
|
||||
<dimen name="rear_display_animation_width">273dp</dimen>
|
||||
<dimen name="rear_display_animation_height">200dp</dimen>
|
||||
<dimen name="rear_display_title_top_padding">24dp</dimen>
|
||||
<dimen name="rear_display_title_bottom_padding">16dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -2728,4 +2728,17 @@
|
||||
shortcut button on the lock screen. [CHAR LIMIT=NONE].
|
||||
-->
|
||||
<string name="keyguard_affordance_enablement_dialog_home_instruction_2">• At least one device is available</string>
|
||||
|
||||
<!-- Text for education page of cancel button to hide the page. [CHAR_LIMIT=NONE] -->
|
||||
<string name="rear_display_bottom_sheet_cancel">Cancel</string>
|
||||
<!-- Text for the user to confirm they flipped the device around. [CHAR_LIMIT=NONE] -->
|
||||
<string name="rear_display_bottom_sheet_confirm">Flip now</string>
|
||||
<!-- Text for education page title to guide user to unfold phone. [CHAR_LIMIT=50] -->
|
||||
<string name="rear_display_fold_bottom_sheet_title">Unfold phone for a better selfie</string>
|
||||
<!-- Text for education page title to guide user to flip to the front display. [CHAR_LIMIT=50] -->
|
||||
<string name="rear_display_unfold_bottom_sheet_title">Flip to front display for a better selfie?</string>
|
||||
<!-- Text for education page description to suggest user to use rear selfie capture. [CHAR_LIMIT=NONE] -->
|
||||
<string name="rear_display_bottom_sheet_description">Use the rear-facing camera for a wider photo with higher resolution.</string>
|
||||
<!-- Text for education page description to warn user that the display will turn off if the button is clicked. [CHAR_LIMIT=NONE] -->
|
||||
<string name="rear_display_bottom_sheet_warning"><b>✱ This screen will turn off</b></string>
|
||||
</resources>
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.android.systemui.media.taptotransfer.MediaTttCommandLineHelper
|
||||
import com.android.systemui.media.taptotransfer.receiver.MediaTttChipControllerReceiver
|
||||
import com.android.systemui.media.taptotransfer.sender.MediaTttSenderCoordinator
|
||||
import com.android.systemui.power.PowerUI
|
||||
import com.android.systemui.reardisplay.RearDisplayDialogController
|
||||
import com.android.systemui.recents.Recents
|
||||
import com.android.systemui.settings.dagger.MultiUserUtilsModule
|
||||
import com.android.systemui.shortcut.ShortcutKeyDispatcher
|
||||
@@ -243,4 +244,11 @@ abstract class SystemUICoreStartableModule {
|
||||
@IntoMap
|
||||
@ClassKey(ChipbarCoordinator::class)
|
||||
abstract fun bindChipbarController(sysui: ChipbarCoordinator): CoreStartable
|
||||
|
||||
|
||||
/** Inject into RearDisplayDialogController) */
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(RearDisplayDialogController::class)
|
||||
abstract fun bindRearDisplayDialogController(sysui: RearDisplayDialogController): CoreStartable
|
||||
}
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.systemui.reardisplay;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.annotation.TestApi;
|
||||
import android.content.Context;
|
||||
import android.hardware.devicestate.DeviceStateManager;
|
||||
import android.hardware.devicestate.DeviceStateManagerGlobal;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.CoreStartable;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.statusbar.phone.SystemUIDialog;
|
||||
|
||||
import com.airbnb.lottie.LottieAnimationView;
|
||||
import com.airbnb.lottie.LottieDrawable;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Provides an educational dialog to the user alerting them to what
|
||||
* they may need to do to enter rear display mode. This may be to open the
|
||||
* device if it is currently folded, or to confirm that they would like
|
||||
* the content to move to the screen on their device that is aligned with
|
||||
* the rear camera. This includes a device animation to provide more context
|
||||
* to the user.
|
||||
*
|
||||
* We are suppressing lint for the VisibleForTests check because the use of
|
||||
* DeviceStateManagerGlobal as in this file should not be encouraged for other use-cases.
|
||||
* The lint check will notify any other use-cases that they are possibly doing something
|
||||
* incorrectly.
|
||||
*/
|
||||
@SuppressLint("VisibleForTests") // TODO(b/260264542) Migrate away from DeviceStateManagerGlobal
|
||||
@SysUISingleton
|
||||
public class RearDisplayDialogController implements CoreStartable, CommandQueue.Callbacks {
|
||||
|
||||
private int[] mFoldedStates;
|
||||
private boolean mStartedFolded;
|
||||
private boolean mServiceNotified = false;
|
||||
private int mAnimationRepeatCount = LottieDrawable.INFINITE;
|
||||
|
||||
private DeviceStateManagerGlobal mDeviceStateManagerGlobal;
|
||||
private DeviceStateManager.DeviceStateCallback mDeviceStateManagerCallback =
|
||||
new DeviceStateManagerCallback();
|
||||
|
||||
private final Context mContext;
|
||||
private final CommandQueue mCommandQueue;
|
||||
private final Executor mExecutor;
|
||||
|
||||
@VisibleForTesting
|
||||
SystemUIDialog mRearDisplayEducationDialog;
|
||||
|
||||
@Inject
|
||||
public RearDisplayDialogController(Context context, CommandQueue commandQueue,
|
||||
@Main Executor executor) {
|
||||
mContext = context;
|
||||
mCommandQueue = commandQueue;
|
||||
mExecutor = executor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
mCommandQueue.addCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showRearDisplayDialog(int currentBaseState) {
|
||||
initializeValues(currentBaseState);
|
||||
createAndShowDialog();
|
||||
}
|
||||
|
||||
private void createAndShowDialog() {
|
||||
mServiceNotified = false;
|
||||
Context dialogContext = mRearDisplayEducationDialog.getContext();
|
||||
|
||||
View dialogView;
|
||||
if (mStartedFolded) {
|
||||
dialogView = View.inflate(dialogContext,
|
||||
R.layout.activity_rear_display_education, null);
|
||||
} else {
|
||||
dialogView = View.inflate(dialogContext,
|
||||
R.layout.activity_rear_display_education_opened, null);
|
||||
}
|
||||
LottieAnimationView animationView = dialogView.findViewById(
|
||||
R.id.rear_display_folded_animation);
|
||||
animationView.setRepeatCount(mAnimationRepeatCount);
|
||||
mRearDisplayEducationDialog.setView(dialogView);
|
||||
|
||||
configureDialogButtons();
|
||||
|
||||
mRearDisplayEducationDialog.show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the buttons on the dialog depending on the starting device posture
|
||||
*/
|
||||
private void configureDialogButtons() {
|
||||
// If we are open, we need to provide a confirm option
|
||||
if (!mStartedFolded) {
|
||||
mRearDisplayEducationDialog.setPositiveButton(
|
||||
R.string.rear_display_bottom_sheet_confirm,
|
||||
(dialog, which) -> closeOverlayAndNotifyService(false), true);
|
||||
}
|
||||
mRearDisplayEducationDialog.setNegativeButton(R.string.rear_display_bottom_sheet_cancel,
|
||||
(dialog, which) -> closeOverlayAndNotifyService(true), true);
|
||||
mRearDisplayEducationDialog.setOnDismissListener(dialog -> {
|
||||
// Dialog is being dismissed before we've notified the system server
|
||||
if (!mServiceNotified) {
|
||||
closeOverlayAndNotifyService(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes properties and values we need when getting ready to show the dialog.
|
||||
*
|
||||
* Ensures we're not using old values from when the dialog may have been shown previously.
|
||||
*/
|
||||
private void initializeValues(int startingBaseState) {
|
||||
mRearDisplayEducationDialog = new SystemUIDialog(mContext);
|
||||
if (mFoldedStates == null) {
|
||||
mFoldedStates = mContext.getResources().getIntArray(
|
||||
com.android.internal.R.array.config_foldedDeviceStates);
|
||||
}
|
||||
mStartedFolded = isFoldedState(startingBaseState);
|
||||
mDeviceStateManagerGlobal = DeviceStateManagerGlobal.getInstance();
|
||||
mDeviceStateManagerGlobal.registerDeviceStateCallback(mDeviceStateManagerCallback,
|
||||
mExecutor);
|
||||
}
|
||||
|
||||
private boolean isFoldedState(int state) {
|
||||
for (int i = 0; i < mFoldedStates.length; i++) {
|
||||
if (mFoldedStates[i] == state) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the educational overlay, and notifies the system service if rear display mode
|
||||
* should be cancelled or enabled.
|
||||
*/
|
||||
private void closeOverlayAndNotifyService(boolean shouldCancelRequest) {
|
||||
mServiceNotified = true;
|
||||
mDeviceStateManagerGlobal.unregisterDeviceStateCallback(mDeviceStateManagerCallback);
|
||||
mDeviceStateManagerGlobal.onStateRequestOverlayDismissed(shouldCancelRequest);
|
||||
}
|
||||
|
||||
/**
|
||||
* TestAPI to allow us to set the folded states array, instead of reading from resources.
|
||||
*/
|
||||
@TestApi
|
||||
void setFoldedStates(int[] foldedStates) {
|
||||
mFoldedStates = foldedStates;
|
||||
}
|
||||
|
||||
@TestApi
|
||||
void setDeviceStateManagerCallback(
|
||||
DeviceStateManager.DeviceStateCallback deviceStateManagerCallback) {
|
||||
mDeviceStateManagerCallback = deviceStateManagerCallback;
|
||||
}
|
||||
|
||||
@TestApi
|
||||
void setAnimationRepeatCount(int repeatCount) {
|
||||
mAnimationRepeatCount = repeatCount;
|
||||
}
|
||||
|
||||
private class DeviceStateManagerCallback implements DeviceStateManager.DeviceStateCallback {
|
||||
@Override
|
||||
public void onBaseStateChanged(int state) {
|
||||
if (mStartedFolded && !isFoldedState(state)) {
|
||||
// We've opened the device, we can close the overlay
|
||||
mRearDisplayEducationDialog.dismiss();
|
||||
closeOverlayAndNotifyService(false);
|
||||
} else if (!mStartedFolded && isFoldedState(state)) {
|
||||
// We've closed the device, finish activity
|
||||
mRearDisplayEducationDialog.dismiss();
|
||||
closeOverlayAndNotifyService(true);
|
||||
}
|
||||
}
|
||||
|
||||
// We only care about physical device changes in this scenario
|
||||
@Override
|
||||
public void onStateChanged(int state) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright (C) 2022 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.systemui.reardisplay;
|
||||
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import android.hardware.devicestate.DeviceStateManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.statusbar.CommandQueue;
|
||||
import com.android.systemui.util.concurrency.FakeExecutor;
|
||||
import com.android.systemui.util.time.FakeSystemClock;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
public class RearDisplayDialogControllerTest extends SysuiTestCase {
|
||||
|
||||
@Mock
|
||||
private CommandQueue mCommandQueue;
|
||||
|
||||
private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
|
||||
|
||||
|
||||
private static final int CLOSED_BASE_STATE = 0;
|
||||
private static final int OPEN_BASE_STATE = 1;
|
||||
|
||||
@Test
|
||||
public void testClosedDialogIsShown() {
|
||||
RearDisplayDialogController controller = new RearDisplayDialogController(mContext,
|
||||
mCommandQueue, mFakeExecutor);
|
||||
controller.setDeviceStateManagerCallback(new TestDeviceStateManagerCallback());
|
||||
controller.setFoldedStates(new int[]{0});
|
||||
controller.setAnimationRepeatCount(0);
|
||||
|
||||
controller.showRearDisplayDialog(CLOSED_BASE_STATE);
|
||||
assertTrue(controller.mRearDisplayEducationDialog.isShowing());
|
||||
View deviceOpenedWarningTextView = controller.mRearDisplayEducationDialog.findViewById(
|
||||
R.id.rear_display_warning_text_view);
|
||||
assertNull(deviceOpenedWarningTextView);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOpenDialogIsShown() {
|
||||
RearDisplayDialogController controller = new RearDisplayDialogController(mContext,
|
||||
mCommandQueue, mFakeExecutor);
|
||||
controller.setDeviceStateManagerCallback(new TestDeviceStateManagerCallback());
|
||||
controller.setFoldedStates(new int[]{0});
|
||||
controller.setAnimationRepeatCount(0);
|
||||
|
||||
controller.showRearDisplayDialog(OPEN_BASE_STATE);
|
||||
|
||||
assertTrue(controller.mRearDisplayEducationDialog.isShowing());
|
||||
View deviceOpenedWarningTextView = controller.mRearDisplayEducationDialog.findViewById(
|
||||
R.id.rear_display_warning_text_view);
|
||||
assertNotNull(deviceOpenedWarningTextView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Empty device state manager callbacks, so we can verify that the correct
|
||||
* dialogs are being created regardless of device state of the test device.
|
||||
*/
|
||||
private static class TestDeviceStateManagerCallback implements
|
||||
DeviceStateManager.DeviceStateCallback {
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int state) { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user