Add username to status bar and update layout
Update the status bar with the new UX designs: - Remove driver and passenger HVAC views - Add driver icon (placeholder) and username aligned to start of bar - Move system icons aligned to end of bar (previously next to clock) - Add AM/PM to clock HVAC will be moved into the navigation bar in a separate change. Test: manual - change to guest, change username, change to long username (truncates before clock view) Test: atest :carsysui-presubmit Bug: 162598687 Change-Id: I5b9095adce7fee0970e8b15d307f01eb4adf2b40
This commit is contained in:
committed by
Julia Kawano
parent
cf259d5288
commit
224c81c6da
25
packages/CarSystemUI/res/drawable/car_ic_user_icon.xml
Normal file
25
packages/CarSystemUI/res/drawable/car_ic_user_icon.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?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.
|
||||
-->
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="@dimen/system_bar_icon_drawing_size"
|
||||
android:height="@dimen/system_bar_icon_drawing_size"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"
|
||||
android:fillColor="@color/system_bar_user_icon_color"/>
|
||||
</vector>
|
||||
@@ -31,39 +31,44 @@
|
||||
android:layoutDirection="ltr">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/left_hvac_container"
|
||||
android:id="@+id/user_name_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_toStartOf="@+id/clock_container"
|
||||
>
|
||||
|
||||
<com.android.systemui.car.navigationbar.CarNavigationButton
|
||||
android:id="@+id/hvacleft"
|
||||
android:id="@+id/user_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@null"
|
||||
systemui:broadcast="true"
|
||||
systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
|
||||
/>
|
||||
|
||||
<com.android.systemui.car.hvac.AnimatedTemperatureView
|
||||
android:id="@+id/lefttext"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="@*android:dimen/car_padding_4"
|
||||
android:paddingEnd="16dp"
|
||||
android:gravity="center_vertical|start"
|
||||
android:minEms="4"
|
||||
android:textAppearance="@style/TextAppearance.CarStatus"
|
||||
systemui:hvacAreaId="49"
|
||||
systemui:hvacMaxText="@string/hvac_max_text"
|
||||
systemui:hvacMaxValue="@dimen/hvac_max_value"
|
||||
systemui:hvacMinText="@string/hvac_min_text"
|
||||
systemui:hvacMinValue="@dimen/hvac_min_value"
|
||||
systemui:hvacPivotOffset="60dp"
|
||||
systemui:hvacPropertyId="358614275"
|
||||
systemui:hvacTempFormat="%.0f\u00B0"
|
||||
/>
|
||||
systemui:icon="@null"
|
||||
systemui:intent="intent:#Intent;component=com.android.car.settings/.users.UserSwitcherActivity;launchFlags=0x24000000;end"
|
||||
>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
>
|
||||
<ImageView
|
||||
android:id="@+id/user_avatar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/car_ic_user_icon"
|
||||
android:paddingLeft="@dimen/system_bar_user_icon_padding"
|
||||
android:paddingRight="@dimen/system_bar_user_icon_padding"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/user_name_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center_vertical"
|
||||
android:textAppearance="@style/TextAppearance.SystemBar.Username"
|
||||
android:maxLines="1"
|
||||
/>
|
||||
</LinearLayout>
|
||||
</com.android.systemui.car.navigationbar.CarNavigationButton>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
@@ -86,7 +91,8 @@
|
||||
android:layout_gravity="center"
|
||||
android:elevation="5dp"
|
||||
android:singleLine="true"
|
||||
android:textAppearance="@style/TextAppearance.StatusBar.Clock"
|
||||
android:textAppearance="@style/TextAppearance.SystemBar.Clock"
|
||||
systemui:amPmStyle="normal"
|
||||
/>
|
||||
</FrameLayout>
|
||||
|
||||
@@ -94,10 +100,9 @@
|
||||
android:id="@+id/system_icon_area"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toEndOf="@+id/clock_container"
|
||||
android:paddingStart="@*android:dimen/car_padding_1"
|
||||
android:paddingEnd="@*android:dimen/car_padding_1"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
>
|
||||
@@ -107,46 +112,9 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:paddingStart="4dp"
|
||||
android:gravity="center_vertical"
|
||||
/>
|
||||
</LinearLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/right_hvac_container"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentEnd="true"
|
||||
>
|
||||
|
||||
<com.android.systemui.car.navigationbar.CarNavigationButton
|
||||
android:id="@+id/hvacright"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@null"
|
||||
systemui:broadcast="true"
|
||||
systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
|
||||
/>
|
||||
|
||||
<com.android.systemui.car.hvac.AnimatedTemperatureView
|
||||
android:id="@+id/righttext"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="@*android:dimen/car_padding_4"
|
||||
android:gravity="center_vertical|end"
|
||||
android:minEms="4"
|
||||
android:textAppearance="@style/TextAppearance.CarStatus"
|
||||
systemui:hvacAreaId="68"
|
||||
systemui:hvacMaxText="@string/hvac_max_text"
|
||||
systemui:hvacMaxValue="@dimen/hvac_max_value"
|
||||
systemui:hvacMinText="@string/hvac_min_text"
|
||||
systemui:hvacMinValue="@dimen/hvac_min_value"
|
||||
systemui:hvacPivotOffset="60dp"
|
||||
systemui:hvacPropertyId="358614275"
|
||||
systemui:hvacTempFormat="%.0f\u00B0"
|
||||
/>
|
||||
</FrameLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
</com.android.systemui.car.navigationbar.CarNavigationBarView>
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
<color name="docked_divider_background">@*android:color/car_grey_50</color>
|
||||
<color name="system_bar_background_opaque">#ff172026</color>
|
||||
|
||||
<!-- colors for status bar -->
|
||||
<color name="system_bar_user_icon_color">#ffffff</color>
|
||||
<color name="status_bar_background_color">#33000000</color>
|
||||
<drawable name="system_bar_background">@color/status_bar_background_color</drawable>
|
||||
|
||||
|
||||
@@ -46,8 +46,9 @@
|
||||
in frameworks/base/core package and thus will have no effect if
|
||||
set here. See car_product overlay for car specific defaults-->
|
||||
|
||||
<dimen name="status_bar_icon_drawing_size_dark">36dp</dimen>
|
||||
<dimen name="status_bar_icon_drawing_size">36dp</dimen>
|
||||
<dimen name="system_bar_user_icon_padding">16dp</dimen>
|
||||
<dimen name="system_bar_icon_drawing_size_dark">36dp</dimen>
|
||||
<dimen name="system_bar_icon_drawing_size">36dp</dimen>
|
||||
<!-- The amount by which to scale up the status bar icons. -->
|
||||
<item name="status_bar_icon_scale_factor" format="float" type="dimen">1.75</item>
|
||||
|
||||
|
||||
@@ -25,11 +25,16 @@
|
||||
<item name="android:padding">22dp</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.StatusBar.Clock"
|
||||
parent="@*android:style/TextAppearance.StatusBar.Icon">
|
||||
<item name="android:textSize">42sp</item>
|
||||
<item name="android:fontFamily">sans-serif-regular</item>
|
||||
<item name="android:textColor">@*android:color/car_grey_50</item>
|
||||
<style name="TextAppearance.SystemBar.Clock"
|
||||
parent="@*android:style/TextAppearance.StatusBar.Icon">
|
||||
<item name="android:textSize">@dimen/car_body1_size</item>
|
||||
<item name="android:textColor">@*android:color/car_headline3</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.SystemBar.Username"
|
||||
parent="@android:style/TextAppearance.DeviceDefault">
|
||||
<item name="android:textSize">@dimen/car_body3_size</item>
|
||||
<item name="android:textColor">@*android:color/car_headline3</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.CarStatus" parent="@android:style/TextAppearance.DeviceDefault">
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.view.ViewGroup;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.android.systemui.car.hvac.HvacController;
|
||||
import com.android.systemui.car.statusbar.UserNameViewController;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -38,6 +39,7 @@ public class CarNavigationBarController {
|
||||
private final ButtonSelectionStateController mButtonSelectionStateController;
|
||||
private final ButtonRoleHolderController mButtonRoleHolderController;
|
||||
private final Lazy<HvacController> mHvacControllerLazy;
|
||||
private final Lazy<UserNameViewController> mUserNameViewControllerLazy;
|
||||
|
||||
private boolean mShowTop;
|
||||
private boolean mShowBottom;
|
||||
@@ -60,12 +62,14 @@ public class CarNavigationBarController {
|
||||
NavigationBarViewFactory navigationBarViewFactory,
|
||||
ButtonSelectionStateController buttonSelectionStateController,
|
||||
Lazy<HvacController> hvacControllerLazy,
|
||||
Lazy<UserNameViewController> userNameViewControllerLazy,
|
||||
ButtonRoleHolderController buttonRoleHolderController,
|
||||
SystemBarConfigs systemBarConfigs) {
|
||||
mContext = context;
|
||||
mNavigationBarViewFactory = navigationBarViewFactory;
|
||||
mButtonSelectionStateController = buttonSelectionStateController;
|
||||
mHvacControllerLazy = hvacControllerLazy;
|
||||
mUserNameViewControllerLazy = userNameViewControllerLazy;
|
||||
mButtonRoleHolderController = buttonRoleHolderController;
|
||||
|
||||
// Read configuration.
|
||||
@@ -109,6 +113,7 @@ public class CarNavigationBarController {
|
||||
mHvacControllerLazy.get().removeAllComponents();
|
||||
mButtonSelectionStateController.removeAll();
|
||||
mButtonRoleHolderController.removeAll();
|
||||
mUserNameViewControllerLazy.get().removeAll();
|
||||
}
|
||||
|
||||
/** Gets the top window if configured to do so. */
|
||||
@@ -218,6 +223,7 @@ public class CarNavigationBarController {
|
||||
mButtonSelectionStateController.addAllButtonsWithSelectionState(view);
|
||||
mButtonRoleHolderController.addAllButtonsWithRoleName(view);
|
||||
mHvacControllerLazy.get().addTemperatureViewToController(view);
|
||||
mUserNameViewControllerLazy.get().addUserNameView(view);
|
||||
}
|
||||
|
||||
/** Sets a touch listener for the top navigation bar. */
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* 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.statusbar;
|
||||
|
||||
import android.car.Car;
|
||||
import android.car.user.CarUserManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.car.CarDeviceProvisionedController;
|
||||
import com.android.systemui.car.CarServiceProvider;
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Controls a TextView with the current driver's username
|
||||
*/
|
||||
@SysUISingleton
|
||||
public class UserNameViewController {
|
||||
private static final String TAG = "UserNameViewController";
|
||||
|
||||
private Context mContext;
|
||||
private UserManager mUserManager;
|
||||
private CarUserManager mCarUserManager;
|
||||
private CarServiceProvider mCarServiceProvider;
|
||||
private CarDeviceProvisionedController mCarDeviceProvisionedController;
|
||||
private BroadcastDispatcher mBroadcastDispatcher;
|
||||
private TextView mUserNameView;
|
||||
|
||||
private final BroadcastReceiver mUserUpdateReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
updateUser(mCarDeviceProvisionedController.getCurrentUser());
|
||||
}
|
||||
};
|
||||
|
||||
private final CarUserManager.UserLifecycleListener mUserLifecycleListener =
|
||||
new CarUserManager.UserLifecycleListener() {
|
||||
@Override
|
||||
public void onEvent(CarUserManager.UserLifecycleEvent event) {
|
||||
if (event.getEventType()
|
||||
== CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING) {
|
||||
updateUser(event.getUserId());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Inject
|
||||
public UserNameViewController(Context context, CarServiceProvider carServiceProvider,
|
||||
UserManager userManager, BroadcastDispatcher broadcastDispatcher,
|
||||
CarDeviceProvisionedController carDeviceProvisionedController) {
|
||||
mContext = context;
|
||||
mCarServiceProvider = carServiceProvider;
|
||||
mUserManager = userManager;
|
||||
mBroadcastDispatcher = broadcastDispatcher;
|
||||
mCarDeviceProvisionedController = carDeviceProvisionedController;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the {@link TextView} for the driver's user name from a view and if found set it with the
|
||||
* current driver's user name.
|
||||
*/
|
||||
public void addUserNameView(View v) {
|
||||
TextView userNameView = v.findViewById(R.id.user_name_text);
|
||||
if (userNameView != null) {
|
||||
if (mUserNameView == null) {
|
||||
registerForUserChangeEvents();
|
||||
}
|
||||
mUserNameView = userNameView;
|
||||
updateUser(mCarDeviceProvisionedController.getCurrentUser());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up the controller and unregister receiver.
|
||||
*/
|
||||
public void removeAll() {
|
||||
mBroadcastDispatcher.unregisterReceiver(mUserUpdateReceiver);
|
||||
if (mCarUserManager != null) {
|
||||
mCarUserManager.removeListener(mUserLifecycleListener);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerForUserChangeEvents() {
|
||||
// Register for user switching
|
||||
mCarServiceProvider.addListener(car -> {
|
||||
mCarUserManager = (CarUserManager) car.getCarManager(Car.CAR_USER_SERVICE);
|
||||
if (mCarUserManager != null) {
|
||||
mCarUserManager.addListener(Runnable::run, mUserLifecycleListener);
|
||||
} else {
|
||||
Log.e(TAG, "CarUserManager could not be obtained.");
|
||||
}
|
||||
});
|
||||
// Also register for user info changing
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_USER_INFO_CHANGED);
|
||||
mBroadcastDispatcher.registerReceiver(mUserUpdateReceiver, filter, /* executor= */ null,
|
||||
UserHandle.ALL);
|
||||
}
|
||||
|
||||
private void updateUser(int userId) {
|
||||
if (mUserNameView != null) {
|
||||
UserInfo currentUserInfo = mUserManager.getUserInfo(userId);
|
||||
mUserNameView.setText(currentUserInfo.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.car.CarSystemUiTest;
|
||||
import com.android.systemui.car.hvac.HvacController;
|
||||
import com.android.systemui.car.statusbar.UserNameViewController;
|
||||
import com.android.systemui.plugins.DarkIconDispatcher;
|
||||
import com.android.systemui.statusbar.phone.StatusBarIconController;
|
||||
|
||||
@@ -58,6 +59,8 @@ public class CarNavigationBarControllerTest extends SysuiTestCase {
|
||||
private ButtonRoleHolderController mButtonRoleHolderController;
|
||||
@Mock
|
||||
private HvacController mHvacController;
|
||||
@Mock
|
||||
private UserNameViewController mUserNameViewController;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@@ -73,7 +76,7 @@ public class CarNavigationBarControllerTest extends SysuiTestCase {
|
||||
private CarNavigationBarController createNavigationBarController() {
|
||||
return new CarNavigationBarController(mContext, mNavigationBarViewFactory,
|
||||
mButtonSelectionStateController, () -> mHvacController,
|
||||
mButtonRoleHolderController,
|
||||
() -> mUserNameViewController, mButtonRoleHolderController,
|
||||
new SystemBarConfigs(mTestableResources.getResources()));
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* 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.statusbar;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.car.Car;
|
||||
import android.car.user.CarUserManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.UserManager;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher;
|
||||
import com.android.systemui.car.CarDeviceProvisionedController;
|
||||
import com.android.systemui.car.CarServiceProvider;
|
||||
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.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@CarSystemUiTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
@TestableLooper.RunWithLooper
|
||||
@SmallTest
|
||||
public class UserNameViewControllerTest extends SysuiTestCase {
|
||||
|
||||
private final UserInfo mUserInfo1 = new UserInfo(/* id= */ 0, "Test User Name", /* flags= */ 0);
|
||||
private final UserInfo mUserInfo2 = new UserInfo(/* id= */ 1, "Another User", /* flags= */ 0);
|
||||
private TextView mTextView;
|
||||
private UserNameViewController mUserNameViewController;
|
||||
|
||||
@Mock
|
||||
private Car mCar;
|
||||
@Mock
|
||||
private CarUserManager mCarUserManager;
|
||||
@Mock
|
||||
private UserManager mUserManager;
|
||||
@Mock
|
||||
private CarDeviceProvisionedController mCarDeviceProvisionedController;
|
||||
@Mock
|
||||
private BroadcastDispatcher mBroadcastDispatcher;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
when(mUserManager.getUserInfo(mUserInfo1.id)).thenReturn(mUserInfo1);
|
||||
when(mUserManager.getUserInfo(mUserInfo2.id)).thenReturn(mUserInfo2);
|
||||
when(mCar.isConnected()).thenReturn(true);
|
||||
when(mCar.getCarManager(Car.CAR_USER_SERVICE)).thenReturn(mCarUserManager);
|
||||
|
||||
CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar);
|
||||
mUserNameViewController = new UserNameViewController(getContext(), carServiceProvider,
|
||||
mUserManager, mBroadcastDispatcher, mCarDeviceProvisionedController);
|
||||
|
||||
mTextView = new TextView(getContext());
|
||||
mTextView.setId(R.id.user_name_text);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addUserNameViewToController_updatesUserNameView() {
|
||||
when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(mUserInfo1.id);
|
||||
|
||||
mUserNameViewController.addUserNameView(mTextView);
|
||||
|
||||
assertEquals(mTextView.getText(), mUserInfo1.name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addUserNameViewToController_withNoTextView_doesNotUpdate() {
|
||||
View nullView = new View(getContext());
|
||||
mUserNameViewController.addUserNameView(nullView);
|
||||
|
||||
assertEquals(mTextView.getText(), "");
|
||||
verifyZeroInteractions(mCarDeviceProvisionedController);
|
||||
verifyZeroInteractions(mCarUserManager);
|
||||
verifyZeroInteractions(mUserManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userLifecycleListener_onUserSwitchLifecycleEvent_updatesUserNameView() {
|
||||
ArgumentCaptor<CarUserManager.UserLifecycleListener> userLifecycleListenerArgumentCaptor =
|
||||
ArgumentCaptor.forClass(CarUserManager.UserLifecycleListener.class);
|
||||
when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(mUserInfo1.id);
|
||||
// Add the initial TextView, which registers the UserLifecycleListener
|
||||
mUserNameViewController.addUserNameView(mTextView);
|
||||
assertEquals(mTextView.getText(), mUserInfo1.name);
|
||||
verify(mCarUserManager).addListener(any(), userLifecycleListenerArgumentCaptor.capture());
|
||||
|
||||
CarUserManager.UserLifecycleEvent event = new CarUserManager.UserLifecycleEvent(
|
||||
CarUserManager.USER_LIFECYCLE_EVENT_TYPE_SWITCHING, /* from= */ mUserInfo1.id,
|
||||
/* to= */ mUserInfo2.id);
|
||||
userLifecycleListenerArgumentCaptor.getValue().onEvent(event);
|
||||
|
||||
assertEquals(mTextView.getText(), mUserInfo2.name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userInfoChangedBroadcast_withoutInitializingUserNameView_doesNothing() {
|
||||
getContext().sendBroadcast(new Intent(Intent.ACTION_USER_INFO_CHANGED));
|
||||
|
||||
assertEquals(mTextView.getText(), "");
|
||||
verifyZeroInteractions(mCarDeviceProvisionedController);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void userInfoChangedBroadcast_withUserNameViewInitialized_updatesUserNameView() {
|
||||
ArgumentCaptor<BroadcastReceiver> broadcastReceiverArgumentCaptor = ArgumentCaptor.forClass(
|
||||
BroadcastReceiver.class);
|
||||
when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(mUserInfo1.id);
|
||||
mUserNameViewController.addUserNameView(mTextView);
|
||||
assertEquals(mTextView.getText(), mUserInfo1.name);
|
||||
verify(mBroadcastDispatcher).registerReceiver(broadcastReceiverArgumentCaptor.capture(),
|
||||
any(), any(), any());
|
||||
|
||||
reset(mCarDeviceProvisionedController);
|
||||
when(mCarDeviceProvisionedController.getCurrentUser()).thenReturn(mUserInfo2.id);
|
||||
broadcastReceiverArgumentCaptor.getValue().onReceive(getContext(),
|
||||
new Intent(Intent.ACTION_USER_INFO_CHANGED));
|
||||
|
||||
assertEquals(mTextView.getText(), mUserInfo2.name);
|
||||
verify(mCarDeviceProvisionedController).getCurrentUser();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user