Loading services/core/java/com/android/server/wm/CameraIdPackageNameBiMapping.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.server.wm; import android.annotation.NonNull; import android.annotation.Nullable; import android.util.ArrayMap; import java.util.Map; /** * Bidirectional mapping (1:1) for the currently active cameraId and the app package that opened it. * * <p>This class is not thread-safe. */ final class CameraIdPackageNameBiMapping { private final Map<String, String> mPackageToCameraIdMap = new ArrayMap<>(); private final Map<String, String> mCameraIdToPackageMap = new ArrayMap<>(); boolean isEmpty() { return mCameraIdToPackageMap.isEmpty(); } void put(@NonNull String packageName, @NonNull String cameraId) { // Always using the last connected camera ID for the package even for the concurrent // camera use case since we can't guess which camera is more important anyway. removePackageName(packageName); removeCameraId(cameraId); mPackageToCameraIdMap.put(packageName, cameraId); mCameraIdToPackageMap.put(cameraId, packageName); } boolean containsPackageName(@NonNull String packageName) { return mPackageToCameraIdMap.containsKey(packageName); } @Nullable String getCameraId(@NonNull String packageName) { return mPackageToCameraIdMap.get(packageName); } void removeCameraId(@NonNull String cameraId) { final String packageName = mCameraIdToPackageMap.get(cameraId); if (packageName == null) { return; } mPackageToCameraIdMap.remove(packageName, cameraId); mCameraIdToPackageMap.remove(cameraId, packageName); } @NonNull String getSummaryForDisplayRotationHistoryRecord() { return "{ mPackageToCameraIdMap=" + mPackageToCameraIdMap + " }"; } private void removePackageName(@NonNull String packageName) { String cameraId = mPackageToCameraIdMap.get(packageName); if (cameraId == null) { return; } mPackageToCameraIdMap.remove(packageName, cameraId); mCameraIdToPackageMap.remove(cameraId, packageName); } } services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java +2 −53 Original line number Diff line number Diff line Loading @@ -46,7 +46,6 @@ import android.content.res.Configuration; import android.hardware.camera2.CameraManager; import android.os.Handler; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; import android.widget.Toast; Loading @@ -56,7 +55,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.server.UiThread; import java.util.Map; import java.util.Set; /** Loading Loading @@ -100,7 +98,8 @@ final class DisplayRotationCompatPolicy { // camera id by a package name when determining rotation; 2) get a package name by a camera id // when camera connection is closed and we need to clean up our records. @GuardedBy("this") private final CameraIdPackageNameBiMap mCameraIdPackageBiMap = new CameraIdPackageNameBiMap(); private final CameraIdPackageNameBiMapping mCameraIdPackageBiMap = new CameraIdPackageNameBiMapping(); @GuardedBy("this") private final Set<String> mScheduledToBeRemovedCameraIdSet = new ArraySet<>(); @GuardedBy("this") Loading Loading @@ -516,54 +515,4 @@ final class DisplayRotationCompatPolicy { } return topActivity.mLetterboxUiController.isRefreshAfterRotationRequested(); } private static class CameraIdPackageNameBiMap { private final Map<String, String> mPackageToCameraIdMap = new ArrayMap<>(); private final Map<String, String> mCameraIdToPackageMap = new ArrayMap<>(); boolean isEmpty() { return mCameraIdToPackageMap.isEmpty(); } void put(String packageName, String cameraId) { // Always using the last connected camera ID for the package even for the concurrent // camera use case since we can't guess which camera is more important anyway. removePackageName(packageName); removeCameraId(cameraId); mPackageToCameraIdMap.put(packageName, cameraId); mCameraIdToPackageMap.put(cameraId, packageName); } boolean containsPackageName(String packageName) { return mPackageToCameraIdMap.containsKey(packageName); } @Nullable String getCameraId(String packageName) { return mPackageToCameraIdMap.get(packageName); } void removeCameraId(String cameraId) { String packageName = mCameraIdToPackageMap.get(cameraId); if (packageName == null) { return; } mPackageToCameraIdMap.remove(packageName, cameraId); mCameraIdToPackageMap.remove(cameraId, packageName); } String getSummaryForDisplayRotationHistoryRecord() { return "{ mPackageToCameraIdMap=" + mPackageToCameraIdMap + " }"; } private void removePackageName(String packageName) { String cameraId = mPackageToCameraIdMap.get(packageName); if (cameraId == null) { return; } mPackageToCameraIdMap.remove(packageName, cameraId); mCameraIdToPackageMap.remove(cameraId, packageName); } } } services/tests/wmtests/src/com/android/server/wm/CameraIdPackageNameBiMappingTests.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.server.wm; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; /** * Tests for {@link CameraIdPackageNameBiMapping}. * * Build/Install/Run: * atest WmTests:CameraIdPackageNameBiMapTests */ @SmallTest @Presubmit public class CameraIdPackageNameBiMappingTests { private CameraIdPackageNameBiMapping mMapping; private static final String PACKAGE_1 = "PACKAGE_1"; private static final String PACKAGE_2 = "PACKAGE_2"; private static final String CAMERA_ID_1 = "1234"; private static final String CAMERA_ID_2 = "5678"; @Before public void setUp() { mMapping = new CameraIdPackageNameBiMapping(); } @Test public void mappingEmptyAtStart() { assertTrue(mMapping.isEmpty()); } @Test public void addPackageAndId_containsPackage() { mMapping.put(PACKAGE_1, CAMERA_ID_1); assertTrue(mMapping.containsPackageName(PACKAGE_1)); } @Test public void addTwoPackagesAndId_containsPackages() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.put(PACKAGE_2, CAMERA_ID_2); assertTrue(mMapping.containsPackageName(PACKAGE_1)); assertTrue(mMapping.containsPackageName(PACKAGE_2)); } @Test public void addPackageAndId_mapContainsPackageAndId() { mMapping.put(PACKAGE_1, CAMERA_ID_1); assertEquals(CAMERA_ID_1, mMapping.getCameraId(PACKAGE_1)); } @Test public void changeCameraId_newestCameraId() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.put(PACKAGE_1, CAMERA_ID_2); assertEquals(CAMERA_ID_2, mMapping.getCameraId(PACKAGE_1)); } @Test public void changePackage_newestPackage() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.put(PACKAGE_2, CAMERA_ID_1); assertFalse(mMapping.containsPackageName(PACKAGE_1)); assertTrue(mMapping.containsPackageName(PACKAGE_2)); assertEquals(CAMERA_ID_1, mMapping.getCameraId(PACKAGE_2)); } @Test public void addAndRemoveCameraId_containsOtherPackage() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.put(PACKAGE_2, CAMERA_ID_2); mMapping.removeCameraId(CAMERA_ID_1); assertFalse(mMapping.containsPackageName(PACKAGE_1)); assertTrue(mMapping.containsPackageName(PACKAGE_2)); } @Test public void addAndRemoveOnlyCameraId_empty() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.removeCameraId(CAMERA_ID_1); assertTrue(mMapping.isEmpty()); } } Loading
services/core/java/com/android/server/wm/CameraIdPackageNameBiMapping.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.server.wm; import android.annotation.NonNull; import android.annotation.Nullable; import android.util.ArrayMap; import java.util.Map; /** * Bidirectional mapping (1:1) for the currently active cameraId and the app package that opened it. * * <p>This class is not thread-safe. */ final class CameraIdPackageNameBiMapping { private final Map<String, String> mPackageToCameraIdMap = new ArrayMap<>(); private final Map<String, String> mCameraIdToPackageMap = new ArrayMap<>(); boolean isEmpty() { return mCameraIdToPackageMap.isEmpty(); } void put(@NonNull String packageName, @NonNull String cameraId) { // Always using the last connected camera ID for the package even for the concurrent // camera use case since we can't guess which camera is more important anyway. removePackageName(packageName); removeCameraId(cameraId); mPackageToCameraIdMap.put(packageName, cameraId); mCameraIdToPackageMap.put(cameraId, packageName); } boolean containsPackageName(@NonNull String packageName) { return mPackageToCameraIdMap.containsKey(packageName); } @Nullable String getCameraId(@NonNull String packageName) { return mPackageToCameraIdMap.get(packageName); } void removeCameraId(@NonNull String cameraId) { final String packageName = mCameraIdToPackageMap.get(cameraId); if (packageName == null) { return; } mPackageToCameraIdMap.remove(packageName, cameraId); mCameraIdToPackageMap.remove(cameraId, packageName); } @NonNull String getSummaryForDisplayRotationHistoryRecord() { return "{ mPackageToCameraIdMap=" + mPackageToCameraIdMap + " }"; } private void removePackageName(@NonNull String packageName) { String cameraId = mPackageToCameraIdMap.get(packageName); if (cameraId == null) { return; } mPackageToCameraIdMap.remove(packageName, cameraId); mCameraIdToPackageMap.remove(cameraId, packageName); } }
services/core/java/com/android/server/wm/DisplayRotationCompatPolicy.java +2 −53 Original line number Diff line number Diff line Loading @@ -46,7 +46,6 @@ import android.content.res.Configuration; import android.hardware.camera2.CameraManager; import android.os.Handler; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; import android.widget.Toast; Loading @@ -56,7 +55,6 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.protolog.common.ProtoLog; import com.android.server.UiThread; import java.util.Map; import java.util.Set; /** Loading Loading @@ -100,7 +98,8 @@ final class DisplayRotationCompatPolicy { // camera id by a package name when determining rotation; 2) get a package name by a camera id // when camera connection is closed and we need to clean up our records. @GuardedBy("this") private final CameraIdPackageNameBiMap mCameraIdPackageBiMap = new CameraIdPackageNameBiMap(); private final CameraIdPackageNameBiMapping mCameraIdPackageBiMap = new CameraIdPackageNameBiMapping(); @GuardedBy("this") private final Set<String> mScheduledToBeRemovedCameraIdSet = new ArraySet<>(); @GuardedBy("this") Loading Loading @@ -516,54 +515,4 @@ final class DisplayRotationCompatPolicy { } return topActivity.mLetterboxUiController.isRefreshAfterRotationRequested(); } private static class CameraIdPackageNameBiMap { private final Map<String, String> mPackageToCameraIdMap = new ArrayMap<>(); private final Map<String, String> mCameraIdToPackageMap = new ArrayMap<>(); boolean isEmpty() { return mCameraIdToPackageMap.isEmpty(); } void put(String packageName, String cameraId) { // Always using the last connected camera ID for the package even for the concurrent // camera use case since we can't guess which camera is more important anyway. removePackageName(packageName); removeCameraId(cameraId); mPackageToCameraIdMap.put(packageName, cameraId); mCameraIdToPackageMap.put(cameraId, packageName); } boolean containsPackageName(String packageName) { return mPackageToCameraIdMap.containsKey(packageName); } @Nullable String getCameraId(String packageName) { return mPackageToCameraIdMap.get(packageName); } void removeCameraId(String cameraId) { String packageName = mCameraIdToPackageMap.get(cameraId); if (packageName == null) { return; } mPackageToCameraIdMap.remove(packageName, cameraId); mCameraIdToPackageMap.remove(cameraId, packageName); } String getSummaryForDisplayRotationHistoryRecord() { return "{ mPackageToCameraIdMap=" + mPackageToCameraIdMap + " }"; } private void removePackageName(String packageName) { String cameraId = mPackageToCameraIdMap.get(packageName); if (cameraId == null) { return; } mPackageToCameraIdMap.remove(packageName, cameraId); mCameraIdToPackageMap.remove(cameraId, packageName); } } }
services/tests/wmtests/src/com/android/server/wm/CameraIdPackageNameBiMappingTests.java 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 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.server.wm; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.platform.test.annotations.Presubmit; import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; /** * Tests for {@link CameraIdPackageNameBiMapping}. * * Build/Install/Run: * atest WmTests:CameraIdPackageNameBiMapTests */ @SmallTest @Presubmit public class CameraIdPackageNameBiMappingTests { private CameraIdPackageNameBiMapping mMapping; private static final String PACKAGE_1 = "PACKAGE_1"; private static final String PACKAGE_2 = "PACKAGE_2"; private static final String CAMERA_ID_1 = "1234"; private static final String CAMERA_ID_2 = "5678"; @Before public void setUp() { mMapping = new CameraIdPackageNameBiMapping(); } @Test public void mappingEmptyAtStart() { assertTrue(mMapping.isEmpty()); } @Test public void addPackageAndId_containsPackage() { mMapping.put(PACKAGE_1, CAMERA_ID_1); assertTrue(mMapping.containsPackageName(PACKAGE_1)); } @Test public void addTwoPackagesAndId_containsPackages() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.put(PACKAGE_2, CAMERA_ID_2); assertTrue(mMapping.containsPackageName(PACKAGE_1)); assertTrue(mMapping.containsPackageName(PACKAGE_2)); } @Test public void addPackageAndId_mapContainsPackageAndId() { mMapping.put(PACKAGE_1, CAMERA_ID_1); assertEquals(CAMERA_ID_1, mMapping.getCameraId(PACKAGE_1)); } @Test public void changeCameraId_newestCameraId() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.put(PACKAGE_1, CAMERA_ID_2); assertEquals(CAMERA_ID_2, mMapping.getCameraId(PACKAGE_1)); } @Test public void changePackage_newestPackage() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.put(PACKAGE_2, CAMERA_ID_1); assertFalse(mMapping.containsPackageName(PACKAGE_1)); assertTrue(mMapping.containsPackageName(PACKAGE_2)); assertEquals(CAMERA_ID_1, mMapping.getCameraId(PACKAGE_2)); } @Test public void addAndRemoveCameraId_containsOtherPackage() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.put(PACKAGE_2, CAMERA_ID_2); mMapping.removeCameraId(CAMERA_ID_1); assertFalse(mMapping.containsPackageName(PACKAGE_1)); assertTrue(mMapping.containsPackageName(PACKAGE_2)); } @Test public void addAndRemoveOnlyCameraId_empty() { mMapping.put(PACKAGE_1, CAMERA_ID_1); mMapping.removeCameraId(CAMERA_ID_1); assertTrue(mMapping.isEmpty()); } }