Merge "Import translations. DO NOT MERGE ANYWHERE" into sc-dev
diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
index 5b259f7..5cfba3d 100644
--- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
@@ -25,6 +25,7 @@
import android.hardware.camera2.extension.IAdvancedExtenderImpl;
import android.hardware.camera2.extension.ICameraExtensionsProxyService;
import android.hardware.camera2.extension.IImageCaptureExtenderImpl;
+import android.hardware.camera2.extension.IInitializeSessionCallback;
import android.hardware.camera2.extension.IPreviewExtenderImpl;
import android.hardware.camera2.extension.LatencyRange;
import android.hardware.camera2.extension.SizeList;
@@ -357,6 +358,27 @@
}
}
+ public void initializeSession(IInitializeSessionCallback cb) throws RemoteException {
+ synchronized (mLock) {
+ if (mProxy != null) {
+ mProxy.initializeSession(cb);
+ }
+ }
+ }
+
+ public void releaseSession() {
+ synchronized (mLock) {
+ if (mProxy != null) {
+ try {
+ mProxy.releaseSession();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to release session! Extension service does"
+ + " not respond!");
+ }
+ }
+ }
+ }
+
public boolean areAdvancedExtensionsSupported() {
return mSupportsAdvancedExtensions;
}
@@ -412,6 +434,20 @@
/**
* @hide
*/
+ public static void initializeSession(IInitializeSessionCallback cb) throws RemoteException {
+ CameraExtensionManagerGlobal.get().initializeSession(cb);
+ }
+
+ /**
+ * @hide
+ */
+ public static void releaseSession() {
+ CameraExtensionManagerGlobal.get().releaseSession();
+ }
+
+ /**
+ * @hide
+ */
public static boolean areAdvancedExtensionsSupported() {
return CameraExtensionManagerGlobal.get().areAdvancedExtensionsSupported();
}
diff --git a/core/java/android/hardware/camera2/CameraExtensionSession.java b/core/java/android/hardware/camera2/CameraExtensionSession.java
index e1b8177..5892f68 100644
--- a/core/java/android/hardware/camera2/CameraExtensionSession.java
+++ b/core/java/android/hardware/camera2/CameraExtensionSession.java
@@ -195,8 +195,9 @@
* This method is called if the session cannot be configured as requested.
*
* <p>This can happen if the set of requested outputs contains unsupported sizes,
- * too many outputs are requested at once or the camera device encounters an
- * unrecoverable error during configuration.</p>
+ * too many outputs are requested at once or when trying to initialize multiple
+ * concurrent extension sessions from two (or more) separate camera devices
+ * or the camera device encounters an unrecoverable error during configuration.</p>
*
* <p>The session is considered to be closed, and all methods called on it after this
* callback is invoked will throw an IllegalStateException.</p>
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index a1c8d29..5833b3d 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -162,6 +162,9 @@
* <p>The set of combinations may include camera devices that may be in use by other camera API
* clients.</p>
*
+ * <p>Concurrent camera extension sessions {@link CameraExtensionSession} are not currently
+ * supported.</p>
+ *
* <p>The set of combinations doesn't contain physical cameras that can only be used as
* part of a logical multi-camera device.</p>
*
diff --git a/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl b/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl
index bc29e9a..b52c6500 100644
--- a/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl
+++ b/core/java/android/hardware/camera2/extension/ICameraExtensionsProxyService.aidl
@@ -18,6 +18,7 @@
import android.hardware.camera2.extension.IAdvancedExtenderImpl;
import android.hardware.camera2.extension.IPreviewExtenderImpl;
import android.hardware.camera2.extension.IImageCaptureExtenderImpl;
+import android.hardware.camera2.extension.IInitializeSessionCallback;
/** @hide */
interface ICameraExtensionsProxyService
@@ -25,6 +26,8 @@
long registerClient();
void unregisterClient(long clientId);
boolean advancedExtensionsSupported();
+ void initializeSession(in IInitializeSessionCallback cb);
+ void releaseSession();
@nullable IPreviewExtenderImpl initializePreviewExtension(int extensionType);
@nullable IImageCaptureExtenderImpl initializeImageExtension(int extensionType);
@nullable IAdvancedExtenderImpl initializeAdvancedExtension(int extensionType);
diff --git a/core/java/android/hardware/camera2/extension/IInitializeSessionCallback.aidl b/core/java/android/hardware/camera2/extension/IInitializeSessionCallback.aidl
new file mode 100644
index 0000000..1747760
--- /dev/null
+++ b/core/java/android/hardware/camera2/extension/IInitializeSessionCallback.aidl
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2021, 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 android.hardware.camera2.extension;
+
+/** @hide */
+interface IInitializeSessionCallback
+{
+ void onSuccess();
+ void onFailure();
+}
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index 5cf50a2..bfc1f27 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -35,9 +35,11 @@
import android.hardware.camera2.TotalCaptureResult;
import android.hardware.camera2.extension.CameraOutputConfig;
import android.hardware.camera2.extension.CameraSessionConfig;
+import android.hardware.camera2.extension.CaptureStageImpl;
import android.hardware.camera2.extension.IAdvancedExtenderImpl;
import android.hardware.camera2.extension.ICaptureCallback;
import android.hardware.camera2.extension.IImageProcessorImpl;
+import android.hardware.camera2.extension.IInitializeSessionCallback;
import android.hardware.camera2.extension.IRequestCallback;
import android.hardware.camera2.extension.IRequestProcessorImpl;
import android.hardware.camera2.extension.ISessionProcessorImpl;
@@ -89,6 +91,7 @@
private Surface mClientCaptureSurface;
private CameraCaptureSession mCaptureSession = null;
private ISessionProcessorImpl mSessionProcessor = null;
+ private final InitializeSessionHandler mInitializeHandler;
private boolean mInitialized;
@@ -181,6 +184,7 @@
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mInitialized = false;
+ mInitializeHandler = new InitializeSessionHandler();
}
/**
@@ -444,7 +448,6 @@
public void release() {
synchronized (mInterfaceLock) {
- mInitialized = false;
mHandlerThread.quitSafely();
if (mSessionProcessor != null) {
@@ -459,7 +462,11 @@
if (mExtensionClientId >= 0) {
CameraExtensionCharacteristics.unregisterClient(mExtensionClientId);
+ if (mInitialized) {
+ CameraExtensionCharacteristics.releaseSession();
+ }
}
+ mInitialized = false;
for (ImageReader reader : mReaderMap.values()) {
reader.close();
@@ -512,17 +519,32 @@
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
- boolean status = true;
synchronized (mInterfaceLock) {
mCaptureSession = session;
try {
+ CameraExtensionCharacteristics.initializeSession(mInitializeHandler);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to initialize session! Extension service does"
+ + " not respond!");
+ notifyConfigurationFailure();
+ }
+ }
+ }
+ }
+
+ private class InitializeSessionHandler extends IInitializeSessionCallback.Stub {
+ @Override
+ public void onSuccess() {
+ boolean status = true;
+ synchronized (mInterfaceLock) {
+ try {
mSessionProcessor.onCaptureSessionStart(mRequestProcessor);
mInitialized = true;
} catch (RemoteException e) {
Log.e(TAG, "Failed to start capture session,"
+ " extension service does not respond!");
status = false;
- session.close();
+ mCaptureSession.close();
}
}
@@ -538,6 +560,15 @@
notifyConfigurationFailure();
}
}
+
+ @Override
+ public void onFailure() {
+ mCaptureSession.close();
+ Log.e(TAG, "Failed to initialize proxy service session!"
+ + " This can happen when trying to configure multiple "
+ + "concurrent extension sessions!");
+ notifyConfigurationFailure();
+ }
}
private final class RequestCallbackHandler extends ICaptureCallback.Stub {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 4bcc494..537b894 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -34,6 +34,7 @@
import android.hardware.camera2.extension.CaptureStageImpl;
import android.hardware.camera2.extension.ICaptureProcessorImpl;
import android.hardware.camera2.extension.IImageCaptureExtenderImpl;
+import android.hardware.camera2.extension.IInitializeSessionCallback;
import android.hardware.camera2.extension.IPreviewExtenderImpl;
import android.hardware.camera2.extension.IRequestUpdateProcessorImpl;
import android.hardware.camera2.extension.ParcelImage;
@@ -48,6 +49,8 @@
import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.IInterface;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.annotation.NonNull;
@@ -80,6 +83,7 @@
private final HandlerThread mHandlerThread;
private final StateCallback mCallbacks;
private final List<Size> mSupportedPreviewSizes;
+ private final InitializeSessionHandler mInitializeHandler;
private CameraCaptureSession mCaptureSession = null;
private Surface mCameraRepeatingSurface, mClientRepeatingRequestSurface;
@@ -216,6 +220,7 @@
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mInitialized = false;
+ mInitializeHandler = new InitializeSessionHandler();
}
private void initializeRepeatingRequestPipeline() throws RemoteException {
@@ -621,7 +626,6 @@
public void release() {
synchronized (mInterfaceLock) {
mInternalRepeatingRequestEnabled = false;
- mInitialized = false;
mHandlerThread.quitSafely();
try {
@@ -634,7 +638,11 @@
if (mExtensionClientId >= 0) {
CameraExtensionCharacteristics.unregisterClient(mExtensionClientId);
+ if (mInitialized) {
+ CameraExtensionCharacteristics.releaseSession();
+ }
}
+ mInitialized = false;
if (mRepeatingRequestImageCallback != null) {
mRepeatingRequestImageCallback.close();
@@ -739,36 +747,63 @@
@Override
public void onConfigured(@NonNull CameraCaptureSession session) {
- boolean status = true;
synchronized (mInterfaceLock) {
mCaptureSession = session;
-
- ArrayList<CaptureStageImpl> initialRequestList = compileInitialRequestList();
- if (!initialRequestList.isEmpty()) {
- try {
- setInitialCaptureRequest(initialRequestList,
- new InitialRequestHandler(mRepeatingRequestImageCallback));
- } catch (CameraAccessException e) {
- Log.e(TAG, "Failed to initialize the initial capture request!");
- status = false;
- }
- } else {
- try {
- setRepeatingRequest(mPreviewExtender.getCaptureStage(),
- new RepeatingRequestHandler(null, null, null,
- mRepeatingRequestImageCallback));
- } catch (CameraAccessException | RemoteException e) {
- Log.e(TAG, "Failed to initialize internal repeating request!");
- status = false;
- }
-
+ try {
+ CameraExtensionCharacteristics.initializeSession(mInitializeHandler);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to initialize session! Extension service does"
+ + " not respond!");
+ notifyConfigurationFailure();
}
}
+ }
+ }
+
+ private class InitializeSessionHandler extends IInitializeSessionCallback.Stub {
+ @Override
+ public void onSuccess() {
+ boolean status = true;
+ ArrayList<CaptureStageImpl> initialRequestList =
+ compileInitialRequestList();
+ if (!initialRequestList.isEmpty()) {
+ try {
+ setInitialCaptureRequest(initialRequestList,
+ new InitialRequestHandler(
+ mRepeatingRequestImageCallback));
+ } catch (CameraAccessException e) {
+ Log.e(TAG,
+ "Failed to initialize the initial capture "
+ + "request!");
+ status = false;
+ }
+ } else {
+ try {
+ setRepeatingRequest(mPreviewExtender.getCaptureStage(),
+ new RepeatingRequestHandler(null, null, null,
+ mRepeatingRequestImageCallback));
+ } catch (CameraAccessException | RemoteException e) {
+ Log.e(TAG,
+ "Failed to initialize internal repeating "
+ + "request!");
+ status = false;
+ }
+
+ }
if (!status) {
notifyConfigurationFailure();
}
}
+
+ @Override
+ public void onFailure() {
+ mCaptureSession.close();
+ Log.e(TAG, "Failed to initialize proxy service session!"
+ + " This can happen when trying to configure multiple "
+ + "concurrent extension sessions!");
+ notifyConfigurationFailure();
+ }
}
private class BurstRequestHandler extends CameraCaptureSession.CaptureCallback {
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index f2827f3..472e3e7 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -98,12 +98,28 @@
private static final double VELOCITY_THRESHOLD = 0.01;
/**
+ * The speed at which we should start linearly interpolating to the destination.
+ * When using a spring, as it gets closer to the destination, the speed drops off exponentially.
+ * Instead of landing very slowly, a better experience is achieved if the final
+ * destination is arrived at quicker.
+ */
+ private static final float LINEAR_VELOCITY_TAKE_OVER = 200f;
+
+ /**
* The value threshold before the spring animation is considered close enough to
* the destination to be settled. This should be around 0.01 pixel.
*/
private static final double VALUE_THRESHOLD = 0.001;
/**
+ * The maximum distance at which we should start linearly interpolating to the destination.
+ * When using a spring, as it gets closer to the destination, the speed drops off exponentially.
+ * Instead of landing very slowly, a better experience is achieved if the final
+ * destination is arrived at quicker.
+ */
+ private static final double LINEAR_DISTANCE_TAKE_OVER = 8.0;
+
+ /**
* The natural frequency of the stretch spring.
*/
private static final double NATURAL_FREQUENCY = 24.657;
@@ -587,55 +603,57 @@
if (mState == STATE_RECEDE) {
updateSpring();
}
- RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
- if (mTmpMatrix == null) {
- mTmpMatrix = new Matrix();
- mTmpPoints = new float[12];
- }
- //noinspection deprecation
- recordingCanvas.getMatrix(mTmpMatrix);
+ if (mDistance != 0f) {
+ RecordingCanvas recordingCanvas = (RecordingCanvas) canvas;
+ if (mTmpMatrix == null) {
+ mTmpMatrix = new Matrix();
+ mTmpPoints = new float[12];
+ }
+ //noinspection deprecation
+ recordingCanvas.getMatrix(mTmpMatrix);
- mTmpPoints[0] = 0;
- mTmpPoints[1] = 0; // top-left
- mTmpPoints[2] = mWidth;
- mTmpPoints[3] = 0; // top-right
- mTmpPoints[4] = mWidth;
- mTmpPoints[5] = mHeight; // bottom-right
- mTmpPoints[6] = 0;
- mTmpPoints[7] = mHeight; // bottom-left
- mTmpPoints[8] = mWidth * mDisplacement;
- mTmpPoints[9] = 0; // drag start point
- mTmpPoints[10] = mWidth * mDisplacement;
- mTmpPoints[11] = mHeight * mDistance; // drag point
- mTmpMatrix.mapPoints(mTmpPoints);
+ mTmpPoints[0] = 0;
+ mTmpPoints[1] = 0; // top-left
+ mTmpPoints[2] = mWidth;
+ mTmpPoints[3] = 0; // top-right
+ mTmpPoints[4] = mWidth;
+ mTmpPoints[5] = mHeight; // bottom-right
+ mTmpPoints[6] = 0;
+ mTmpPoints[7] = mHeight; // bottom-left
+ mTmpPoints[8] = mWidth * mDisplacement;
+ mTmpPoints[9] = 0; // drag start point
+ mTmpPoints[10] = mWidth * mDisplacement;
+ mTmpPoints[11] = mHeight * mDistance; // drag point
+ mTmpMatrix.mapPoints(mTmpPoints);
- RenderNode renderNode = recordingCanvas.mNode;
+ RenderNode renderNode = recordingCanvas.mNode;
- float left = renderNode.getLeft()
+ float left = renderNode.getLeft()
+ min(mTmpPoints[0], mTmpPoints[2], mTmpPoints[4], mTmpPoints[6]);
- float top = renderNode.getTop()
+ float top = renderNode.getTop()
+ min(mTmpPoints[1], mTmpPoints[3], mTmpPoints[5], mTmpPoints[7]);
- float right = renderNode.getLeft()
+ float right = renderNode.getLeft()
+ max(mTmpPoints[0], mTmpPoints[2], mTmpPoints[4], mTmpPoints[6]);
- float bottom = renderNode.getTop()
+ float bottom = renderNode.getTop()
+ max(mTmpPoints[1], mTmpPoints[3], mTmpPoints[5], mTmpPoints[7]);
- // assume rotations of increments of 90 degrees
- float x = mTmpPoints[10] - mTmpPoints[8];
- float width = right - left;
- float vecX = dampStretchVector(Math.max(-1f, Math.min(1f, x / width)));
+ // assume rotations of increments of 90 degrees
+ float x = mTmpPoints[10] - mTmpPoints[8];
+ float width = right - left;
+ float vecX = dampStretchVector(Math.max(-1f, Math.min(1f, x / width)));
- float y = mTmpPoints[11] - mTmpPoints[9];
- float height = bottom - top;
- float vecY = dampStretchVector(Math.max(-1f, Math.min(1f, y / height)));
+ float y = mTmpPoints[11] - mTmpPoints[9];
+ float height = bottom - top;
+ float vecY = dampStretchVector(Math.max(-1f, Math.min(1f, y / height)));
- boolean hasValidVectors = Float.isFinite(vecX) && Float.isFinite(vecY);
- if (right > left && bottom > top && mWidth > 0 && mHeight > 0 && hasValidVectors) {
- renderNode.stretch(
+ boolean hasValidVectors = Float.isFinite(vecX) && Float.isFinite(vecY);
+ if (right > left && bottom > top && mWidth > 0 && mHeight > 0 && hasValidVectors) {
+ renderNode.stretch(
vecX, // horizontal stretch intensity
vecY, // vertical stretch intensity
mWidth, // max horizontal stretch in pixels
mHeight // max vertical stretch in pixels
- );
+ );
+ }
}
} else {
// Animations have been disabled or this is TYPE_STRETCH and drawing into a Canvas
@@ -730,6 +748,26 @@
if (deltaT < 0.001f) {
return; // Must have at least 1 ms difference
}
+ mStartTime = time;
+
+ if (Math.abs(mVelocity) <= LINEAR_VELOCITY_TAKE_OVER
+ && Math.abs(mDistance * mHeight) < LINEAR_DISTANCE_TAKE_OVER
+ && Math.signum(mVelocity) == -Math.signum(mDistance)
+ ) {
+ // This is close. The spring will slowly reach the destination. Instead, we
+ // will interpolate linearly so that it arrives at its destination quicker.
+ mVelocity = Math.signum(mVelocity) * LINEAR_VELOCITY_TAKE_OVER;
+
+ float targetDistance = mDistance + (mVelocity * deltaT / mHeight);
+ if (Math.signum(targetDistance) != Math.signum(mDistance)) {
+ // We have arrived
+ mDistance = 0;
+ mVelocity = 0;
+ } else {
+ mDistance = targetDistance;
+ }
+ return;
+ }
final double mDampedFreq = NATURAL_FREQUENCY * Math.sqrt(1 - DAMPING_RATIO * DAMPING_RATIO);
// We're always underdamped, so we can use only those equations:
@@ -745,9 +783,7 @@
+ mDampedFreq * sinCoeff * Math.cos(mDampedFreq * deltaT));
mDistance = (float) distance / mHeight;
mVelocity = (float) velocity;
- mStartTime = time;
if (isAtEquilibrium()) {
- mState = STATE_IDLE;
mDistance = 0;
mVelocity = 0;
}
diff --git a/core/java/com/android/server/backup/AccountManagerBackupHelper.java b/core/java/com/android/server/backup/AccountManagerBackupHelper.java
index 39b18c0..f76dd09 100644
--- a/core/java/com/android/server/backup/AccountManagerBackupHelper.java
+++ b/core/java/com/android/server/backup/AccountManagerBackupHelper.java
@@ -56,7 +56,7 @@
}
}
} catch (Exception e) {
- Slog.e(TAG, "Unable to store payload " + key);
+ Slog.e(TAG, "Unable to store payload " + key, e);
}
return new byte[0];
@@ -79,7 +79,7 @@
}
}
} catch (Exception e) {
- Slog.w(TAG, "Unable to restore key " + key);
+ Slog.e(TAG, "Unable to restore key " + key, e);
}
}
}
diff --git a/core/java/com/android/server/backup/NotificationBackupHelper.java b/core/java/com/android/server/backup/NotificationBackupHelper.java
index 7d4f8f7..faa0509 100644
--- a/core/java/com/android/server/backup/NotificationBackupHelper.java
+++ b/core/java/com/android/server/backup/NotificationBackupHelper.java
@@ -49,7 +49,7 @@
newPayload = nm.getBackupPayload(mUserId);
} catch (Exception e) {
// Treat as no data
- Slog.e(TAG, "Couldn't communicate with notification manager");
+ Slog.e(TAG, "Couldn't communicate with notification manager", e);
newPayload = null;
}
}
@@ -68,7 +68,7 @@
ServiceManager.getService("notification"));
nm.applyRestore(payload, mUserId);
} catch (Exception e) {
- Slog.e(TAG, "Couldn't communicate with notification manager");
+ Slog.e(TAG, "Couldn't communicate with notification manager", e);
}
}
}
diff --git a/core/java/com/android/server/backup/PermissionBackupHelper.java b/core/java/com/android/server/backup/PermissionBackupHelper.java
index 4d1949e..ec5e251 100644
--- a/core/java/com/android/server/backup/PermissionBackupHelper.java
+++ b/core/java/com/android/server/backup/PermissionBackupHelper.java
@@ -59,7 +59,7 @@
Slog.w(TAG, "Unexpected backup key " + key);
}
} catch (Exception e) {
- Slog.e(TAG, "Unable to store payload " + key);
+ Slog.e(TAG, "Unable to store payload " + key, e);
}
return null;
}
@@ -79,7 +79,7 @@
Slog.w(TAG, "Unexpected restore key " + key);
}
} catch (Exception e) {
- Slog.w(TAG, "Unable to restore key " + key);
+ Slog.e(TAG, "Unable to restore key " + key, e);
}
}
}
diff --git a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
index 503c719..47e0c07 100644
--- a/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
+++ b/core/java/com/android/server/backup/PreferredActivityBackupHelper.java
@@ -95,7 +95,7 @@
Slog.w(TAG, "Unexpected backup key " + key);
}
} catch (Exception e) {
- Slog.e(TAG, "Unable to store payload " + key);
+ Slog.e(TAG, "Unable to store payload " + key, e);
}
return null;
}
@@ -124,7 +124,7 @@
Slog.w(TAG, "Unexpected restore key " + key);
}
} catch (Exception e) {
- Slog.w(TAG, "Unable to restore key " + key);
+ Slog.e(TAG, "Unable to restore key " + key, e);
}
}
}
diff --git a/core/java/com/android/server/backup/SliceBackupHelper.java b/core/java/com/android/server/backup/SliceBackupHelper.java
index 8e5a5ee..77517b3 100644
--- a/core/java/com/android/server/backup/SliceBackupHelper.java
+++ b/core/java/com/android/server/backup/SliceBackupHelper.java
@@ -48,7 +48,7 @@
newPayload = sm.getBackupPayload(UserHandle.USER_SYSTEM);
} catch (Exception e) {
// Treat as no data
- Slog.e(TAG, "Couldn't communicate with slice manager");
+ Slog.e(TAG, "Couldn't communicate with slice manager", e);
newPayload = null;
}
}
@@ -66,7 +66,7 @@
// TODO: http://b/22388012
sm.applyRestore(payload, UserHandle.USER_SYSTEM);
} catch (Exception e) {
- Slog.e(TAG, "Couldn't communicate with slice manager");
+ Slog.e(TAG, "Couldn't communicate with slice manager", e);
}
}
}
diff --git a/libs/hwui/effects/StretchEffect.h b/libs/hwui/effects/StretchEffect.h
index 3eab9f0..7eb6404 100644
--- a/libs/hwui/effects/StretchEffect.h
+++ b/libs/hwui/effects/StretchEffect.h
@@ -40,9 +40,7 @@
StretchEffect() {}
- bool isEmpty() const {
- return MathUtils::isZero(mStretchDirection.x()) && MathUtils::isZero(mStretchDirection.y());
- }
+ bool isEmpty() const { return isZero(mStretchDirection.x()) && isZero(mStretchDirection.y()); }
void setEmpty() {
*this = StretchEffect{};
@@ -118,6 +116,18 @@
}
private:
+ // The epsilon for StretchEffect is less than in MathUtils because
+ // the range is 0-1 for an entire screen and should be significantly
+ // less than 1 pixel for a smooth stretch animation.
+ inline static bool isZero(float value) {
+ // Using fabsf is more performant as ARM computes
+ // fabsf in a single instruction.
+ return fabsf(value) <= NON_ZERO_EPSILON;
+ }
+ // This should be good for 1/25,000 of a screen and should be good for
+ // screens with less than ~8000 pixels in one dimension with only 1/4 pixel
+ // cut-off.
+ static constexpr float NON_ZERO_EPSILON = 0.00004f;
static sk_sp<SkRuntimeEffect> getStretchEffect();
mutable SkVector mStretchDirection{0, 0};
mutable std::unique_ptr<SkRuntimeShaderBuilder> mBuilder;
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index fa4806d..395a9a7 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -41,6 +41,7 @@
private static final int TOOLBAR_MAX_LINE_NUMBER = 2;
private static final int FULLY_EXPANDED_OFFSET = 0;
+ private static final float TOOLBAR_LINE_SPACING_MULTIPLIER = 1.1f;
private static final String KEY_IS_TOOLBAR_COLLAPSED = "is_toolbar_collapsed";
@Nullable
@@ -194,6 +195,8 @@
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_three_lines));
mCollapsingToolbarLayout.setLayoutParams(lp);
+ mCollapsingToolbarLayout
+ .setLineSpacingMultiplier(TOOLBAR_LINE_SPACING_MULTIPLIER);
} else if (count == TOOLBAR_MAX_LINE_NUMBER) {
final ViewGroup.LayoutParams lp = mCollapsingToolbarLayout.getLayoutParams();
lp.height = getResources()
@@ -202,6 +205,8 @@
getResources().getDimensionPixelSize(
R.dimen.scrim_visible_height_trigger_two_lines));
mCollapsingToolbarLayout.setLayoutParams(lp);
+ mCollapsingToolbarLayout
+ .setLineSpacingMultiplier(TOOLBAR_LINE_SPACING_MULTIPLIER);
}
}
});
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index 3f4baaf..50f38b6 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -78,6 +78,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="matrix"
+ android:visibility="invisible"
app:layout_constraintTop_toTopOf="@id/preview"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
diff --git a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
index 9314685..892f64b 100644
--- a/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
+++ b/packages/SystemUI/res/layout/people_tile_medium_with_content.xml
@@ -29,7 +29,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="@layout/people_tile_punctuation_background_medium" />
- <include layout="@layout/people_tile_punctuation_background_medium" />
+ <include layout="@layout/people_tile_emoji_background_medium" />
<include layout="@layout/people_status_scrim_layout" />
<LinearLayout
android:id="@+id/content"
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index 221bb15..844a8c6 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -121,6 +121,8 @@
private static final int MESSAGES_COUNT_OVERFLOW = 6;
+ private static final CharSequence EMOJI_CAKE = "\ud83c\udf82";
+
private static final Pattern DOUBLE_EXCLAMATION_PATTERN = Pattern.compile("[!][!]+");
private static final Pattern DOUBLE_QUESTION_PATTERN = Pattern.compile("[?][?]+");
private static final Pattern ANY_DOUBLE_MARK_PATTERN = Pattern.compile("[!?][!?]+");
@@ -704,6 +706,10 @@
views.setViewVisibility(R.id.predefined_icon, View.VISIBLE);
views.setTextViewText(R.id.text_content, statusText);
+ if (status.getActivity() == ACTIVITY_BIRTHDAY) {
+ setEmojiBackground(views, EMOJI_CAKE);
+ }
+
Icon statusIcon = status.getIcon();
if (statusIcon != null) {
// No text content styled text on medium or large.
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 07f6d36..741dddc 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -200,7 +200,6 @@
/ (float) mLongScreenshot.getHeight());
mEnterTransitionView.setImageDrawable(drawable);
-
mEnterTransitionView.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
@@ -220,7 +219,6 @@
mCropView.animateEntrance();
mCropView.setVisibility(View.VISIBLE);
setButtonsEnabled(true);
- mEnterTransitionView.setVisibility(View.GONE);
});
});
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 24cca91..63ecc0b 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -33,6 +33,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.Nullable;
+import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.app.ExitTransitionCoordinator;
import android.app.ExitTransitionCoordinator.ExitTransitionCallbacks;
@@ -253,6 +254,7 @@
private final DisplayManager mDisplayManager;
private final ScrollCaptureController mScrollCaptureController;
private final LongScreenshotData mLongScreenshotHolder;
+ private final boolean mIsLowRamDevice;
private ScreenshotView mScreenshotView;
private Bitmap mScreenBitmap;
@@ -297,7 +299,8 @@
ImageExporter imageExporter,
@Main Executor mainExecutor,
ScrollCaptureController scrollCaptureController,
- LongScreenshotData longScreenshotHolder) {
+ LongScreenshotData longScreenshotHolder,
+ ActivityManager activityManager) {
mScreenshotSmartActions = screenshotSmartActions;
mNotificationsController = screenshotNotificationsController;
mScrollCaptureClient = scrollCaptureClient;
@@ -306,6 +309,7 @@
mMainExecutor = mainExecutor;
mScrollCaptureController = scrollCaptureController;
mLongScreenshotHolder = longScreenshotHolder;
+ mIsLowRamDevice = activityManager.isLowRamDevice();
mBgExecutor = Executors.newSingleThreadExecutor();
mDisplayManager = requireNonNull(context.getSystemService(DisplayManager.class));
@@ -621,6 +625,10 @@
}
private void requestScrollCapture() {
+ if (!allowLongScreenshots()) {
+ Log.d(TAG, "Long screenshots not supported on this device");
+ return;
+ }
mScrollCaptureClient.setHostWindowToken(mWindow.getDecorView().getWindowToken());
if (mLastScrollCaptureRequest != null) {
mLastScrollCaptureRequest.cancel(true);
@@ -682,12 +690,8 @@
intent.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- Pair<ActivityOptions, ExitTransitionCoordinator> transition =
- ActivityOptions.startSharedElementAnimation(mWindow,
- new ScreenshotExitTransitionCallbacksSupplier(false).get(),
- null);
- transition.second.startExit();
- mContext.startActivity(intent, transition.first.toBundle());
+ mContext.startActivity(intent,
+ ActivityOptions.makeCustomAnimation(mContext, 0, 0).toBundle());
RemoteAnimationAdapter runner = new RemoteAnimationAdapter(
SCREENSHOT_REMOTE_RUNNER, 0, 0);
try {
@@ -982,6 +986,10 @@
return mDisplayManager.getDisplay(DEFAULT_DISPLAY);
}
+ private boolean allowLongScreenshots() {
+ return !mIsLowRamDevice;
+ }
+
/** Does the aspect ratio of the bitmap with insets removed match the bounds. */
private static boolean aspectRatiosMatch(Bitmap bitmap, Insets bitmapInsets,
Rect screenBounds) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index 41af80e..cfe95e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -71,6 +71,7 @@
private final DozeParameters mDozeParameters;
private final Optional<Bubbles> mBubblesOptional;
private final StatusBarWindowController mStatusBarWindowController;
+ private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private int mIconSize;
private int mIconHPadding;
@@ -119,7 +120,8 @@
Optional<Bubbles> bubblesOptional,
DemoModeController demoModeController,
DarkIconDispatcher darkIconDispatcher,
- StatusBarWindowController statusBarWindowController) {
+ StatusBarWindowController statusBarWindowController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
mContrastColorUtil = ContrastColorUtil.getInstance(context);
mContext = context;
mStatusBarStateController = statusBarStateController;
@@ -133,6 +135,7 @@
mDemoModeController = demoModeController;
mDemoModeController.addCallback(this);
mStatusBarWindowController = statusBarWindowController;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
notificationListener.addNotificationSettingsListener(mSettingsListener);
initializeNotificationAreaViews(context);
@@ -677,7 +680,12 @@
}
boolean visible = mBypassController.getBypassEnabled()
|| mWakeUpCoordinator.getNotificationsFullyHidden();
- if (mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
+
+ // Hide the AOD icons if we're not in the KEYGUARD state unless the screen off animation is
+ // playing, in which case we want them to be visible since we're animating in the AOD UI and
+ // will be switching to KEYGUARD shortly.
+ if (mStatusBarStateController.getState() != StatusBarState.KEYGUARD
+ && !mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) {
visible = false;
}
if (visible && mWakeUpCoordinator.isPulseExpanding()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
index c958796..98fb6f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImpl.java
@@ -99,6 +99,7 @@
mCallbacks = Lists.newArrayList();
private final SysuiColorExtractor mColorExtractor;
+ private final UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private float mFaceAuthDisplayBrightness = LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
@Inject
@@ -110,7 +111,8 @@
KeyguardBypassController keyguardBypassController,
SysuiColorExtractor colorExtractor,
DumpManager dumpManager,
- KeyguardStateController keyguardStateController) {
+ KeyguardStateController keyguardStateController,
+ UnlockedScreenOffAnimationController unlockedScreenOffAnimationController) {
mContext = context;
mWindowManager = windowManager;
mActivityManager = activityManager;
@@ -121,6 +123,7 @@
mKeyguardViewMediator = keyguardViewMediator;
mKeyguardBypassController = keyguardBypassController;
mColorExtractor = colorExtractor;
+ mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
dumpManager.registerDumpable(getClass().getName(), this);
mLockScreenDisplayTimeout = context.getResources()
@@ -300,7 +303,11 @@
private void applyFocusableFlag(State state) {
boolean panelFocusable = state.mNotificationShadeFocusable && state.mPanelExpanded;
if (state.mBouncerShowing && (state.mKeyguardOccluded || state.mKeyguardNeedsInput)
- || ENABLE_REMOTE_INPUT && state.mRemoteInputActive) {
+ || ENABLE_REMOTE_INPUT && state.mRemoteInputActive
+ // Make the panel focusable if we're doing the screen off animation, since the light
+ // reveal scrim is drawing in the panel and should consume touch events so that they
+ // don't go to the app behind.
+ || mUnlockedScreenOffAnimationController.isScreenOffAnimationPlaying()) {
mLpChanged.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE;
mLpChanged.flags &= ~LayoutParams.FLAG_ALT_FOCUSABLE_IM;
} else if (state.isKeyguardShowingAndNotOccluded() || panelFocusable) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
index 407b248..5de7846a 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialogImpl.java
@@ -1127,7 +1127,12 @@
.alpha(0.f)
.setStartDelay(0)
.setDuration(mDialogHideAnimationDurationMs)
- .withEndAction(() -> mODICaptionsTooltipView.setVisibility(INVISIBLE))
+ .withEndAction(() -> {
+ // It might have been nulled out by tryToRemoveCaptionsTooltip.
+ if (mODICaptionsTooltipView != null) {
+ mODICaptionsTooltipView.setVisibility(INVISIBLE);
+ }
+ })
.start();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
index 5f8eb9e..25aa93a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconAreaControllerTest.java
@@ -66,6 +66,8 @@
DarkIconDispatcher mDarkIconDispatcher;
@Mock
StatusBarWindowController mStatusBarWindowController;
+ @Mock
+ UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private NotificationIconAreaController mController;
@Mock
private Bubbles mBubbles;
@@ -87,7 +89,8 @@
Optional.of(mBubbles),
mDemoModeController,
mDarkIconDispatcher,
- mStatusBarWindowController);
+ mStatusBarWindowController,
+ mUnlockedScreenOffAnimationController);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
index 9fe47ec..b03712c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationShadeWindowControllerImplTest.java
@@ -72,6 +72,7 @@
@Mock ColorExtractor.GradientColors mGradientColors;
@Mock private DumpManager mDumpManager;
@Mock private KeyguardStateController mKeyguardStateController;
+ @Mock private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
@Captor private ArgumentCaptor<WindowManager.LayoutParams> mLayoutParameters;
private NotificationShadeWindowControllerImpl mNotificationShadeWindowController;
@@ -85,7 +86,8 @@
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
- mColorExtractor, mDumpManager, mKeyguardStateController);
+ mColorExtractor, mDumpManager, mKeyguardStateController,
+ mUnlockedScreenOffAnimationController);
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
mNotificationShadeWindowController.attach();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
index 9fa35f8..eb9206d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -98,6 +98,7 @@
import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -233,6 +234,8 @@
private ShellTaskOrganizer mShellTaskOrganizer;
@Mock
private KeyguardStateController mKeyguardStateController;
+ @Mock
+ private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private TestableBubblePositioner mPositioner;
@@ -255,7 +258,8 @@
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
- mColorExtractor, mDumpManager, mKeyguardStateController);
+ mColorExtractor, mDumpManager, mKeyguardStateController,
+ mUnlockedScreenOffAnimationController);
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
mNotificationShadeWindowController.attach();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
index 55cc8bb..24a5b3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/NewNotifPipelineBubblesTest.java
@@ -81,6 +81,7 @@
import com.android.systemui.statusbar.phone.NotificationShadeWindowControllerImpl;
import com.android.systemui.statusbar.phone.NotificationShadeWindowView;
import com.android.systemui.statusbar.phone.ShadeController;
+import com.android.systemui.statusbar.phone.UnlockedScreenOffAnimationController;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -197,6 +198,8 @@
private ShellTaskOrganizer mShellTaskOrganizer;
@Mock
private KeyguardStateController mKeyguardStateController;
+ @Mock
+ private UnlockedScreenOffAnimationController mUnlockedScreenOffAnimationController;
private TestableBubblePositioner mPositioner;
@@ -218,7 +221,8 @@
mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(mContext,
mWindowManager, mActivityManager, mDozeParameters, mStatusBarStateController,
mConfigurationController, mKeyguardViewMediator, mKeyguardBypassController,
- mColorExtractor, mDumpManager, mKeyguardStateController);
+ mColorExtractor, mDumpManager, mKeyguardStateController,
+ mUnlockedScreenOffAnimationController);
mNotificationShadeWindowController.setNotificationShadeView(mNotificationShadeWindowView);
mNotificationShadeWindowController.attach();
diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
index 69874f8..ab3643c 100644
--- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
+++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
@@ -18,6 +18,7 @@
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.hardware.camera2.CameraAccessException;
@@ -42,6 +43,7 @@
import android.hardware.camera2.extension.IRequestUpdateProcessorImpl;
import android.hardware.camera2.extension.IImageCaptureExtenderImpl;
import android.hardware.camera2.extension.IImageProcessorImpl;
+import android.hardware.camera2.extension.IInitializeSessionCallback;
import android.hardware.camera2.extension.ISessionProcessorImpl;
import android.hardware.camera2.extension.LatencyRange;
import android.hardware.camera2.extension.OutputConfigId;
@@ -57,6 +59,7 @@
import android.hardware.camera2.impl.PhysicalCaptureResultInfo;
import android.media.Image;
import android.media.ImageReader;
+import android.os.Binder;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerExecutor;
@@ -176,6 +179,7 @@
private long mCurrentClientCount = 0;
private ArraySet<Long> mActiveClients = new ArraySet<>();
+ private IInitializeSessionCallback mInitializeCb = null;
// Singleton instance
private static final CameraExtensionManagerGlobal GLOBAL_CAMERA_MANAGER =
@@ -328,6 +332,40 @@
}
}
}
+
+ private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
+ @Override
+ public void binderDied() {
+ synchronized (mLock) {
+ mInitializeCb = null;
+ }
+ }
+ };
+
+ public boolean initializeSession(IInitializeSessionCallback cb) {
+ synchronized (mLock) {
+ if (mInitializeCb == null) {
+ mInitializeCb = cb;
+ try {
+ mInitializeCb.asBinder().linkToDeath(mDeathRecipient, 0);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void releaseSession() {
+ synchronized (mLock) {
+ if (mInitializeCb != null) {
+ mInitializeCb.asBinder().unlinkToDeath(mDeathRecipient, 0);
+ mInitializeCb = null;
+ }
+ }
+ }
}
/**
@@ -353,6 +391,26 @@
/**
* @hide
*/
+ public static boolean initializeSession(IInitializeSessionCallback cb) {
+ if (!EXTENSIONS_PRESENT) {
+ return false;
+ }
+ return CameraExtensionManagerGlobal.get().initializeSession(cb);
+ }
+
+ /**
+ * @hide
+ */
+ public static void releaseSession() {
+ if (!EXTENSIONS_PRESENT) {
+ return;
+ }
+ CameraExtensionManagerGlobal.get().releaseSession();
+ }
+
+ /**
+ * @hide
+ */
public static Pair<PreviewExtenderImpl, ImageCaptureExtenderImpl> initializeExtension(
int extensionType) {
switch (extensionType) {
@@ -538,6 +596,39 @@
CameraExtensionsProxyService.unregisterClient(clientId);
}
+ private boolean checkCameraPermission() {
+ int allowed = CameraExtensionsProxyService.this.checkPermission(
+ android.Manifest.permission.CAMERA, Binder.getCallingPid(),
+ Binder.getCallingUid());
+ return (PackageManager.PERMISSION_GRANTED == allowed);
+ }
+
+ @Override
+ public void initializeSession(IInitializeSessionCallback cb) {
+ try {
+ if (!checkCameraPermission()) {
+ Log.i(TAG, "Camera permission required for initializing capture session");
+ cb.onFailure();
+ return;
+ }
+
+ if (CameraExtensionsProxyService.initializeSession(cb)) {
+ cb.onSuccess();
+ } else {
+ cb.onFailure();
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Client doesn't respond!");
+ }
+ }
+
+ @Override
+ public void releaseSession() {
+ if (checkCameraPermission()) {
+ CameraExtensionsProxyService.releaseSession();
+ }
+ }
+
@Override
public boolean advancedExtensionsSupported() {
return ADVANCED_API_SUPPORTED;
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index bba50a7..c3fc995 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -5477,8 +5477,8 @@
getPendingTransaction().setMatrix(getSurfaceControl(),
newHScale, 0, 0, newVScale);
mLastGlobalScale = mGlobalScale;
- mLastHScale = mHScale;
- mLastVScale = mVScale;
+ mLastHScale = newHScale;
+ mLastVScale = newVScale;
}
}