Loading core/java/android/content/pm/PackageParser.java +0 −18 Original line number Diff line number Diff line Loading @@ -2628,15 +2628,6 @@ public class PackageParser { return Build.VERSION_CODES.CUR_DEVELOPMENT; } // STOPSHIP: hack for the pre-release SDK if (platformSdkCodenames.length == 0 && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( targetCode)) { Slog.w(TAG, "Package requires development platform " + targetCode + ", returning current version " + Build.VERSION.SDK_INT); return Build.VERSION.SDK_INT; } // Otherwise, we're looking at an incompatible pre-release SDK. if (platformSdkCodenames.length > 0) { outError[0] = "Requires development platform " + targetCode Loading Loading @@ -2708,15 +2699,6 @@ public class PackageParser { return Build.VERSION_CODES.CUR_DEVELOPMENT; } // STOPSHIP: hack for the pre-release SDK if (platformSdkCodenames.length == 0 && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( minCode)) { Slog.w(TAG, "Package requires min development platform " + minCode + ", returning current version " + Build.VERSION.SDK_INT); return Build.VERSION.SDK_INT; } // Otherwise, we're looking at an incompatible pre-release SDK. if (platformSdkCodenames.length > 0) { outError[0] = "Requires development platform " + minCode Loading core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java +8 −25 Original line number Diff line number Diff line Loading @@ -316,15 +316,6 @@ public class FrameworkParsingPackageUtils { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } // STOPSHIP: hack for the pre-release SDK if (platformSdkCodenames.length == 0 && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( minCode)) { Slog.w(TAG, "Parsed package requires min development platform " + minCode + ", returning current version " + Build.VERSION.SDK_INT); return input.success(Build.VERSION.SDK_INT); } // Otherwise, we're looking at an incompatible pre-release SDK. if (platformSdkCodenames.length > 0) { return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, Loading Loading @@ -377,27 +368,19 @@ public class FrameworkParsingPackageUtils { return input.success(targetVers); } // If it's a pre-release SDK and the codename matches this platform, it // definitely targets this SDK. if (matchTargetCode(platformSdkCodenames, targetCode)) { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } // STOPSHIP: hack for the pre-release SDK if (platformSdkCodenames.length == 0 && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( targetCode)) { Slog.w(TAG, "Parsed package requires development platform " + targetCode + ", returning current version " + Build.VERSION.SDK_INT); return input.success(Build.VERSION.SDK_INT); } try { if (allowUnknownCodenames && UnboundedSdkLevel.isAtMost(targetCode)) { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } } catch (IllegalArgumentException e) { return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, "Bad package SDK"); // isAtMost() throws it when encountering an older SDK codename return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, e.getMessage()); } // If it's a pre-release SDK and the codename matches this platform, it // definitely targets this SDK. if (matchTargetCode(platformSdkCodenames, targetCode)) { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } // Otherwise, we're looking at an incompatible pre-release SDK. Loading core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java +59 −23 Original line number Diff line number Diff line Loading @@ -77,18 +77,18 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private static final String TAG = "CameraAdvancedExtensionSessionImpl"; private final Executor mExecutor; private final CameraDevice mCameraDevice; private CameraDevice mCameraDevice; private final Map<String, CameraMetadataNative> mCharacteristicsMap; private final long mExtensionClientId; private final Handler mHandler; private final HandlerThread mHandlerThread; private final CameraExtensionSession.StateCallback mCallbacks; private final IAdvancedExtenderImpl mAdvancedExtender; private IAdvancedExtenderImpl mAdvancedExtender; // maps registered camera surfaces to extension output configs private final HashMap<Surface, CameraOutputConfig> mCameraConfigMap = new HashMap<>(); // maps camera extension output ids to camera registered image readers private final HashMap<Integer, ImageReader> mReaderMap = new HashMap<>(); private final RequestProcessor mRequestProcessor = new RequestProcessor(); private RequestProcessor mRequestProcessor = new RequestProcessor(); private final int mSessionId; private Surface mClientRepeatingRequestSurface; Loading @@ -100,7 +100,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private final ExtensionSessionStatsAggregator mStatsAggregator; private boolean mInitialized; private boolean mSessionClosed; // Lock to synchronize cross-thread access to device public interface final Object mInterfaceLock; Loading Loading @@ -237,6 +237,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mInitialized = false; mSessionClosed = false; mInitializeHandler = new InitializeSessionHandler(); mSessionId = sessionId; mInterfaceLock = cameraDevice.mInterfaceLock; Loading Loading @@ -424,7 +425,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mSessionProcessor.setParameters(request); seqId = mSessionProcessor.startRepeating(new RequestCallbackHandler(request, executor, listener)); executor, listener, mCameraDevice.getId())); } catch (RemoteException e) { throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed to enable repeating request, extension service failed to respond!"); Loading Loading @@ -452,7 +453,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mSessionProcessor.setParameters(request); seqId = mSessionProcessor.startCapture(new RequestCallbackHandler(request, executor, listener), isPostviewRequested); executor, listener, mCameraDevice.getId()), isPostviewRequested); } catch (RemoteException e) { throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed " + " to submit capture request, extension service failed to respond!"); Loading @@ -460,8 +461,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } else if ((mClientRepeatingRequestSurface != null) && request.containsTarget(mClientRepeatingRequestSurface)) { try { seqId = mSessionProcessor.startTrigger(request, new RequestCallbackHandler(request, executor, listener)); seqId = mSessionProcessor.startTrigger(request, new RequestCallbackHandler( request, executor, listener, mCameraDevice.getId())); } catch (RemoteException e) { throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed " + " to submit trigger request, extension service failed to respond!"); Loading Loading @@ -528,6 +529,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mCaptureSession.stopRepeating(); mSessionProcessor.stopRepeating(); mSessionProcessor.onCaptureSessionEnd(); mSessionClosed = true; } catch (RemoteException e) { Log.e(TAG, "Failed to stop the repeating request or end the session," + " , extension service does not respond!") ; Loading Loading @@ -560,6 +562,9 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes if (mSessionProcessor != null) { try { if (!mSessionClosed) { mSessionProcessor.onCaptureSessionEnd(); } mSessionProcessor.deInitSession(); } catch (RemoteException e) { Log.e(TAG, "Failed to de-initialize session processor, extension service" Loading @@ -584,6 +589,10 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mClientRepeatingRequestSurface = null; mClientCaptureSurface = null; mCaptureSession = null; mRequestProcessor = null; mCameraDevice = null; mAdvancedExtender = null; } if (notifyClose && !skipCloseNotification) { Loading Loading @@ -706,13 +715,16 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private final CaptureRequest mClientRequest; private final Executor mClientExecutor; private final ExtensionCaptureCallback mClientCallbacks; private final String mCameraId; private RequestCallbackHandler(@NonNull CaptureRequest clientRequest, @NonNull Executor clientExecutor, @NonNull ExtensionCaptureCallback clientCallbacks) { @NonNull ExtensionCaptureCallback clientCallbacks, @NonNull String cameraId) { mClientRequest = clientRequest; mClientExecutor = clientExecutor; mClientCallbacks = clientCallbacks; mCameraId = cameraId; } @Override Loading Loading @@ -784,7 +796,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } result.set(CaptureResult.SENSOR_TIMESTAMP, timestamp); TotalCaptureResult totalResult = new TotalCaptureResult(mCameraDevice.getId(), result, TotalCaptureResult totalResult = new TotalCaptureResult(mCameraId, result, mClientRequest, requestId, timestamp, new ArrayList<>(), mSessionId, new PhysicalCaptureResultInfo[0]); final long ident = Binder.clearCallingIdentity(); Loading Loading @@ -1036,6 +1048,11 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes public int submitBurst(List<Request> requests, IRequestCallback callback) { int seqId = -1; try { synchronized (mInterfaceLock) { if (!mInitialized) { return seqId; } CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback); ArrayList<CaptureRequest> captureRequests = new ArrayList<>(); for (Request request : requests) { Loading @@ -1044,6 +1061,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } seqId = mCaptureSession.captureBurstRequests(captureRequests, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); } } catch (CameraAccessException e) { Log.e(TAG, "Failed to submit capture requests!"); } catch (IllegalStateException e) { Loading @@ -1057,11 +1075,17 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes public int setRepeating(Request request, IRequestCallback callback) { int seqId = -1; try { synchronized (mInterfaceLock) { if (!mInitialized) { return seqId; } CaptureRequest repeatingRequest = initializeCaptureRequest(mCameraDevice, request, mCameraConfigMap); CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback); seqId = mCaptureSession.setSingleRepeatingRequest(repeatingRequest, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); } } catch (CameraAccessException e) { Log.e(TAG, "Failed to enable repeating request!"); } catch (IllegalStateException e) { Loading @@ -1074,7 +1098,13 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes @Override public void abortCaptures() { try { synchronized (mInterfaceLock) { if (!mInitialized) { return; } mCaptureSession.abortCaptures(); } } catch (CameraAccessException e) { Log.e(TAG, "Failed during capture abort!"); } catch (IllegalStateException e) { Loading @@ -1085,7 +1115,13 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes @Override public void stopRepeating() { try { synchronized (mInterfaceLock) { if (!mInitialized) { return; } mCaptureSession.stopRepeating(); } } catch (CameraAccessException e) { Log.e(TAG, "Failed during repeating capture stop!"); } catch (IllegalStateException e) { Loading libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java +50 −6 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.util.DisplayMetrics; import android.util.Pair; import android.view.Display; import android.view.DisplayAddress; import android.view.Surface; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -36,6 +37,7 @@ import androidx.window.extensions.core.util.function.Consumer; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import java.util.Objects; Loading Loading @@ -229,27 +231,41 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, * @since {@link WindowExtensions#VENDOR_API_LEVEL_3} */ @Override @NonNull public DisplayMetrics getRearDisplayMetrics() { DisplayMetrics metrics = null; DisplayMetrics rearDisplayMetrics = null; // DISPLAY_CATEGORY_REAR displays are only available when you are in the concurrent // display state, so we have to look through all displays to match the address Display[] displays = mDisplayManager.getDisplays( final Display[] displays = mDisplayManager.getDisplays( DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED); final Display defaultDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); for (int i = 0; i < displays.length; i++) { DisplayAddress.Physical address = (DisplayAddress.Physical) displays[i].getAddress(); if (mRearDisplayAddress == address.getPhysicalDisplayId()) { metrics = new DisplayMetrics(); displays[i].getRealMetrics(metrics); rearDisplayMetrics = new DisplayMetrics(); final Display rearDisplay = displays[i]; // We must always retrieve the metrics for the rear display regardless of if it is // the default display or not. rearDisplay.getRealMetrics(rearDisplayMetrics); // TODO(b/287170025): This should be something like if (!rearDisplay.isEnabled) // instead. Currently when the rear display is disabled, its state is STATE_OFF. if (rearDisplay.getDisplayId() != Display.DEFAULT_DISPLAY) { rotateRearDisplayMetricsIfNeeded(defaultDisplay.getRotation(), rearDisplay.getRotation(), rearDisplayMetrics); } break; } } synchronized (mLock) { // Update the rear display metrics with our latest value if one was received if (metrics != null) { mRearDisplayMetrics = metrics; if (rearDisplayMetrics != null) { mRearDisplayMetrics = rearDisplayMetrics; } return Objects.requireNonNullElseGet(mRearDisplayMetrics, DisplayMetrics::new); Loading Loading @@ -540,6 +556,34 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, return mLastReportedRearDisplayPresentationStatus; } @VisibleForTesting static void rotateRearDisplayMetricsIfNeeded( @Surface.Rotation int defaultDisplayRotation, @Surface.Rotation int rearDisplayRotation, @NonNull DisplayMetrics inOutMetrics) { // If the rear display has a non-zero rotation, it means the backing DisplayContent / // DisplayRotation is fresh. if (rearDisplayRotation != Surface.ROTATION_0) { return; } // If the default display is 0 or 180, the rear display must also be 0 or 180. if (defaultDisplayRotation == Surface.ROTATION_0 || defaultDisplayRotation == Surface.ROTATION_180) { return; } final int heightPixels = inOutMetrics.heightPixels; final int widthPixels = inOutMetrics.widthPixels; inOutMetrics.widthPixels = heightPixels; inOutMetrics.heightPixels = widthPixels; final int noncompatHeightPixels = inOutMetrics.noncompatHeightPixels; final int noncompatWidthPixels = inOutMetrics.noncompatWidthPixels; inOutMetrics.noncompatWidthPixels = noncompatHeightPixels; inOutMetrics.noncompatHeightPixels = noncompatWidthPixels; } /** * Callback for the {@link DeviceStateRequest} to be notified of when the request has been * activated or cancelled. This callback provides information to the client library Loading libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/area/WindowAreaComponentImplTests.java 0 → 100644 +96 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 androidx.window.extensions.area; import static org.junit.Assert.assertEquals; import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; import android.view.Surface; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) public class WindowAreaComponentImplTests { private final DisplayMetrics mTestDisplayMetrics = new DisplayMetrics(); @Before public void setup() { mTestDisplayMetrics.widthPixels = 1; mTestDisplayMetrics.heightPixels = 2; mTestDisplayMetrics.noncompatWidthPixels = 3; mTestDisplayMetrics.noncompatHeightPixels = 4; } /** * Cases where the rear display metrics does not need to be transformed. */ @Test public void testRotateRearDisplayMetrics_noTransformNeeded() { final DisplayMetrics originalMetrics = new DisplayMetrics(); originalMetrics.setTo(mTestDisplayMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_0, Surface.ROTATION_0, mTestDisplayMetrics); assertEquals(originalMetrics, mTestDisplayMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_180, Surface.ROTATION_180, mTestDisplayMetrics); assertEquals(originalMetrics, mTestDisplayMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_0, Surface.ROTATION_180, mTestDisplayMetrics); assertEquals(originalMetrics, mTestDisplayMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_180, Surface.ROTATION_0, mTestDisplayMetrics); assertEquals(originalMetrics, mTestDisplayMetrics); } /** * Cases where the rear display metrics need to be transformed. */ @Test public void testRotateRearDisplayMetrics_transformNeeded() { DisplayMetrics originalMetrics = new DisplayMetrics(); originalMetrics.setTo(mTestDisplayMetrics); DisplayMetrics expectedMetrics = new DisplayMetrics(); expectedMetrics.setTo(mTestDisplayMetrics); expectedMetrics.widthPixels = mTestDisplayMetrics.heightPixels; expectedMetrics.heightPixels = mTestDisplayMetrics.widthPixels; expectedMetrics.noncompatWidthPixels = mTestDisplayMetrics.noncompatHeightPixels; expectedMetrics.noncompatHeightPixels = mTestDisplayMetrics.noncompatWidthPixels; WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_90, Surface.ROTATION_0, mTestDisplayMetrics); assertEquals(expectedMetrics, mTestDisplayMetrics); mTestDisplayMetrics.setTo(originalMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_270, Surface.ROTATION_0, mTestDisplayMetrics); assertEquals(expectedMetrics, mTestDisplayMetrics); } } Loading
core/java/android/content/pm/PackageParser.java +0 −18 Original line number Diff line number Diff line Loading @@ -2628,15 +2628,6 @@ public class PackageParser { return Build.VERSION_CODES.CUR_DEVELOPMENT; } // STOPSHIP: hack for the pre-release SDK if (platformSdkCodenames.length == 0 && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( targetCode)) { Slog.w(TAG, "Package requires development platform " + targetCode + ", returning current version " + Build.VERSION.SDK_INT); return Build.VERSION.SDK_INT; } // Otherwise, we're looking at an incompatible pre-release SDK. if (platformSdkCodenames.length > 0) { outError[0] = "Requires development platform " + targetCode Loading Loading @@ -2708,15 +2699,6 @@ public class PackageParser { return Build.VERSION_CODES.CUR_DEVELOPMENT; } // STOPSHIP: hack for the pre-release SDK if (platformSdkCodenames.length == 0 && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( minCode)) { Slog.w(TAG, "Package requires min development platform " + minCode + ", returning current version " + Build.VERSION.SDK_INT); return Build.VERSION.SDK_INT; } // Otherwise, we're looking at an incompatible pre-release SDK. if (platformSdkCodenames.length > 0) { outError[0] = "Requires development platform " + minCode Loading
core/java/android/content/pm/parsing/FrameworkParsingPackageUtils.java +8 −25 Original line number Diff line number Diff line Loading @@ -316,15 +316,6 @@ public class FrameworkParsingPackageUtils { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } // STOPSHIP: hack for the pre-release SDK if (platformSdkCodenames.length == 0 && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( minCode)) { Slog.w(TAG, "Parsed package requires min development platform " + minCode + ", returning current version " + Build.VERSION.SDK_INT); return input.success(Build.VERSION.SDK_INT); } // Otherwise, we're looking at an incompatible pre-release SDK. if (platformSdkCodenames.length > 0) { return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, Loading Loading @@ -377,27 +368,19 @@ public class FrameworkParsingPackageUtils { return input.success(targetVers); } // If it's a pre-release SDK and the codename matches this platform, it // definitely targets this SDK. if (matchTargetCode(platformSdkCodenames, targetCode)) { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } // STOPSHIP: hack for the pre-release SDK if (platformSdkCodenames.length == 0 && Build.VERSION.KNOWN_CODENAMES.stream().max(String::compareTo).orElse("").equals( targetCode)) { Slog.w(TAG, "Parsed package requires development platform " + targetCode + ", returning current version " + Build.VERSION.SDK_INT); return input.success(Build.VERSION.SDK_INT); } try { if (allowUnknownCodenames && UnboundedSdkLevel.isAtMost(targetCode)) { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } } catch (IllegalArgumentException e) { return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, "Bad package SDK"); // isAtMost() throws it when encountering an older SDK codename return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK, e.getMessage()); } // If it's a pre-release SDK and the codename matches this platform, it // definitely targets this SDK. if (matchTargetCode(platformSdkCodenames, targetCode)) { return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT); } // Otherwise, we're looking at an incompatible pre-release SDK. Loading
core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java +59 −23 Original line number Diff line number Diff line Loading @@ -77,18 +77,18 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private static final String TAG = "CameraAdvancedExtensionSessionImpl"; private final Executor mExecutor; private final CameraDevice mCameraDevice; private CameraDevice mCameraDevice; private final Map<String, CameraMetadataNative> mCharacteristicsMap; private final long mExtensionClientId; private final Handler mHandler; private final HandlerThread mHandlerThread; private final CameraExtensionSession.StateCallback mCallbacks; private final IAdvancedExtenderImpl mAdvancedExtender; private IAdvancedExtenderImpl mAdvancedExtender; // maps registered camera surfaces to extension output configs private final HashMap<Surface, CameraOutputConfig> mCameraConfigMap = new HashMap<>(); // maps camera extension output ids to camera registered image readers private final HashMap<Integer, ImageReader> mReaderMap = new HashMap<>(); private final RequestProcessor mRequestProcessor = new RequestProcessor(); private RequestProcessor mRequestProcessor = new RequestProcessor(); private final int mSessionId; private Surface mClientRepeatingRequestSurface; Loading @@ -100,7 +100,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private final ExtensionSessionStatsAggregator mStatsAggregator; private boolean mInitialized; private boolean mSessionClosed; // Lock to synchronize cross-thread access to device public interface final Object mInterfaceLock; Loading Loading @@ -237,6 +237,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mInitialized = false; mSessionClosed = false; mInitializeHandler = new InitializeSessionHandler(); mSessionId = sessionId; mInterfaceLock = cameraDevice.mInterfaceLock; Loading Loading @@ -424,7 +425,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mSessionProcessor.setParameters(request); seqId = mSessionProcessor.startRepeating(new RequestCallbackHandler(request, executor, listener)); executor, listener, mCameraDevice.getId())); } catch (RemoteException e) { throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed to enable repeating request, extension service failed to respond!"); Loading Loading @@ -452,7 +453,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mSessionProcessor.setParameters(request); seqId = mSessionProcessor.startCapture(new RequestCallbackHandler(request, executor, listener), isPostviewRequested); executor, listener, mCameraDevice.getId()), isPostviewRequested); } catch (RemoteException e) { throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed " + " to submit capture request, extension service failed to respond!"); Loading @@ -460,8 +461,8 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } else if ((mClientRepeatingRequestSurface != null) && request.containsTarget(mClientRepeatingRequestSurface)) { try { seqId = mSessionProcessor.startTrigger(request, new RequestCallbackHandler(request, executor, listener)); seqId = mSessionProcessor.startTrigger(request, new RequestCallbackHandler( request, executor, listener, mCameraDevice.getId())); } catch (RemoteException e) { throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed " + " to submit trigger request, extension service failed to respond!"); Loading Loading @@ -528,6 +529,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mCaptureSession.stopRepeating(); mSessionProcessor.stopRepeating(); mSessionProcessor.onCaptureSessionEnd(); mSessionClosed = true; } catch (RemoteException e) { Log.e(TAG, "Failed to stop the repeating request or end the session," + " , extension service does not respond!") ; Loading Loading @@ -560,6 +562,9 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes if (mSessionProcessor != null) { try { if (!mSessionClosed) { mSessionProcessor.onCaptureSessionEnd(); } mSessionProcessor.deInitSession(); } catch (RemoteException e) { Log.e(TAG, "Failed to de-initialize session processor, extension service" Loading @@ -584,6 +589,10 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes mClientRepeatingRequestSurface = null; mClientCaptureSurface = null; mCaptureSession = null; mRequestProcessor = null; mCameraDevice = null; mAdvancedExtender = null; } if (notifyClose && !skipCloseNotification) { Loading Loading @@ -706,13 +715,16 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes private final CaptureRequest mClientRequest; private final Executor mClientExecutor; private final ExtensionCaptureCallback mClientCallbacks; private final String mCameraId; private RequestCallbackHandler(@NonNull CaptureRequest clientRequest, @NonNull Executor clientExecutor, @NonNull ExtensionCaptureCallback clientCallbacks) { @NonNull ExtensionCaptureCallback clientCallbacks, @NonNull String cameraId) { mClientRequest = clientRequest; mClientExecutor = clientExecutor; mClientCallbacks = clientCallbacks; mCameraId = cameraId; } @Override Loading Loading @@ -784,7 +796,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } result.set(CaptureResult.SENSOR_TIMESTAMP, timestamp); TotalCaptureResult totalResult = new TotalCaptureResult(mCameraDevice.getId(), result, TotalCaptureResult totalResult = new TotalCaptureResult(mCameraId, result, mClientRequest, requestId, timestamp, new ArrayList<>(), mSessionId, new PhysicalCaptureResultInfo[0]); final long ident = Binder.clearCallingIdentity(); Loading Loading @@ -1036,6 +1048,11 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes public int submitBurst(List<Request> requests, IRequestCallback callback) { int seqId = -1; try { synchronized (mInterfaceLock) { if (!mInitialized) { return seqId; } CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback); ArrayList<CaptureRequest> captureRequests = new ArrayList<>(); for (Request request : requests) { Loading @@ -1044,6 +1061,7 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes } seqId = mCaptureSession.captureBurstRequests(captureRequests, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); } } catch (CameraAccessException e) { Log.e(TAG, "Failed to submit capture requests!"); } catch (IllegalStateException e) { Loading @@ -1057,11 +1075,17 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes public int setRepeating(Request request, IRequestCallback callback) { int seqId = -1; try { synchronized (mInterfaceLock) { if (!mInitialized) { return seqId; } CaptureRequest repeatingRequest = initializeCaptureRequest(mCameraDevice, request, mCameraConfigMap); CaptureCallbackHandler captureCallback = new CaptureCallbackHandler(callback); seqId = mCaptureSession.setSingleRepeatingRequest(repeatingRequest, new CameraExtensionUtils.HandlerExecutor(mHandler), captureCallback); } } catch (CameraAccessException e) { Log.e(TAG, "Failed to enable repeating request!"); } catch (IllegalStateException e) { Loading @@ -1074,7 +1098,13 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes @Override public void abortCaptures() { try { synchronized (mInterfaceLock) { if (!mInitialized) { return; } mCaptureSession.abortCaptures(); } } catch (CameraAccessException e) { Log.e(TAG, "Failed during capture abort!"); } catch (IllegalStateException e) { Loading @@ -1085,7 +1115,13 @@ public final class CameraAdvancedExtensionSessionImpl extends CameraExtensionSes @Override public void stopRepeating() { try { synchronized (mInterfaceLock) { if (!mInitialized) { return; } mCaptureSession.stopRepeating(); } } catch (CameraAccessException e) { Log.e(TAG, "Failed during repeating capture stop!"); } catch (IllegalStateException e) { Loading
libs/WindowManager/Jetpack/src/androidx/window/extensions/area/WindowAreaComponentImpl.java +50 −6 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ import android.util.DisplayMetrics; import android.util.Pair; import android.view.Display; import android.view.DisplayAddress; import android.view.Surface; import androidx.annotation.NonNull; import androidx.annotation.Nullable; Loading @@ -36,6 +37,7 @@ import androidx.window.extensions.core.util.function.Consumer; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import java.util.Objects; Loading Loading @@ -229,27 +231,41 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, * @since {@link WindowExtensions#VENDOR_API_LEVEL_3} */ @Override @NonNull public DisplayMetrics getRearDisplayMetrics() { DisplayMetrics metrics = null; DisplayMetrics rearDisplayMetrics = null; // DISPLAY_CATEGORY_REAR displays are only available when you are in the concurrent // display state, so we have to look through all displays to match the address Display[] displays = mDisplayManager.getDisplays( final Display[] displays = mDisplayManager.getDisplays( DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED); final Display defaultDisplay = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); for (int i = 0; i < displays.length; i++) { DisplayAddress.Physical address = (DisplayAddress.Physical) displays[i].getAddress(); if (mRearDisplayAddress == address.getPhysicalDisplayId()) { metrics = new DisplayMetrics(); displays[i].getRealMetrics(metrics); rearDisplayMetrics = new DisplayMetrics(); final Display rearDisplay = displays[i]; // We must always retrieve the metrics for the rear display regardless of if it is // the default display or not. rearDisplay.getRealMetrics(rearDisplayMetrics); // TODO(b/287170025): This should be something like if (!rearDisplay.isEnabled) // instead. Currently when the rear display is disabled, its state is STATE_OFF. if (rearDisplay.getDisplayId() != Display.DEFAULT_DISPLAY) { rotateRearDisplayMetricsIfNeeded(defaultDisplay.getRotation(), rearDisplay.getRotation(), rearDisplayMetrics); } break; } } synchronized (mLock) { // Update the rear display metrics with our latest value if one was received if (metrics != null) { mRearDisplayMetrics = metrics; if (rearDisplayMetrics != null) { mRearDisplayMetrics = rearDisplayMetrics; } return Objects.requireNonNullElseGet(mRearDisplayMetrics, DisplayMetrics::new); Loading Loading @@ -540,6 +556,34 @@ public class WindowAreaComponentImpl implements WindowAreaComponent, return mLastReportedRearDisplayPresentationStatus; } @VisibleForTesting static void rotateRearDisplayMetricsIfNeeded( @Surface.Rotation int defaultDisplayRotation, @Surface.Rotation int rearDisplayRotation, @NonNull DisplayMetrics inOutMetrics) { // If the rear display has a non-zero rotation, it means the backing DisplayContent / // DisplayRotation is fresh. if (rearDisplayRotation != Surface.ROTATION_0) { return; } // If the default display is 0 or 180, the rear display must also be 0 or 180. if (defaultDisplayRotation == Surface.ROTATION_0 || defaultDisplayRotation == Surface.ROTATION_180) { return; } final int heightPixels = inOutMetrics.heightPixels; final int widthPixels = inOutMetrics.widthPixels; inOutMetrics.widthPixels = heightPixels; inOutMetrics.heightPixels = widthPixels; final int noncompatHeightPixels = inOutMetrics.noncompatHeightPixels; final int noncompatWidthPixels = inOutMetrics.noncompatWidthPixels; inOutMetrics.noncompatWidthPixels = noncompatHeightPixels; inOutMetrics.noncompatHeightPixels = noncompatWidthPixels; } /** * Callback for the {@link DeviceStateRequest} to be notified of when the request has been * activated or cancelled. This callback provides information to the client library Loading
libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/area/WindowAreaComponentImplTests.java 0 → 100644 +96 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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 androidx.window.extensions.area; import static org.junit.Assert.assertEquals; import android.platform.test.annotations.Presubmit; import android.util.DisplayMetrics; import android.view.Surface; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @Presubmit @SmallTest @RunWith(AndroidJUnit4.class) public class WindowAreaComponentImplTests { private final DisplayMetrics mTestDisplayMetrics = new DisplayMetrics(); @Before public void setup() { mTestDisplayMetrics.widthPixels = 1; mTestDisplayMetrics.heightPixels = 2; mTestDisplayMetrics.noncompatWidthPixels = 3; mTestDisplayMetrics.noncompatHeightPixels = 4; } /** * Cases where the rear display metrics does not need to be transformed. */ @Test public void testRotateRearDisplayMetrics_noTransformNeeded() { final DisplayMetrics originalMetrics = new DisplayMetrics(); originalMetrics.setTo(mTestDisplayMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_0, Surface.ROTATION_0, mTestDisplayMetrics); assertEquals(originalMetrics, mTestDisplayMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_180, Surface.ROTATION_180, mTestDisplayMetrics); assertEquals(originalMetrics, mTestDisplayMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_0, Surface.ROTATION_180, mTestDisplayMetrics); assertEquals(originalMetrics, mTestDisplayMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_180, Surface.ROTATION_0, mTestDisplayMetrics); assertEquals(originalMetrics, mTestDisplayMetrics); } /** * Cases where the rear display metrics need to be transformed. */ @Test public void testRotateRearDisplayMetrics_transformNeeded() { DisplayMetrics originalMetrics = new DisplayMetrics(); originalMetrics.setTo(mTestDisplayMetrics); DisplayMetrics expectedMetrics = new DisplayMetrics(); expectedMetrics.setTo(mTestDisplayMetrics); expectedMetrics.widthPixels = mTestDisplayMetrics.heightPixels; expectedMetrics.heightPixels = mTestDisplayMetrics.widthPixels; expectedMetrics.noncompatWidthPixels = mTestDisplayMetrics.noncompatHeightPixels; expectedMetrics.noncompatHeightPixels = mTestDisplayMetrics.noncompatWidthPixels; WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_90, Surface.ROTATION_0, mTestDisplayMetrics); assertEquals(expectedMetrics, mTestDisplayMetrics); mTestDisplayMetrics.setTo(originalMetrics); WindowAreaComponentImpl.rotateRearDisplayMetricsIfNeeded( Surface.ROTATION_270, Surface.ROTATION_0, mTestDisplayMetrics); assertEquals(expectedMetrics, mTestDisplayMetrics); } }