Merge "Import translations. DO NOT MERGE ANYWHERE" into sc-v2-dev
diff --git a/cpp/security/vehicle_binding_util/tests/Android.bp b/cpp/security/vehicle_binding_util/tests/Android.bp
index d47b8e5..69a61cf 100644
--- a/cpp/security/vehicle_binding_util/tests/Android.bp
+++ b/cpp/security/vehicle_binding_util/tests/Android.bp
@@ -37,7 +37,6 @@
name: "vehicle_binding_integration_test",
test_suites: [
"device-tests",
- "vts"
],
require_root: true,
defaults: ["vehicle_binding_util_defaults"],
diff --git a/service/src/com/android/car/am/FixedActivityService.java b/service/src/com/android/car/am/FixedActivityService.java
index bbc76ff..c969fc1 100644
--- a/service/src/com/android/car/am/FixedActivityService.java
+++ b/service/src/com/android/car/am/FixedActivityService.java
@@ -61,6 +61,7 @@
import com.android.car.R;
import com.android.car.user.CarUserService;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import java.util.List;
@@ -417,12 +418,20 @@
return false;
}
for (int i = mRunningActivities.size() - 1; i >= 0; i--) {
+ int displayIdForActivity = mRunningActivities.keyAt(i);
+ Display display = mDm.getDisplay(displayIdForActivity);
+ if (display == null) {
+ Slog.e(TAG_AM, "Stop fixed activity for non-available display"
+ + displayIdForActivity);
+ mRunningActivities.removeAt(i);
+ continue;
+ }
+
RunningActivityInfo activityInfo = mRunningActivities.valueAt(i);
activityInfo.isVisible = false;
if (isUserAllowedToLaunchActivity(activityInfo.userId)) {
continue;
}
- final int displayIdForActivity = mRunningActivities.keyAt(i);
if (activityInfo.taskId != INVALID_TASK_ID) {
Slog.i(TAG_AM, "Finishing fixed activity on user switching:"
+ activityInfo);
@@ -432,12 +441,6 @@
Slog.e(TAG_AM, "remote exception from AM", e);
}
CarServiceUtils.runOnMain(() -> {
- Display display = mDm.getDisplay(displayIdForActivity);
- if (display == null) {
- Slog.e(TAG_AM, "Display not available, cannot launnch window:"
- + displayIdForActivity);
- return;
- }
Presentation p = new Presentation(mContext, display,
android.R.style.Theme_Black_NoTitleBar_Fullscreen,
// TYPE_PRESENTATION can't be used in the internal display.
@@ -546,7 +549,8 @@
}
}
- private void launchIfNecessary() {
+ @VisibleForTesting
+ void launchIfNecessary() {
launchIfNecessary(Display.INVALID_DISPLAY);
}
@@ -609,6 +613,13 @@
return true;
}
+ @VisibleForTesting
+ RunningActivityInfo getRunningFixedActivity(int displayId) {
+ synchronized (mLock) {
+ return mRunningActivities.get(displayId);
+ }
+ }
+
/**
* Checks {@link InstrumentClusterRenderingService#startFixedActivityModeForDisplayAndUser(
* Intent, ActivityOptions, int)}
diff --git a/service/src/com/android/car/cluster/ClusterHomeService.java b/service/src/com/android/car/cluster/ClusterHomeService.java
index b032d93..3af771a 100644
--- a/service/src/com/android/car/cluster/ClusterHomeService.java
+++ b/service/src/com/android/car/cluster/ClusterHomeService.java
@@ -84,6 +84,7 @@
private Insets mInsets = Insets.NONE;
private int mUiType = ClusterHomeManager.UI_TYPE_CLUSTER_HOME;
private Intent mLastIntent;
+ private int mLastIntentUserId = UserHandle.USER_SYSTEM;
private final RemoteCallbackList<IClusterHomeCallback> mClientCallbacks =
new RemoteCallbackList<>();
@@ -126,6 +127,7 @@
private void initClusterDisplay() {
int clusterDisplayId = mOccupantZoneService.getDisplayIdForDriver(
CarOccupantZoneManager.DISPLAY_TYPE_INSTRUMENT_CLUSTER);
+ Slogf.d(TAG, "initClusterDisplay: displayId=%d", clusterDisplayId);
if (clusterDisplayId == Display.INVALID_DISPLAY) {
Slogf.i(TAG, "No cluster display is defined");
}
@@ -152,7 +154,7 @@
ActivityOptions activityOptions = ActivityOptions.makeBasic()
.setLaunchDisplayId(clusterDisplayId);
mFixedActivityService.startFixedActivityModeForDisplayAndUser(
- mLastIntent, activityOptions, clusterDisplayId, UserHandle.USER_SYSTEM);
+ mLastIntent, activityOptions, clusterDisplayId, mLastIntentUserId);
}
private final ICarOccupantZoneCallback mOccupantZoneCallback =
@@ -292,6 +294,7 @@
@Override
public boolean startFixedActivityModeAsUser(Intent intent,
Bundle activityOptionsBundle, int userId) {
+ Slogf.d(TAG, "startFixedActivityModeAsUser: intent=%s, userId=%d", intent, userId);
enforcePermission(Car.PERMISSION_CAR_INSTRUMENT_CLUSTER_CONTROL);
if (!mServiceEnabled) throw new IllegalStateException("Service is not enabled");
if (mClusterDisplayId == Display.INVALID_DISPLAY) {
@@ -302,6 +305,7 @@
ActivityOptions activityOptions = ActivityOptions.fromBundle(activityOptionsBundle);
activityOptions.setLaunchDisplayId(mClusterDisplayId);
mLastIntent = intent;
+ mLastIntentUserId = userId;
return mFixedActivityService.startFixedActivityModeForDisplayAndUser(
intent, activityOptions, mClusterDisplayId, userId);
}
diff --git a/tests/carservice_unit_test/src/com/android/car/am/FixedActivityServiceTest.java b/tests/carservice_unit_test/src/com/android/car/am/FixedActivityServiceTest.java
index b22831d..4a9f0c7 100644
--- a/tests/carservice_unit_test/src/com/android/car/am/FixedActivityServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/am/FixedActivityServiceTest.java
@@ -87,6 +87,8 @@
private CarUserService mCarUserService;
@Mock
private CarPowerManager mCarPowerManager;
+ @Mock
+ private Display mValidDisplay;
private FixedActivityService mFixedActivityService;
@@ -102,6 +104,7 @@
when(mContext.getPackageManager()).thenReturn(mPackageManager);
doReturn(mCarUserService).when(() -> CarLocalServices.getService(CarUserService.class));
doReturn(mCarPowerManager).when(() -> CarLocalServices.createCarPowerManager(mContext));
+ when(mDisplayManager.getDisplay(mValidDisplayId)).thenReturn(mValidDisplay);
mFixedActivityService = new FixedActivityService(mContext, mActivityManager, mUserManager,
mDisplayManager);
}
@@ -252,6 +255,7 @@
assertThat(ret).isTrue();
int anotherValidDisplayId = mValidDisplayId + 1;
+ when(mDisplayManager.getDisplay(anotherValidDisplayId)).thenReturn(mValidDisplay);
ret = mFixedActivityService.startFixedActivityModeForDisplayAndUser(anotherIntent,
options, anotherValidDisplayId, userId);
verify(mContext).startActivityAsUser(eq(anotherIntent), any(Bundle.class),
@@ -272,6 +276,46 @@
}
@Test
+ public void testStartFixedActivityModeForDisplayAndUser_unavailableDisplay() {
+ int userId = 10;
+ Intent intent = new Intent(Intent.ACTION_MAIN);
+ ActivityOptions options = new ActivityOptions(new Bundle());
+ int unavailableDisplayId = mValidDisplayId + 1;
+
+ boolean started = mFixedActivityService.startFixedActivityModeForDisplayAndUser(
+ intent, options, unavailableDisplayId, userId);
+ assertThat(started).isFalse();
+ }
+
+ @Test
+ public void testStartFixedActivityModeForDisplayAndUser_displayRemoved()
+ throws Exception {
+ int displayToBeRemoved = mValidDisplayId + 1;
+ when(mDisplayManager.getDisplay(displayToBeRemoved)).thenReturn(
+ mValidDisplay, // for startFixedActivityModeForDisplayAndUser
+ mValidDisplay, // for launchIf
+ null);
+ int userId = 10;
+ ActivityOptions options = new ActivityOptions(new Bundle());
+ Intent intent = expectComponentAvailable("test_package", "com.test.dude", userId);
+ mockAmGetCurrentUser(userId);
+ expectNoActivityStack();
+
+ boolean started = mFixedActivityService.startFixedActivityModeForDisplayAndUser(
+ intent, options, displayToBeRemoved, userId);
+ assertThat(started).isTrue();
+ assertThat(mFixedActivityService.getRunningFixedActivity(displayToBeRemoved)).isNotNull();
+
+ // The display is still valid.
+ mFixedActivityService.launchIfNecessary();
+ assertThat(mFixedActivityService.getRunningFixedActivity(displayToBeRemoved)).isNotNull();
+
+ // The display is removed.
+ mFixedActivityService.launchIfNecessary();
+ assertThat(mFixedActivityService.getRunningFixedActivity(displayToBeRemoved)).isNull();
+ }
+
+ @Test
public void testStartFixedActivityModeForDisplayAndUser_notAllowedUser() {
int currentUserId = 10;
int notAllowedUserId = 11;