Add ReadViewCameraViewController/Mediator.

- Launch config_rearViewCameraActivity in the overlay Window when
  gear is reversed.
- Add/Remove ActivityView dynamically to save the system resource
  while it is hidden.

Bug: 157481389
Test: atest com.android.systemui.car.rvc
Test: Check if RearViewCamera is launched when the gear is reversed and if it will be closed when the gear is changed to the other one.
Change-Id: I768fe9090eed9cb82c4108ab8f6335802d36fa64
This commit is contained in:
Yuncheol Heo
2020-06-04 16:06:43 -07:00
parent bc89f3ea7a
commit b1369818a3
12 changed files with 608 additions and 1 deletions

View File

@@ -23,6 +23,8 @@
<uses-permission android:name="android.car.permission.CAR_POWER" />
<!-- This permission is required to get the trusted device list of a user. -->
<uses-permission android:name="android.car.permission.CAR_ENROLL_TRUST"/>
<!-- This permission is required to monitor gear state. -->
<uses-permission android:name="android.car.permission.CAR_POWERTRAIN" />
<!-- This permission is required to get bluetooth broadcast. -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- These permissions are required to implement icons based on role holders. -->

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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.
-->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/rear_view_camera_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:orientation="vertical">
<Button
android:id="@+id/close_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/rear_view_camera_button_background"
android:text="@string/rear_view_camera_close_button_text"
android:textAppearance="?android:attr/textAppearanceLarge"/>
</LinearLayout>

View File

@@ -42,4 +42,10 @@
android:layout_height="match_parent"
android:layout="@layout/car_user_switching_dialog"/>
</FrameLayout>
<!-- Should be at bottom to get the highest Z-order. -->
<ViewStub android:id="@+id/rear_view_camera_stub"
android:layout_width="@dimen/rear_view_camera_width"
android:layout_height="@dimen/rear_view_camera_height"
android:layout_gravity="center"
android:layout="@layout/rear_view_camera"/>
</FrameLayout>

View File

@@ -66,4 +66,6 @@
<color name="car_user_switching_dialog_background_color">@android:color/black</color>
<color name="car_user_switching_dialog_loading_text_color">@*android:color/car_body1</color>
<color name="rear_view_camera_button_background">@*android:color/car_card_dark</color>
</resources>

View File

@@ -108,6 +108,7 @@
<item>com.android.systemui.car.keyguard.CarKeyguardViewMediator</item>
<item>com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator</item>
<item>com.android.systemui.car.userswitcher.UserSwitchTransitionViewMediator</item>
<item>com.android.systemui.car.rvc.RearViewCameraViewMediator</item>
</string-array>
<!--
@@ -150,4 +151,7 @@
<!-- How many milliseconds to wait before force hiding the UserSwitchTransitionView -->
<integer name="config_userSwitchTransitionViewShownTimeoutMs" translatable="false">5000</integer>
<!-- The Activity name for the Rear View Camera, if empty, the feature will be disabled. -->
<string name="config_rearViewCameraActivity" translatable="false"></string>
</resources>

View File

@@ -227,4 +227,8 @@
<dimen name="car_fullscreen_user_pod_image_avatar_height">96dp</dimen>
<dimen name="car_user_switching_dialog_loading_text_margin_top">@*android:dimen/car_padding_4</dimen>
<dimen name="car_user_switching_dialog_loading_text_font_size">@*android:dimen/car_body1_size</dimen>
<!-- dimensions for rear view camera -->
<dimen name="rear_view_camera_width">600dp</dimen>
<dimen name="rear_view_camera_height">500dp</dimen>
</resources>

View File

@@ -42,4 +42,6 @@
<string name="car_loading_profile">Loading</string>
<!-- Message to inform user that the new user profile is loading with additional information on the previous and the next user. [CHAR LIMIT=100] -->
<string name="car_loading_profile_developer_message">Loading user (from <xliff:g id="from_user" example="10">%1$d</xliff:g> to <xliff:g id="to_user" example="12">%2$d</xliff:g>)</string>
<!-- Text for the close button in Rear View Camera [CHAR LIMIT=30] -->
<string name="rear_view_camera_close_button_text">Close</string>
</resources>

View File

@@ -0,0 +1,141 @@
/*
* 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.systemui.car.rvc;
import android.app.ActivityView;
import android.app.ActivityView.StateCallback;
import android.content.ComponentName;
import android.content.Intent;
import android.content.res.Resources;
import android.util.Slog;
import android.view.ViewGroup;
import android.widget.LinearLayout.LayoutParams;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
import com.android.systemui.car.window.OverlayViewController;
import com.android.systemui.car.window.OverlayViewGlobalStateController;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import javax.inject.Inject;
/** View controller for the rear view camera. */
@SysUISingleton
public class RearViewCameraViewController extends OverlayViewController {
private static final String TAG = "RearViewCameraView";
private static final boolean DBG = false;
private final ComponentName mRearViewCameraActivity;
private ViewGroup mRvcView;
private final LayoutParams mRvcViewLayoutParams = new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, /* weight= */ 1.0f);
@VisibleForTesting
ActivityView mActivityView;
@VisibleForTesting
final StateCallback mActivityViewCallback = new StateCallback() {
@Override
public void onActivityViewReady(ActivityView view) {
Intent intent = new Intent(Intent.ACTION_MAIN)
.setComponent(mRearViewCameraActivity)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
// TODO(b/170899079): Migrate this to FixedActivityService.
view.startActivity(intent);
}
@Override
public void onActivityViewDestroyed(ActivityView view) {}
};
@Inject
public RearViewCameraViewController(
@Main Resources resources,
OverlayViewGlobalStateController overlayViewGlobalStateController) {
super(R.id.rear_view_camera_stub, overlayViewGlobalStateController);
String rearViewCameraActivityName = resources.getString(
R.string.config_rearViewCameraActivity);
if (!rearViewCameraActivityName.isEmpty()) {
mRearViewCameraActivity = ComponentName.unflattenFromString(rearViewCameraActivityName);
if (DBG) Slog.d(TAG, "mRearViewCameraActivity=" + mRearViewCameraActivity);
} else {
mRearViewCameraActivity = null;
Slog.e(TAG, "RearViewCameraViewController is disabled, since no Activity is defined");
}
}
@Override
protected void onFinishInflate() {
mRvcView = (ViewGroup) getLayout().findViewById(R.id.rear_view_camera_container);
getLayout().findViewById(R.id.close_button).setOnClickListener(v -> {
stop();
});
}
@Override
protected void hideInternal() {
super.hideInternal();
if (DBG) Slog.d(TAG, "hideInternal: mActivityView=" + mActivityView);
if (mActivityView == null) return;
mRvcView.removeView(mActivityView);
// Release ActivityView since the Activity on ActivityView (with showWhenLocked flag) keeps
// running even if ActivityView is hidden.
mActivityView.release();
mActivityView = null;
}
@Override
protected void showInternal() {
super.showInternal();
if (DBG) Slog.d(TAG, "showInternal: mActivityView=" + mActivityView);
if (mActivityView != null) return;
mActivityView = new ActivityView(mRvcView.getContext());
mActivityView.setCallback(mActivityViewCallback);
mActivityView.setLayoutParams(mRvcViewLayoutParams);
mRvcView.addView(mActivityView, /* index= */ 0);
}
boolean isShown() {
return mActivityView != null;
}
boolean isEnabled() {
return mRearViewCameraActivity != null;
}
@Override
protected boolean shouldShowHUN() {
return false;
}
@Override
protected boolean shouldShowWhenOccluded() {
// Returns true to show it on top of Keylock.
return true;
}
@Override
protected boolean shouldShowNavigationBarInsets() {
return true;
}
@Override
protected boolean shouldShowStatusBarInsets() {
return true;
}
}

View File

@@ -0,0 +1,121 @@
/*
* 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.systemui.car.rvc;
import android.car.Car;
import android.car.VehicleGear;
import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.UserHandle;
import android.util.Slog;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.window.OverlayViewMediator;
import com.android.systemui.dagger.SysUISingleton;
import javax.inject.Inject;
/**
* View mediator for the rear view camera (RVC), which monitors the gear changes and shows
* the RVC when the gear position is R and otherwise it hides the RVC.
*/
@SysUISingleton
public class RearViewCameraViewMediator implements OverlayViewMediator {
private static final String TAG = "RearViewCameraView";
private static final boolean DBG = false;
private final RearViewCameraViewController mRearViewCameraViewController;
private final CarServiceProvider mCarServiceProvider;
private final BroadcastDispatcher mBroadcastDispatcher;
private CarPropertyManager mCarPropertyManager;
// TODO(b/170792252): Replace the following with the callback from CarEvsManager if it's ready.
private final CarPropertyEventCallback mPropertyEventCallback = new CarPropertyEventCallback() {
@Override
public void onChangeEvent(CarPropertyValue value) {
if (DBG) Slog.d(TAG, "onChangeEvent value=" + value);
if (value.getPropertyId() != VehiclePropertyIds.GEAR_SELECTION) {
Slog.w(TAG, "Got the event for non-registered property: " + value.getPropertyId());
return;
}
if ((Integer) value.getValue() == VehicleGear.GEAR_REVERSE) {
mRearViewCameraViewController.start();
} else {
mRearViewCameraViewController.stop();
}
}
@Override
public void onErrorEvent(int propId, int zone) {
Slog.e(TAG, "onErrorEvent propId=" + propId + ", zone=" + zone);
}
};
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (DBG) Slog.d(TAG, "onReceive: " + intent);
if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())
&& mRearViewCameraViewController.isShown()) {
mRearViewCameraViewController.stop();
}
}
};
@Inject
public RearViewCameraViewMediator(
RearViewCameraViewController rearViewCameraViewController,
CarServiceProvider carServiceProvider,
BroadcastDispatcher broadcastDispatcher) {
if (DBG) Slog.d(TAG, "RearViewCameraViewMediator:init");
mRearViewCameraViewController = rearViewCameraViewController;
mCarServiceProvider = carServiceProvider;
mBroadcastDispatcher = broadcastDispatcher;
}
@Override
public void registerListeners() {
if (DBG) Slog.d(TAG, "RearViewCameraViewMediator:registerListeners");
if (!mRearViewCameraViewController.isEnabled()) {
Slog.i(TAG, "RearViewCameraViewController isn't enabled");
return;
}
mCarServiceProvider.addListener(car -> {
mCarPropertyManager = (CarPropertyManager) car.getCarManager(Car.PROPERTY_SERVICE);
if (mCarPropertyManager == null) {
Slog.e(TAG, "Unable to get CarPropertyManager");
return;
}
if (DBG) Slog.d(TAG, "Registering mPropertyEventCallback.");
mCarPropertyManager.registerCallback(mPropertyEventCallback,
VehiclePropertyIds.GEAR_SELECTION, CarPropertyManager.SENSOR_RATE_UI);
});
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver,
new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS), /* executor= */ null,
UserHandle.ALL);
}
@Override
public void setupOverlayContentViewControllers() {}
}

View File

@@ -20,6 +20,7 @@ import com.android.systemui.car.keyguard.CarKeyguardViewMediator;
import com.android.systemui.car.notification.BottomNotificationPanelViewMediator;
import com.android.systemui.car.notification.NotificationPanelViewMediator;
import com.android.systemui.car.notification.TopNotificationPanelViewMediator;
import com.android.systemui.car.rvc.RearViewCameraViewMediator;
import com.android.systemui.car.userswitcher.FullscreenUserSwitcherViewMediator;
import com.android.systemui.car.userswitcher.UserSwitchTransitionViewMediator;
@@ -75,4 +76,11 @@ public abstract class OverlayWindowModule {
@ClassKey(UserSwitchTransitionViewMediator.class)
public abstract OverlayViewMediator bindUserSwitchTransitionViewMediator(
UserSwitchTransitionViewMediator userSwitchTransitionViewMediator);
/** Injects RearViewCameraViewMediator. */
@Binds
@IntoMap
@ClassKey(RearViewCameraViewMediator.class)
public abstract OverlayViewMediator bindRearViewCameraViewMediator(
RearViewCameraViewMediator overlayViewsMediator);
}

View File

@@ -0,0 +1,117 @@
/*
* 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.systemui.car.rvc;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.verify;
import android.app.ActivityView;
import android.content.ComponentName;
import android.content.Intent;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.car.CarSystemUiTest;
import com.android.systemui.car.window.OverlayViewGlobalStateController;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@CarSystemUiTest
@RunWith(MockitoJUnitRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
public class RearViewCameraViewControllerTest extends SysuiTestCase {
private static final String TEST_ACTIVITY_NAME = "testPackage/testActivity";
private RearViewCameraViewController mRearViewCameraViewController;
@Mock
private OverlayViewGlobalStateController mOverlayViewGlobalStateController;
@Mock
private ActivityView mMockActivityView;
@Captor
private ArgumentCaptor<Intent> mIntentCaptor;
private void setUpRearViewCameraViewController(String testActivityName) {
mContext.getOrCreateTestableResources().addOverride(
R.string.config_rearViewCameraActivity, testActivityName);
mRearViewCameraViewController = new RearViewCameraViewController(
mContext.getOrCreateTestableResources().getResources(),
mOverlayViewGlobalStateController);
mRearViewCameraViewController.inflate((ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.sysui_overlay_window, /* root= */ null));
}
@Test
public void testEmptyResourceDisablesController() {
setUpRearViewCameraViewController("");
assertThat(mRearViewCameraViewController.isEnabled()).isFalse();
}
@Test
public void testNonEmptyResourceEnablesController() {
setUpRearViewCameraViewController(TEST_ACTIVITY_NAME);
assertThat(mRearViewCameraViewController.isEnabled()).isTrue();
}
@Test
public void testShowInternal() {
setUpRearViewCameraViewController(TEST_ACTIVITY_NAME);
assertThat(mRearViewCameraViewController.isShown()).isFalse();
assertThat(mRearViewCameraViewController.mActivityView).isNull();
mRearViewCameraViewController.showInternal();
assertThat(mRearViewCameraViewController.isShown()).isTrue();
assertThat(mRearViewCameraViewController.mActivityView).isNotNull();
}
@Test
public void testHideInternal() {
setUpRearViewCameraViewController(TEST_ACTIVITY_NAME);
assertThat(mRearViewCameraViewController.isShown()).isFalse();
mRearViewCameraViewController.showInternal();
assertThat(mRearViewCameraViewController.isShown()).isTrue();
mRearViewCameraViewController.hideInternal();
assertThat(mRearViewCameraViewController.isShown()).isFalse();
assertThat(mRearViewCameraViewController.mActivityView).isNull();
}
@Test
public void testOnActivityViewReady_fireIntent() {
setUpRearViewCameraViewController(TEST_ACTIVITY_NAME);
mRearViewCameraViewController.mActivityViewCallback.onActivityViewReady(mMockActivityView);
verify(mMockActivityView).startActivity(mIntentCaptor.capture());
ComponentName expectedComponent = ComponentName.unflattenFromString(TEST_ACTIVITY_NAME);
assertThat(mIntentCaptor.getValue().getComponent()).isEqualTo(expectedComponent);
}
}

View File

@@ -0,0 +1,169 @@
/*
* 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.systemui.car.rvc;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.car.Car;
import android.car.VehicleAreaType;
import android.car.VehicleGear;
import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.car.hardware.property.CarPropertyManager.CarPropertyEventCallback;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.testing.TestableLooper;
import android.util.Log;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.car.CarServiceProvider;
import com.android.systemui.car.CarServiceProvider.CarServiceOnConnectedListener;
import com.android.systemui.car.CarSystemUiTest;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
@CarSystemUiTest
@RunWith(MockitoJUnitRunner.class)
@TestableLooper.RunWithLooper
@SmallTest
public class RearViewCameraViewMediatorTest extends SysuiTestCase {
private static final String TAG = RearViewCameraViewMediatorTest.class.getSimpleName();
private RearViewCameraViewMediator mRearViewCameraViewMediator;
@Mock
private CarServiceProvider mCarServiceProvider;
@Mock
private Car mCar;
@Mock
private CarPropertyManager mCarPropertyManager;
@Captor
private ArgumentCaptor<CarPropertyEventCallback> mCarPropertyEventCallbackCaptor;
@Mock
private BroadcastDispatcher mBroadcastDispatcher;
@Captor
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
@Captor
private ArgumentCaptor<IntentFilter> mIntentFilterCaptor;
@Mock
private RearViewCameraViewController mRearViewCameraViewController;
@Before
public void setUp() throws Exception {
mRearViewCameraViewMediator = new RearViewCameraViewMediator(
mRearViewCameraViewController, mCarServiceProvider, mBroadcastDispatcher);
}
public void setUpListener() {
doAnswer(invocation -> {
CarServiceOnConnectedListener listener = invocation.getArgument(0);
listener.onConnected(mCar);
return null;
}).when(mCarServiceProvider).addListener(any(CarServiceOnConnectedListener.class));
when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager);
when(mRearViewCameraViewController.isEnabled()).thenReturn(true);
mRearViewCameraViewMediator.registerListeners();
verify(mCarPropertyManager).registerCallback(mCarPropertyEventCallbackCaptor.capture(),
eq(VehiclePropertyIds.GEAR_SELECTION), anyFloat());
verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(),
mIntentFilterCaptor.capture(), any(), any());
assertThat(mIntentFilterCaptor.getValue().getAction(0)).isEqualTo(
Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
}
@Test
public void testDoesnNotRegisterListenersWhenRearViewCameraViewControllerIsDisabled() {
when(mRearViewCameraViewController.isEnabled()).thenReturn(false);
mRearViewCameraViewMediator.registerListeners();
verify(mCarPropertyManager, never()).registerCallback(any(), anyInt(), anyFloat());
verify(mBroadcastDispatcher, never()).registerReceiver(any(), any(), any());
}
@Test
public void testGearReverseStartsRearViewCamera() {
setUpListener();
CarPropertyValue<Integer> gearReverse = new CarPropertyValue(
VehiclePropertyIds.GEAR_SELECTION, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL,
VehicleGear.GEAR_REVERSE);
mCarPropertyEventCallbackCaptor.getValue().onChangeEvent(gearReverse);
verify(mRearViewCameraViewController, times(1)).start();
}
@Test
public void testGearNonReverseStopsRearViewCamera() {
setUpListener();
int[] nonReverseVehicleGears = new int[]{
VehicleGear.GEAR_NEUTRAL, VehicleGear.GEAR_PARK, VehicleGear.GEAR_DRIVE,
VehicleGear.GEAR_FIRST
};
for (int i = 0; i < nonReverseVehicleGears.length; ++i) {
Log.i(TAG, "testGearNonReverseStopsRearViewCamera: gear=" + nonReverseVehicleGears[i]);
CarPropertyValue<Integer> propertyGear = new CarPropertyValue(
VehiclePropertyIds.GEAR_SELECTION, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL,
nonReverseVehicleGears[i]);
mCarPropertyEventCallbackCaptor.getValue().onChangeEvent(propertyGear);
verify(mRearViewCameraViewController, times(i + 1)).stop();
}
}
@Test
public void testBroadcastIntentStopsRearViewCamera() {
setUpListener();
when(mRearViewCameraViewController.isShown()).thenReturn(true);
Intent randomIntent = new Intent(Intent.ACTION_MAIN);
mBroadcastReceiverCaptor.getValue().onReceive(mContext, randomIntent);
verify(mRearViewCameraViewController, never()).stop();
Intent actionCloseSystemDialogs = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
mBroadcastReceiverCaptor.getValue().onReceive(mContext, actionCloseSystemDialogs);
verify(mRearViewCameraViewController, times(1)).stop();
}
}