Merge "Use new CarAudioManager.registerCarVolumeCallback API"
diff --git a/api/current.txt b/api/current.txt
index 2ef4a39..f6f5476 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11479,6 +11479,7 @@
field public static final java.lang.String FEATURE_HIFI_SENSORS = "android.hardware.sensor.hifi_sensors";
field public static final java.lang.String FEATURE_HOME_SCREEN = "android.software.home_screen";
field public static final java.lang.String FEATURE_INPUT_METHODS = "android.software.input_methods";
+ field public static final java.lang.String FEATURE_IPSEC_TUNNELS = "android.software.ipsec_tunnels";
field public static final java.lang.String FEATURE_IRIS = "android.hardware.iris";
field public static final java.lang.String FEATURE_LEANBACK = "android.software.leanback";
field public static final java.lang.String FEATURE_LEANBACK_ONLY = "android.software.leanback_only";
diff --git a/api/system-current.txt b/api/system-current.txt
index 57b7eed..9873c37 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -2925,6 +2925,13 @@
field public static final int RADIO_TUNER = 1998; // 0x7ce
}
+ public static class MediaTimestamp.Builder {
+ ctor public MediaTimestamp.Builder();
+ ctor public MediaTimestamp.Builder(android.media.MediaTimestamp);
+ method public android.media.MediaTimestamp build();
+ method public android.media.MediaTimestamp.Builder setMediaTimestamp(long, long, float);
+ }
+
public class PlayerProxy {
method public void pause();
method public void setPan(float);
@@ -2945,7 +2952,7 @@
ctor public TimedMetaData.Builder();
ctor public TimedMetaData.Builder(android.media.TimedMetaData);
method public android.media.TimedMetaData build();
- method public android.media.TimedMetaData.Builder setTimedMetaData(int, byte[]);
+ method public android.media.TimedMetaData.Builder setTimedMetaData(long, byte[]);
}
}
@@ -3035,7 +3042,6 @@
package android.media.session {
public final class MediaSessionManager {
- method public android.media.session.ISession createSession(android.media.session.MediaSession.CallbackStub, java.lang.String, int);
method public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, android.os.Handler);
method public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, android.os.Handler);
}
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 3069be6..f2fb33f 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -476,9 +476,11 @@
public static final int OP_READ_MEDIA_IMAGES = 85;
/** @hide Write media of image type. */
public static final int OP_WRITE_MEDIA_IMAGES = 86;
+ /** @hide Has a legacy (non-isolated) view of storage. */
+ public static final int OP_LEGACY_STORAGE = 87;
/** @hide */
@UnsupportedAppUsage
- public static final int _NUM_OP = 87;
+ public static final int _NUM_OP = 88;
/** Access to coarse location information. */
public static final String OPSTR_COARSE_LOCATION = "android:coarse_location";
@@ -745,6 +747,8 @@
public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
/** @hide Write media of image type. */
public static final String OPSTR_WRITE_MEDIA_IMAGES = "android:write_media_images";
+ /** @hide Has a legacy (non-isolated) view of storage. */
+ public static final String OPSTR_LEGACY_STORAGE = "android:legacy_storage";
// Warning: If an permission is added here it also has to be added to
// com.android.packageinstaller.permission.utils.EventLogger
@@ -903,6 +907,7 @@
OP_WRITE_MEDIA_VIDEO, // WRITE_MEDIA_VIDEO
OP_READ_MEDIA_IMAGES, // READ_MEDIA_IMAGES
OP_WRITE_MEDIA_IMAGES, // WRITE_MEDIA_IMAGES
+ OP_LEGACY_STORAGE, // LEGACY_STORAGE
};
/**
@@ -996,6 +1001,7 @@
OPSTR_WRITE_MEDIA_VIDEO,
OPSTR_READ_MEDIA_IMAGES,
OPSTR_WRITE_MEDIA_IMAGES,
+ OPSTR_LEGACY_STORAGE,
};
/**
@@ -1090,6 +1096,7 @@
"WRITE_MEDIA_VIDEO",
"READ_MEDIA_IMAGES",
"WRITE_MEDIA_IMAGES",
+ "LEGACY_STORAGE",
};
/**
@@ -1185,6 +1192,7 @@
null, // no permission for OP_WRITE_MEDIA_VIDEO
Manifest.permission.READ_MEDIA_IMAGES,
null, // no permission for OP_WRITE_MEDIA_IMAGES
+ null, // no permission for OP_LEGACY_STORAGE
};
/**
@@ -1280,6 +1288,7 @@
null, // WRITE_MEDIA_VIDEO
null, // READ_MEDIA_IMAGES
null, // WRITE_MEDIA_IMAGES
+ null, // LEGACY_STORAGE
};
/**
@@ -1374,6 +1383,7 @@
false, // WRITE_MEDIA_VIDEO
false, // READ_MEDIA_IMAGES
false, // WRITE_MEDIA_IMAGES
+ false, // LEGACY_STORAGE
};
/**
@@ -1467,6 +1477,7 @@
AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_VIDEO
AppOpsManager.MODE_ALLOWED, // READ_MEDIA_IMAGES
AppOpsManager.MODE_ERRORED, // WRITE_MEDIA_IMAGES
+ AppOpsManager.MODE_DEFAULT, // LEGACY_STORAGE
};
/**
@@ -1564,6 +1575,7 @@
false, // WRITE_MEDIA_VIDEO
false, // READ_MEDIA_IMAGES
false, // WRITE_MEDIA_IMAGES
+ false, // LEGACY_STORAGE
};
/**
diff --git a/core/java/android/app/job/JobParameters.java b/core/java/android/app/job/JobParameters.java
index 578a9ae..3cc56ae 100644
--- a/core/java/android/app/job/JobParameters.java
+++ b/core/java/android/app/job/JobParameters.java
@@ -47,6 +47,8 @@
public static final int REASON_TIMEOUT = JobProtoEnums.STOP_REASON_TIMEOUT; // 3.
/** @hide */
public static final int REASON_DEVICE_IDLE = JobProtoEnums.STOP_REASON_DEVICE_IDLE; // 4.
+ /** @hide */
+ public static final int REASON_DEVICE_THERMAL = JobProtoEnums.STOP_REASON_DEVICE_THERMAL; // 5.
/** @hide */
public static String getReasonName(int reason) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index b7df2bf..f40be84 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2687,6 +2687,16 @@
"android.software.device_id_attestation";
/**
+ * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device has
+ * the requisite kernel support for multinetworking-capable IPsec tunnels.
+ *
+ * <p>This feature implies that the device supports XFRM Interfaces (CONFIG_XFRM_INTERFACE), or
+ * VTIs with kernel patches allowing updates of output/set mark via UPDSA.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_IPSEC_TUNNELS = "android.software.ipsec_tunnels";
+
+ /**
* Extra field name for the URI to a verification file. Passed to a package
* verifier.
*
diff --git a/core/java/android/service/autofill/augmented/FillWindow.java b/core/java/android/service/autofill/augmented/FillWindow.java
index 9e3aba4..27df845 100644
--- a/core/java/android/service/autofill/augmented/FillWindow.java
+++ b/core/java/android/service/autofill/augmented/FillWindow.java
@@ -26,6 +26,7 @@
import android.service.autofill.augmented.PresentationParams.Area;
import android.util.Log;
import android.view.Gravity;
+import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
@@ -140,10 +141,24 @@
// TODO(b/111330312): make sure all touch events are handled, window is always closed,
// etc.
- mDialog = new Dialog(rootView.getContext());
+ mDialog = new Dialog(rootView.getContext()) {
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {
+ FillWindow.this.destroy();
+ }
+ return false;
+ }
+ };
mCloseGuard.open("destroy");
final Window window = mDialog.getWindow();
window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
+ // Makes sure touch outside the dialog is received by the window behind the dialog.
+ window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
+ // Makes sure the touch outside the dialog is received by the dialog to dismiss it.
+ window.addFlags(WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
+ // Makes sure keyboard shows up.
+ window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
final int height = rect.bottom - rect.top;
final int width = rect.right - rect.left;
diff --git a/core/proto/android/app/job/enums.proto b/core/proto/android/app/job/enums.proto
index 2290b2f..bba8328 100644
--- a/core/proto/android/app/job/enums.proto
+++ b/core/proto/android/app/job/enums.proto
@@ -30,4 +30,5 @@
STOP_REASON_PREEMPT = 2;
STOP_REASON_TIMEOUT = 3;
STOP_REASON_DEVICE_IDLE = 4;
+ STOP_REASON_DEVICE_THERMAL = 5;
}
diff --git a/core/proto/android/server/jobscheduler.proto b/core/proto/android/server/jobscheduler.proto
index 231caab..c2bc7bf 100644
--- a/core/proto/android/server/jobscheduler.proto
+++ b/core/proto/android/server/jobscheduler.proto
@@ -41,6 +41,7 @@
optional int64 last_heartbeat_time_millis = 16;
optional int64 next_heartbeat_time_millis = 17;
optional bool in_parole = 18;
+ optional bool in_thermal = 19;
repeated int32 started_users = 2;
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 594ae6b..1dd42b8 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1595,7 +1595,7 @@
@hide This should only be used by ManagedProvisioning app.
-->
<permission android:name="android.permission.NETWORK_MANAGED_PROVISIONING"
- android:protectionLevel="signature|privileged" />
+ android:protectionLevel="signature" />
<!-- #SystemApi @hide Allows applications to access information about LoWPAN interfaces.
<p>Not for use by third-party applications. -->
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index ed7d5e5..d22eaf3 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -178,6 +178,7 @@
"renderthread/CanvasContext.cpp",
"renderthread/DrawFrameTask.cpp",
"renderthread/EglManager.cpp",
+ "renderthread/ReliableSurface.cpp",
"renderthread/VulkanManager.cpp",
"renderthread/RenderProxy.cpp",
"renderthread/RenderTask.cpp",
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index c63e449..0b847af 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -912,18 +912,6 @@
fDL->drawAnnotation(rect, key, val);
}
-void RecordingCanvas::onDrawText(const void* text, size_t bytes, SkScalar x, SkScalar y,
- const SkPaint& paint) {
- fDL->drawText(text, bytes, x, y, paint);
-}
-void RecordingCanvas::onDrawPosText(const void* text, size_t bytes, const SkPoint pos[],
- const SkPaint& paint) {
- fDL->drawPosText(text, bytes, pos, paint);
-}
-void RecordingCanvas::onDrawPosTextH(const void* text, size_t bytes, const SkScalar xs[],
- SkScalar y, const SkPaint& paint) {
- fDL->drawPosTextH(text, bytes, xs, y, paint);
-}
void RecordingCanvas::onDrawTextRSXform(const void* text, size_t bytes, const SkRSXform xform[],
const SkRect* cull, const SkPaint& paint) {
fDL->drawTextRSXform(text, bytes, xform, cull, paint);
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 08cfc62..35cf707 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -170,10 +170,6 @@
void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
- void onDrawText(const void*, size_t, SkScalar x, SkScalar y, const SkPaint&) override;
- void onDrawPosText(const void*, size_t, const SkPoint[], const SkPaint&) override;
- void onDrawPosTextH(const void*, size_t, const SkScalar[], SkScalar, const SkPaint&) override;
-
void onDrawTextRSXform(const void*, size_t, const SkRSXform[], const SkRect*,
const SkPaint&) override;
void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;
diff --git a/libs/hwui/pipeline/skia/DumpOpsCanvas.h b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
index 2062194..2b5d580 100644
--- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h
+++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
@@ -82,18 +82,6 @@
mOutput << mIdent << "drawDRRect" << std::endl;
}
- void onDrawText(const void*, size_t, SkScalar, SkScalar, const SkPaint&) override {
- mOutput << mIdent << "drawText" << std::endl;
- }
-
- void onDrawPosText(const void*, size_t, const SkPoint[], const SkPaint&) override {
- mOutput << mIdent << "drawPosText" << std::endl;
- }
-
- void onDrawPosTextH(const void*, size_t, const SkScalar[], SkScalar, const SkPaint&) override {
- mOutput << mIdent << "drawPosTextH" << std::endl;
- }
-
void onDrawTextRSXform(const void*, size_t, const SkRSXform[], const SkRect*,
const SkPaint&) override {
mOutput << mIdent << "drawTextRSXform" << std::endl;
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
index 142bca9..07979a2 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.cpp
@@ -155,7 +155,7 @@
}
}
-bool SkiaOpenGLPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior,
+bool SkiaOpenGLPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior,
ColorMode colorMode) {
if (mEglSurface != EGL_NO_SURFACE) {
mEglManager.destroySurface(mEglSurface);
diff --git a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
index 4ab3541..47991069 100644
--- a/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaOpenGLPipeline.h
@@ -42,7 +42,7 @@
bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) override;
DeferredLayerUpdater* createTextureLayer() override;
- bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior,
+ bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior,
renderthread::ColorMode colorMode) override;
void onStop() override;
bool isSurfaceReady() override;
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
index 3607b23..437b5dc 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.cpp
@@ -115,7 +115,7 @@
void SkiaVulkanPipeline::onStop() {}
-bool SkiaVulkanPipeline::setSurface(Surface* surface, SwapBehavior swapBehavior,
+bool SkiaVulkanPipeline::setSurface(ANativeWindow* surface, SwapBehavior swapBehavior,
ColorMode colorMode) {
if (mVkSurface) {
mVkManager.destroySurface(mVkSurface);
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 14c0d69..02874c7 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -38,7 +38,7 @@
bool swapBuffers(const renderthread::Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) override;
DeferredLayerUpdater* createTextureLayer() override;
- bool setSurface(Surface* window, renderthread::SwapBehavior swapBehavior,
+ bool setSurface(ANativeWindow* surface, renderthread::SwapBehavior swapBehavior,
renderthread::ColorMode colorMode) override;
void onStop() override;
bool isSurfaceReady() override;
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 6869972..4e4262c 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -142,7 +142,12 @@
void CanvasContext::setSurface(sp<Surface>&& surface) {
ATRACE_CALL();
- mNativeSurface = std::move(surface);
+ if (surface) {
+ mNativeSurface = new ReliableSurface{std::move(surface)};
+ mNativeSurface->setDequeueTimeout(500_ms);
+ } else {
+ mNativeSurface = nullptr;
+ }
ColorMode colorMode = mWideColorGamut ? ColorMode::WideColorGamut : ColorMode::SRGB;
bool hasSurface = mRenderPipeline->setSurface(mNativeSurface.get(), mSwapBehavior, colorMode);
@@ -285,10 +290,11 @@
info.damageAccumulator = &mDamageAccumulator;
info.layerUpdateQueue = &mLayerUpdateQueue;
+ info.out.canDrawThisFrame = true;
mAnimationContext->startFrame(info.mode);
mRenderPipeline->onPrepareTree();
- for (const sp<RenderNode>& node : mRenderNodes) {
+ for (const sp<RenderNode> &node : mRenderNodes) {
// Only the primary target node will be drawn full - all other nodes would get drawn in
// real time mode. In case of a window, the primary node is the window content and the other
// node(s) are non client / filler nodes.
@@ -304,7 +310,7 @@
mIsDirty = true;
- if (CC_UNLIKELY(!mNativeSurface.get())) {
+ if (CC_UNLIKELY(!hasSurface())) {
mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
info.out.canDrawThisFrame = false;
return;
@@ -312,7 +318,7 @@
if (CC_LIKELY(mSwapHistory.size() && !Properties::forceDrawFrame)) {
nsecs_t latestVsync = mRenderThread.timeLord().latestVsync();
- SwapHistory& lastSwap = mSwapHistory.back();
+ SwapHistory &lastSwap = mSwapHistory.back();
nsecs_t vsyncDelta = std::abs(lastSwap.vsyncTime - latestVsync);
// The slight fudge-factor is to deal with cases where
// the vsync was estimated due to being slow handling the signal.
@@ -333,7 +339,19 @@
info.out.canDrawThisFrame = false;
}
- if (!info.out.canDrawThisFrame) {
+ if (info.out.canDrawThisFrame) {
+ int err = mNativeSurface->reserveNext();
+ if (err != OK) {
+ mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
+ info.out.canDrawThisFrame = false;
+ ALOGW("reserveNext failed, error = %d (%s)", err, strerror(-err));
+ if (err != TIMED_OUT) {
+ // A timed out surface can still recover, but assume others are permanently dead.
+ setSurface(nullptr);
+ return;
+ }
+ }
+ } else {
mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame);
}
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 70be4a6..9e7abf4 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -25,6 +25,7 @@
#include "IRenderPipeline.h"
#include "LayerUpdateQueue.h"
#include "RenderNode.h"
+#include "ReliableSurface.h"
#include "renderthread/RenderTask.h"
#include "renderthread/RenderThread.h"
#include "thread/Task.h"
@@ -219,7 +220,7 @@
EGLint mLastFrameHeight = 0;
RenderThread& mRenderThread;
- sp<Surface> mNativeSurface;
+ sp<ReliableSurface> mNativeSurface;
// stopped indicates the CanvasContext will reject actual redraw operations,
// and defer repaint until it is un-stopped
bool mStopped = false;
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 65ced6a..8230dfd 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -31,6 +31,8 @@
#include <string>
#include <vector>
+#include <system/window.h>
+#include <gui/Surface.h>
#define GLES_VERSION 2
@@ -106,7 +108,7 @@
LOG_ALWAYS_FATAL_IF(eglInitialize(mEglDisplay, &major, &minor) == EGL_FALSE,
"Failed to initialize display %p! err=%s", mEglDisplay, eglErrorString());
- ALOGI("Initialized EGL, version %d.%d", (int)major, (int)minor);
+ ALOGV("Initialized EGL, version %d.%d", (int)major, (int)minor);
initExtensions();
diff --git a/libs/hwui/renderthread/IRenderPipeline.h b/libs/hwui/renderthread/IRenderPipeline.h
index 4972554..42e17b273 100644
--- a/libs/hwui/renderthread/IRenderPipeline.h
+++ b/libs/hwui/renderthread/IRenderPipeline.h
@@ -28,9 +28,9 @@
class GrContext;
-namespace android {
+struct ANativeWindow;
-class Surface;
+namespace android {
namespace uirenderer {
@@ -67,7 +67,7 @@
virtual bool swapBuffers(const Frame& frame, bool drew, const SkRect& screenDirty,
FrameInfo* currentFrameInfo, bool* requireSwap) = 0;
virtual DeferredLayerUpdater* createTextureLayer() = 0;
- virtual bool setSurface(Surface* window, SwapBehavior swapBehavior, ColorMode colorMode) = 0;
+ virtual bool setSurface(ANativeWindow* window, SwapBehavior swapBehavior, ColorMode colorMode) = 0;
virtual void onStop() = 0;
virtual bool isSurfaceReady() = 0;
virtual bool isContextReady() = 0;
diff --git a/libs/hwui/renderthread/ReliableSurface.cpp b/libs/hwui/renderthread/ReliableSurface.cpp
new file mode 100644
index 0000000..6f2b9df
--- /dev/null
+++ b/libs/hwui/renderthread/ReliableSurface.cpp
@@ -0,0 +1,318 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#include "ReliableSurface.h"
+
+#include <private/android/AHardwareBufferHelpers.h>
+
+namespace android::uirenderer::renderthread {
+
+// TODO: Re-enable after addressing more of the TODO's
+// With this disabled we won't have a good up-front signal that the surface is no longer valid,
+// however we can at least handle that reactively post-draw. There's just not a good mechanism
+// to propagate this error back to the caller
+constexpr bool DISABLE_BUFFER_PREFETCH = true;
+
+// TODO: Make surface less protected
+// This exists because perform is a varargs, and ANativeWindow has no va_list perform.
+// So wrapping/chaining that is hard. Telling the compiler to ignore protected is easy, so we do
+// that instead
+struct SurfaceExposer : Surface {
+ // Make warnings happy
+ SurfaceExposer() = delete;
+
+ using Surface::setBufferCount;
+ using Surface::setSwapInterval;
+ using Surface::dequeueBuffer;
+ using Surface::queueBuffer;
+ using Surface::cancelBuffer;
+ using Surface::lockBuffer_DEPRECATED;
+ using Surface::perform;
+};
+
+#define callProtected(surface, func, ...) ((*surface).*&SurfaceExposer::func)(__VA_ARGS__)
+
+ReliableSurface::ReliableSurface(sp<Surface>&& surface) : mSurface(std::move(surface)) {
+ LOG_ALWAYS_FATAL_IF(!mSurface, "Error, unable to wrap a nullptr");
+
+ ANativeWindow::setSwapInterval = hook_setSwapInterval;
+ ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
+ ANativeWindow::cancelBuffer = hook_cancelBuffer;
+ ANativeWindow::queueBuffer = hook_queueBuffer;
+ ANativeWindow::query = hook_query;
+ ANativeWindow::perform = hook_perform;
+
+ ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
+ ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
+ ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
+ ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
+}
+
+ReliableSurface::~ReliableSurface() {
+ clearReservedBuffer();
+}
+
+void ReliableSurface::perform(int operation, va_list args) {
+ std::lock_guard _lock{mMutex};
+
+ switch (operation) {
+ case NATIVE_WINDOW_SET_USAGE:
+ mUsage = va_arg(args, uint32_t);
+ break;
+ case NATIVE_WINDOW_SET_USAGE64:
+ mUsage = va_arg(args, uint64_t);
+ break;
+ case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
+ /* width */ va_arg(args, uint32_t);
+ /* height */ va_arg(args, uint32_t);
+ mFormat = va_arg(args, PixelFormat);
+ break;
+ case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
+ mFormat = va_arg(args, PixelFormat);
+ break;
+ }
+}
+
+int ReliableSurface::reserveNext() {
+ {
+ std::lock_guard _lock{mMutex};
+ if (mReservedBuffer) {
+ ALOGW("reserveNext called but there was already a buffer reserved?");
+ return OK;
+ }
+ if (mInErrorState) {
+ return UNKNOWN_ERROR;
+ }
+ if (mHasDequeuedBuffer) {
+ return OK;
+ }
+ if constexpr (DISABLE_BUFFER_PREFETCH) {
+ return OK;
+ }
+ }
+
+ // TODO: Update this to better handle when requested dimensions have changed
+ // Currently the driver does this via query + perform but that's after we've already
+ // reserved a buffer. Should we do that logic instead? Or should we drop
+ // the backing Surface to the ground and go full manual on the IGraphicBufferProducer instead?
+
+ int fenceFd = -1;
+ ANativeWindowBuffer* buffer = nullptr;
+ int result = callProtected(mSurface, dequeueBuffer, &buffer, &fenceFd);
+
+ {
+ std::lock_guard _lock{mMutex};
+ LOG_ALWAYS_FATAL_IF(mReservedBuffer, "race condition in reserveNext");
+ mReservedBuffer = buffer;
+ mReservedFenceFd.reset(fenceFd);
+ }
+
+ return result;
+}
+
+void ReliableSurface::clearReservedBuffer() {
+ ANativeWindowBuffer* buffer = nullptr;
+ int releaseFd = -1;
+ {
+ std::lock_guard _lock{mMutex};
+ if (mReservedBuffer) {
+ ALOGW("Reserved buffer %p was never used", mReservedBuffer);
+ buffer = mReservedBuffer;
+ releaseFd = mReservedFenceFd.release();
+ }
+ mReservedBuffer = nullptr;
+ mReservedFenceFd.reset();
+ mHasDequeuedBuffer = false;
+ }
+ if (buffer) {
+ callProtected(mSurface, cancelBuffer, buffer, releaseFd);
+ }
+}
+
+int ReliableSurface::cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd) {
+ clearReservedBuffer();
+ if (isFallbackBuffer(buffer)) {
+ if (fenceFd > 0) {
+ close(fenceFd);
+ }
+ return OK;
+ }
+ int result = callProtected(mSurface, cancelBuffer, buffer, fenceFd);
+ return result;
+}
+
+int ReliableSurface::dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd) {
+ {
+ std::lock_guard _lock{mMutex};
+ if (mReservedBuffer) {
+ *buffer = mReservedBuffer;
+ *fenceFd = mReservedFenceFd.release();
+ mReservedBuffer = nullptr;
+ return OK;
+ }
+ }
+
+ int result = callProtected(mSurface, dequeueBuffer, buffer, fenceFd);
+ if (result != OK) {
+ ALOGW("dequeueBuffer failed, error = %d; switching to fallback", result);
+ *buffer = acquireFallbackBuffer();
+ *fenceFd = -1;
+ return *buffer ? OK : INVALID_OPERATION;
+ } else {
+ std::lock_guard _lock{mMutex};
+ mHasDequeuedBuffer = true;
+ }
+ return OK;
+}
+
+int ReliableSurface::queueBuffer(ANativeWindowBuffer* buffer, int fenceFd) {
+ clearReservedBuffer();
+
+ if (isFallbackBuffer(buffer)) {
+ if (fenceFd > 0) {
+ close(fenceFd);
+ }
+ return OK;
+ }
+
+ int result = callProtected(mSurface, queueBuffer, buffer, fenceFd);
+ return result;
+}
+
+bool ReliableSurface::isFallbackBuffer(const ANativeWindowBuffer* windowBuffer) const {
+ if (!mScratchBuffer || !windowBuffer) {
+ return false;
+ }
+ ANativeWindowBuffer* scratchBuffer =
+ AHardwareBuffer_to_ANativeWindowBuffer(mScratchBuffer.get());
+ return windowBuffer == scratchBuffer;
+}
+
+ANativeWindowBuffer* ReliableSurface::acquireFallbackBuffer() {
+ std::lock_guard _lock{mMutex};
+ mInErrorState = true;
+
+ if (mScratchBuffer) {
+ return AHardwareBuffer_to_ANativeWindowBuffer(mScratchBuffer.get());
+ }
+
+ AHardwareBuffer_Desc desc;
+ desc.usage = mUsage;
+ desc.format = mFormat;
+ desc.width = 1;
+ desc.height = 1;
+ desc.layers = 1;
+ desc.rfu0 = 0;
+ desc.rfu1 = 0;
+ AHardwareBuffer* newBuffer = nullptr;
+ int err = AHardwareBuffer_allocate(&desc, &newBuffer);
+ if (err) {
+ // Allocate failed, that sucks
+ ALOGW("Failed to allocate scratch buffer, error=%d", err);
+ return nullptr;
+ }
+ mScratchBuffer.reset(newBuffer);
+ return AHardwareBuffer_to_ANativeWindowBuffer(newBuffer);
+}
+
+Surface* ReliableSurface::getWrapped(const ANativeWindow* window) {
+ return getSelf(window)->mSurface.get();
+}
+
+int ReliableSurface::hook_setSwapInterval(ANativeWindow* window, int interval) {
+ return callProtected(getWrapped(window), setSwapInterval, interval);
+}
+
+int ReliableSurface::hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer,
+ int* fenceFd) {
+ return getSelf(window)->dequeueBuffer(buffer, fenceFd);
+}
+
+int ReliableSurface::hook_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer,
+ int fenceFd) {
+ return getSelf(window)->cancelBuffer(buffer, fenceFd);
+}
+
+int ReliableSurface::hook_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer,
+ int fenceFd) {
+ return getSelf(window)->queueBuffer(buffer, fenceFd);
+}
+
+int ReliableSurface::hook_dequeueBuffer_DEPRECATED(ANativeWindow* window,
+ ANativeWindowBuffer** buffer) {
+ ANativeWindowBuffer* buf;
+ int fenceFd = -1;
+ int result = window->dequeueBuffer(window, &buf, &fenceFd);
+ if (result != OK) {
+ return result;
+ }
+ sp<Fence> fence(new Fence(fenceFd));
+ int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
+ if (waitResult != OK) {
+ ALOGE("dequeueBuffer_DEPRECATED: Fence::wait returned an error: %d", waitResult);
+ window->cancelBuffer(window, buf, -1);
+ return waitResult;
+ }
+ *buffer = buf;
+ return result;
+}
+
+int ReliableSurface::hook_cancelBuffer_DEPRECATED(ANativeWindow* window,
+ ANativeWindowBuffer* buffer) {
+ return window->cancelBuffer(window, buffer, -1);
+}
+
+int ReliableSurface::hook_lockBuffer_DEPRECATED(ANativeWindow* window,
+ ANativeWindowBuffer* buffer) {
+ // This method is a no-op in Surface as well
+ return OK;
+}
+
+int ReliableSurface::hook_queueBuffer_DEPRECATED(ANativeWindow* window,
+ ANativeWindowBuffer* buffer) {
+ return window->queueBuffer(window, buffer, -1);
+}
+
+int ReliableSurface::hook_query(const ANativeWindow* window, int what, int* value) {
+ return getWrapped(window)->query(what, value);
+}
+
+int ReliableSurface::hook_perform(ANativeWindow* window, int operation, ...) {
+ // Drop the reserved buffer if there is one since this (probably) mutated buffer dimensions
+ // TODO: Filter to things that only affect the reserved buffer
+ // TODO: Can we mutate the reserved buffer in some cases?
+ getSelf(window)->clearReservedBuffer();
+ va_list args;
+ va_start(args, operation);
+ int result = callProtected(getWrapped(window), perform, operation, args);
+ va_end(args);
+
+ switch (operation) {
+ case NATIVE_WINDOW_SET_BUFFERS_FORMAT:
+ case NATIVE_WINDOW_SET_USAGE:
+ case NATIVE_WINDOW_SET_USAGE64:
+ va_start(args, operation);
+ getSelf(window)->perform(operation, args);
+ va_end(args);
+ break;
+ default:
+ break;
+ }
+
+ return result;
+}
+
+}; // namespace android::uirenderer::renderthread
\ No newline at end of file
diff --git a/libs/hwui/renderthread/ReliableSurface.h b/libs/hwui/renderthread/ReliableSurface.h
new file mode 100644
index 0000000..0bfc72e
--- /dev/null
+++ b/libs/hwui/renderthread/ReliableSurface.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+#pragma once
+
+#include <gui/Surface.h>
+#include <utils/Macros.h>
+#include <utils/StrongPointer.h>
+
+#include <memory>
+
+namespace android::uirenderer::renderthread {
+
+class ReliableSurface : public ANativeObjectBase<ANativeWindow, ReliableSurface, RefBase> {
+ PREVENT_COPY_AND_ASSIGN(ReliableSurface);
+
+public:
+ ReliableSurface(sp<Surface>&& surface);
+ ~ReliableSurface();
+
+ void setDequeueTimeout(nsecs_t timeout) { mSurface->setDequeueTimeout(timeout); }
+
+ int reserveNext();
+
+ void allocateBuffers() { mSurface->allocateBuffers(); }
+
+ int query(int what, int* value) const { return mSurface->query(what, value); }
+
+ nsecs_t getLastDequeueStartTime() const { return mSurface->getLastDequeueStartTime(); }
+
+ uint64_t getNextFrameNumber() const { return mSurface->getNextFrameNumber(); }
+
+private:
+ const sp<Surface> mSurface;
+
+ mutable std::mutex mMutex;
+
+ uint64_t mUsage = AHARDWAREBUFFER_USAGE_GPU_FRAMEBUFFER;
+ PixelFormat mFormat = PIXEL_FORMAT_RGBA_8888;
+ std::unique_ptr<AHardwareBuffer, void (*)(AHardwareBuffer*)> mScratchBuffer{
+ nullptr, AHardwareBuffer_release};
+ ANativeWindowBuffer* mReservedBuffer = nullptr;
+ base::unique_fd mReservedFenceFd;
+ bool mHasDequeuedBuffer = false;
+ bool mInErrorState = false;
+
+ bool isFallbackBuffer(const ANativeWindowBuffer* windowBuffer) const;
+ ANativeWindowBuffer* acquireFallbackBuffer();
+ void clearReservedBuffer();
+
+ void perform(int operation, va_list args);
+ int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd);
+ int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
+ int queueBuffer(ANativeWindowBuffer* buffer, int fenceFd);
+
+ static Surface* getWrapped(const ANativeWindow*);
+
+ // ANativeWindow hooks
+ static int hook_cancelBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd);
+ static int hook_dequeueBuffer(ANativeWindow* window, ANativeWindowBuffer** buffer,
+ int* fenceFd);
+ static int hook_queueBuffer(ANativeWindow* window, ANativeWindowBuffer* buffer, int fenceFd);
+
+ static int hook_perform(ANativeWindow* window, int operation, ...);
+ static int hook_query(const ANativeWindow* window, int what, int* value);
+ static int hook_setSwapInterval(ANativeWindow* window, int interval);
+
+ static int hook_cancelBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer);
+ static int hook_dequeueBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer** buffer);
+ static int hook_lockBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer);
+ static int hook_queueBuffer_DEPRECATED(ANativeWindow* window, ANativeWindowBuffer* buffer);
+};
+
+}; // namespace android::uirenderer::renderthread
\ No newline at end of file
diff --git a/libs/hwui/tests/unit/FatalTestCanvas.h b/libs/hwui/tests/unit/FatalTestCanvas.h
index 89f0c52..146662b 100644
--- a/libs/hwui/tests/unit/FatalTestCanvas.h
+++ b/libs/hwui/tests/unit/FatalTestCanvas.h
@@ -30,18 +30,6 @@
void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) {
ADD_FAILURE() << "onDrawDRRect not expected in this test";
}
- void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
- const SkPaint& paint) {
- ADD_FAILURE() << "onDrawText not expected in this test";
- }
- void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
- const SkPaint& paint) {
- ADD_FAILURE() << "onDrawPosText not expected in this test";
- }
- void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY,
- const SkPaint& paint) {
- ADD_FAILURE() << "onDrawPosTextH not expected in this test";
- }
void onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform[],
const SkRect* cullRect, const SkPaint& paint) {
ADD_FAILURE() << "onDrawTextRSXform not expected in this test";
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index 3e3e651..24d2725 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -670,27 +670,43 @@
}
/**
- * Private constructor with an ignored argument to differentiate from the removed default ctor
- * @param ignoredArgument
- */
- private AudioFormat(int ignoredArgument) {
- }
-
- /**
* Constructor used by the JNI. Parameters are not checked for validity.
*/
// Update sound trigger JNI in core/jni/android_hardware_SoundTrigger.cpp when modifying this
// constructor
@UnsupportedAppUsage
private AudioFormat(int encoding, int sampleRate, int channelMask, int channelIndexMask) {
- mEncoding = encoding;
- mSampleRate = sampleRate;
- mChannelMask = channelMask;
- mChannelIndexMask = channelIndexMask;
- mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_ENCODING |
- AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE |
- AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK |
- AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK;
+ this(
+ AUDIO_FORMAT_HAS_PROPERTY_ENCODING
+ | AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE
+ | AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK
+ | AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK,
+ encoding, sampleRate, channelMask, channelIndexMask
+ );
+ }
+
+ private AudioFormat(int propertySetMask,
+ int encoding, int sampleRate, int channelMask, int channelIndexMask) {
+ mPropertySetMask = propertySetMask;
+ mEncoding = (propertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0
+ ? encoding : ENCODING_INVALID;
+ mSampleRate = (propertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) != 0
+ ? sampleRate : SAMPLE_RATE_UNSPECIFIED;
+ mChannelMask = (propertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) != 0
+ ? channelMask : CHANNEL_INVALID;
+ mChannelIndexMask = (propertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0
+ ? channelIndexMask : CHANNEL_INVALID;
+
+ // Compute derived values.
+
+ final int channelIndexCount = Integer.bitCount(getChannelIndexMask());
+ int channelCount = channelCountFromOutChannelMask(getChannelMask());
+ if (channelCount == 0) {
+ channelCount = channelIndexCount;
+ } else if (channelCount != channelIndexCount && channelIndexCount != 0) {
+ channelCount = 0; // position and index channel count mismatch
+ }
+ mChannelCount = channelCount;
}
/** @hide */
@@ -704,14 +720,20 @@
/** @hide */
public final static int AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK = 0x1 << 3;
+ // This is an immutable class, all member variables are final.
+
+ // Essential values.
@UnsupportedAppUsage
- private int mEncoding;
+ private final int mEncoding;
@UnsupportedAppUsage
- private int mSampleRate;
+ private final int mSampleRate;
@UnsupportedAppUsage
- private int mChannelMask;
- private int mChannelIndexMask;
- private int mPropertySetMask;
+ private final int mChannelMask;
+ private final int mChannelIndexMask;
+ private final int mPropertySetMask;
+
+ // Derived values computed in the constructor, cached here.
+ private final int mChannelCount;
/**
* Return the encoding.
@@ -721,9 +743,6 @@
* {@link AudioFormat#ENCODING_INVALID} if not set.
*/
public int getEncoding() {
- if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) == 0) {
- return ENCODING_INVALID;
- }
return mEncoding;
}
@@ -745,9 +764,6 @@
* {@link AudioFormat#CHANNEL_INVALID} if not set.
*/
public int getChannelMask() {
- if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) == 0) {
- return CHANNEL_INVALID;
- }
return mChannelMask;
}
@@ -760,9 +776,6 @@
* {@link AudioFormat#CHANNEL_INVALID} if not set or an invalid mask was used.
*/
public int getChannelIndexMask() {
- if ((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) == 0) {
- return CHANNEL_INVALID;
- }
return mChannelIndexMask;
}
@@ -772,14 +785,7 @@
* Zero is returned if both the channel position mask and the channel index mask are not set.
*/
public int getChannelCount() {
- final int channelIndexCount = Integer.bitCount(getChannelIndexMask());
- int channelCount = channelCountFromOutChannelMask(getChannelMask());
- if (channelCount == 0) {
- channelCount = channelIndexCount;
- } else if (channelCount != channelIndexCount && channelIndexCount != 0) {
- channelCount = 0; // position and index channel count mismatch
- }
- return channelCount;
+ return mChannelCount;
}
/** @hide */
@@ -790,7 +796,7 @@
/** @hide */
public String toLogFriendlyString() {
return String.format("%dch %dHz %s",
- getChannelCount(), mSampleRate, toLogFriendlyEncoding(mEncoding));
+ mChannelCount, mSampleRate, toLogFriendlyEncoding(mEncoding));
}
/**
@@ -839,14 +845,13 @@
* @return a new {@link AudioFormat} object
*/
public AudioFormat build() {
- AudioFormat af = new AudioFormat(1980/*ignored*/);
- af.mEncoding = mEncoding;
- // not calling setSampleRate is equivalent to calling
- // setSampleRate(SAMPLE_RATE_UNSPECIFIED)
- af.mSampleRate = mSampleRate;
- af.mChannelMask = mChannelMask;
- af.mChannelIndexMask = mChannelIndexMask;
- af.mPropertySetMask = mPropertySetMask;
+ AudioFormat af = new AudioFormat(
+ mPropertySetMask,
+ mEncoding,
+ mSampleRate,
+ mChannelMask,
+ mChannelIndexMask
+ );
return af;
}
@@ -1049,11 +1054,13 @@
}
private AudioFormat(Parcel in) {
- mPropertySetMask = in.readInt();
- mEncoding = in.readInt();
- mSampleRate = in.readInt();
- mChannelMask = in.readInt();
- mChannelIndexMask = in.readInt();
+ this(
+ in.readInt(), // propertySetMask
+ in.readInt(), // encoding
+ in.readInt(), // sampleRate
+ in.readInt(), // channelMask
+ in.readInt() // channelIndexMask
+ );
}
public static final Parcelable.Creator<AudioFormat> CREATOR =
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index 4805780..9038f72 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -1711,10 +1711,12 @@
public MediaTimestamp getTimestamp() {
try {
// TODO: get the timestamp from native side
- return new MediaTimestamp(
- getCurrentPosition() * 1000L,
- System.nanoTime(),
- getState() == PLAYER_STATE_PLAYING ? getPlaybackParams().getSpeed() : 0.f);
+ return new MediaTimestamp.Builder()
+ .setMediaTimestamp(
+ getCurrentPosition() * 1000L,
+ System.nanoTime(),
+ getState() == PLAYER_STATE_PLAYING ? getPlaybackParams().getSpeed() : 0.f)
+ .build();
} catch (IllegalStateException e) {
return null;
}
@@ -2398,11 +2400,13 @@
return;
}
Iterator<Value> in = playerMsg.getValuesList().iterator();
- SubtitleData data = new SubtitleData(
- in.next().getInt32Value(), // trackIndex
- in.next().getInt64Value(), // startTimeUs
- in.next().getInt64Value(), // durationUs
- in.next().getBytesValue().toByteArray()); // data
+ SubtitleData data = new SubtitleData.Builder()
+ .setSubtitleData(
+ in.next().getInt32Value(), // trackIndex
+ in.next().getInt64Value(), // startTimeUs
+ in.next().getInt64Value(), // durationUs
+ in.next().getBytesValue().toByteArray()) // data
+ .build();
sendEvent(new EventNotifier() {
@Override
public void notify(EventCallback callback) {
@@ -2426,9 +2430,11 @@
return;
}
Iterator<Value> in = playerMsg.getValuesList().iterator();
- data = new TimedMetaData(
- in.next().getInt64Value(), // timestampUs
- in.next().getBytesValue().toByteArray()); // metaData
+ data = new TimedMetaData.Builder()
+ .setTimedMetaData(
+ in.next().getInt64Value(), // timestampUs
+ in.next().getBytesValue().toByteArray()) // metaData
+ .build();
} else {
data = null;
}
diff --git a/media/java/android/media/MediaTimestamp.java b/media/java/android/media/MediaTimestamp.java
index e079a8e..03e454c 100644
--- a/media/java/android/media/MediaTimestamp.java
+++ b/media/java/android/media/MediaTimestamp.java
@@ -16,6 +16,9 @@
package android.media;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
/**
* An immutable object that represents the linear correlation between the media time
* and the system time. It contains the media clock rate, together with the media timestamp
@@ -117,4 +120,71 @@
+ " clockRate=" + clockRate
+ "}";
}
+
+ /**
+ * Builder class for {@link MediaTimestamp} objects.
+ * <p> Here is an example where <code>Builder</code> is used to define the
+ * {@link MediaTimestamp}:
+ *
+ * <pre class="prettyprint">
+ * MediaTimestamp mts = new MediaTimestamp.Builder()
+ * .setMediaTimestamp(mediaTime, systemTime, rate)
+ * .build();
+ * </pre>
+ * @hide
+ */
+ @SystemApi
+ public static class Builder {
+ long mMediaTimeUs;
+ long mNanoTime;
+ float mClockRate = 1.0f;
+
+ /**
+ * Constructs a new Builder with the defaults.
+ */
+ public Builder() {
+ }
+
+ /**
+ * Constructs a new Builder from a given {@link MediaTimestamp} instance
+ * @param mts the {@link MediaTimestamp} object whose data will be reused
+ * in the new Builder.
+ */
+ public Builder(@NonNull MediaTimestamp mts) {
+ if (mts == null) {
+ throw new IllegalArgumentException("null MediaTimestamp is not allowed");
+ }
+ mMediaTimeUs = mts.mediaTimeUs;
+ mNanoTime = mts.nanoTime;
+ mClockRate = mts.clockRate;
+ }
+
+ /**
+ * Combines all of the fields that have been set and return a new
+ * {@link MediaTimestamp} object.
+ *
+ * @return a new {@link MediaTimestamp} object
+ */
+ public @NonNull MediaTimestamp build() {
+ return new MediaTimestamp(mMediaTimeUs, mNanoTime, mClockRate);
+ }
+
+ /**
+ * Sets the info of media timestamp.
+ *
+ * @param mediaTimeUs the media time of the anchor in microseconds
+ * @param nanoTime the {@link java.lang.System#nanoTime system time} corresponding to
+ * the media time in nanoseconds.
+ * @param clockRate the rate of the media clock in relation to the system time.
+ * @return the same Builder instance.
+ */
+ public @NonNull Builder setMediaTimestamp(
+ long mediaTimeUs, long nanoTime, float clockRate) {
+ mMediaTimeUs = mediaTimeUs;
+ mNanoTime = nanoTime;
+ mClockRate = clockRate;
+
+ return this;
+ }
+ }
}
diff --git a/media/java/android/media/TimedMetaData.java b/media/java/android/media/TimedMetaData.java
index bcc18ef..2a89888 100644
--- a/media/java/android/media/TimedMetaData.java
+++ b/media/java/android/media/TimedMetaData.java
@@ -148,7 +148,7 @@
* It should not be null.
* @return the same Builder instance.
*/
- public @NonNull Builder setTimedMetaData(int timestamp, @NonNull byte[] metaData) {
+ public @NonNull Builder setTimedMetaData(long timestamp, @NonNull byte[] metaData) {
if (metaData == null) {
throw new IllegalArgumentException("null metaData is not allowed");
}
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 5a9a7c8..6a06dd0 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -96,15 +96,9 @@
* @return The binder object from the system
* @hide
*/
- @SystemApi
public @NonNull ISession createSession(@NonNull MediaSession.CallbackStub cbStub,
- @NonNull String tag, int userId) {
- try {
- return mService.createSession(mContext.getPackageName(), cbStub, tag, userId);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
- return null;
+ @NonNull String tag, int userId) throws RemoteException {
+ return mService.createSession(mContext.getPackageName(), cbStub, tag, userId);
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c16f1db..40da881 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1199,8 +1199,8 @@
void setProfileProc(ProcessRecord profileProc) {
mProfileProc = profileProc;
if (mAtmInternal != null) {
- mAtmInternal.setProfileProc(
- profileProc.getWindowProcessController());
+ mAtmInternal.setProfileProc(profileProc == null ? null
+ : profileProc.getWindowProcessController());
}
}
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 173f074..e8b2e8b 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -54,6 +54,8 @@
import android.os.BatteryStatsInternal;
import android.os.Binder;
import android.os.Handler;
+import android.os.IThermalService;
+import android.os.IThermalStatusListener;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
@@ -62,6 +64,7 @@
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.SystemClock;
+import android.os.Temperature;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.provider.Settings;
@@ -75,6 +78,7 @@
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.util.ArrayUtils;
@@ -179,6 +183,11 @@
private final StorageController mStorageController;
/** Need directly for sending uid state changes */
private final DeviceIdleJobsController mDeviceIdleJobsController;
+ /** Need directly for receiving thermal events */
+ private IThermalService mThermalService;
+ /** Thermal constraint. */
+ @GuardedBy("mLock")
+ private boolean mThermalConstraint = false;
/**
* Queue of pending jobs. The JobServiceContext class will receive jobs from this list
@@ -310,6 +319,19 @@
}
/**
+ * Thermal event received from Thermal Service
+ */
+ private final class ThermalStatusListener extends IThermalStatusListener.Stub {
+ @Override public void onStatusChange(int status) {
+ // Throttle for Temperature.THROTTLING_SEVERE and above
+ synchronized (mLock) {
+ mThermalConstraint = status >= Temperature.THROTTLING_SEVERE;
+ }
+ onControllerStateChanged();
+ }
+ }
+
+ /**
* All times are in milliseconds. These constants are kept synchronized with the system
* global Settings. Any access to this class or its fields should be done while
* holding the JobSchedulerService.mLock lock.
@@ -1366,6 +1388,16 @@
}
// Remove any jobs that are not associated with any of the current users.
cancelJobsForNonExistentUsers();
+ // Register thermal callback
+ mThermalService = IThermalService.Stub.asInterface(
+ ServiceManager.getService(Context.THERMAL_SERVICE));
+ if (mThermalService != null) {
+ try {
+ mThermalService.registerThermalStatusListener(new ThermalStatusListener());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to register thermal callback.", e);
+ }
+ }
} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
synchronized (mLock) {
// Let's go!
@@ -1789,14 +1821,26 @@
}
}
+ private boolean isJobThermalConstrainedLocked(JobStatus job) {
+ return mThermalConstraint && job.hasConnectivityConstraint()
+ && (evaluateJobPriorityLocked(job) < JobInfo.PRIORITY_FOREGROUND_APP);
+ }
+
private void stopNonReadyActiveJobsLocked() {
for (int i=0; i<mActiveServices.size(); i++) {
JobServiceContext serviceContext = mActiveServices.get(i);
final JobStatus running = serviceContext.getRunningJobLocked();
- if (running != null && !running.isReady()) {
+ if (running == null) {
+ continue;
+ }
+ if (!running.isReady()) {
serviceContext.cancelExecutingJobLocked(
JobParameters.REASON_CONSTRAINTS_NOT_SATISFIED,
"cancelled due to unsatisfied constraints");
+ } else if (isJobThermalConstrainedLocked(running)) {
+ serviceContext.cancelExecutingJobLocked(
+ JobParameters.REASON_DEVICE_THERMAL,
+ "cancelled due to thermal condition");
}
}
}
@@ -2084,6 +2128,10 @@
return false;
}
+ if (isJobThermalConstrainedLocked(job)) {
+ return false;
+ }
+
final boolean jobPending = mPendingJobs.contains(job);
final boolean jobActive = isCurrentlyActiveLocked(job);
@@ -3033,6 +3081,9 @@
pw.print(" In parole?: ");
pw.print(mInParole);
pw.println();
+ pw.print(" In thermal throttling?: ");
+ pw.print(mThermalConstraint);
+ pw.println();
pw.println();
pw.println("Started users: " + Arrays.toString(mStartedUsers));
@@ -3208,6 +3259,7 @@
proto.write(JobSchedulerServiceDumpProto.NEXT_HEARTBEAT_TIME_MILLIS,
mLastHeartbeatTime + mConstants.STANDBY_HEARTBEAT_TIME - nowUptime);
proto.write(JobSchedulerServiceDumpProto.IN_PAROLE, mInParole);
+ proto.write(JobSchedulerServiceDumpProto.IN_THERMAL, mThermalConstraint);
for (int u : mStartedUsers) {
proto.write(JobSchedulerServiceDumpProto.STARTED_USERS, u);
diff --git a/services/core/java/com/android/server/location/GnssGeofenceProvider.java b/services/core/java/com/android/server/location/GnssGeofenceProvider.java
index 6ac4aeb..a84b0b1 100644
--- a/services/core/java/com/android/server/location/GnssGeofenceProvider.java
+++ b/services/core/java/com/android/server/location/GnssGeofenceProvider.java
@@ -1,18 +1,12 @@
package com.android.server.location;
import android.location.IGpsGeofenceHardware;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
import android.util.Log;
import android.util.SparseArray;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
-
/**
* Manages GNSS Geofence operations.
*/
@@ -34,26 +28,26 @@
public boolean paused;
}
+ private final Object mLock = new Object();
+ @GuardedBy("mLock")
private final GnssGeofenceProviderNative mNative;
+ @GuardedBy("mLock")
private final SparseArray<GeofenceEntry> mGeofenceEntries = new SparseArray<>();
- private final Handler mHandler;
- GnssGeofenceProvider(Looper looper) {
- this(looper, new GnssGeofenceProviderNative());
+ GnssGeofenceProvider() {
+ this(new GnssGeofenceProviderNative());
}
@VisibleForTesting
- GnssGeofenceProvider(Looper looper, GnssGeofenceProviderNative gnssGeofenceProviderNative) {
- mHandler = new Handler(looper);
+ GnssGeofenceProvider(GnssGeofenceProviderNative gnssGeofenceProviderNative) {
mNative = gnssGeofenceProviderNative;
}
- // TODO(b/37460011): use this method in HAL death recovery.
void resumeIfStarted() {
if (DEBUG) {
Log.d(TAG, "resumeIfStarted");
}
- mHandler.post(() -> {
+ synchronized (mLock) {
for (int i = 0; i < mGeofenceEntries.size(); i++) {
GeofenceEntry entry = mGeofenceEntries.valueAt(i);
boolean added = mNative.addGeofence(entry.geofenceId, entry.latitude,
@@ -65,30 +59,21 @@
mNative.pauseGeofence(entry.geofenceId);
}
}
- });
- }
-
- private boolean runOnHandlerThread(Callable<Boolean> callable) {
- FutureTask<Boolean> futureTask = new FutureTask<>(callable);
- mHandler.post(futureTask);
- try {
- return futureTask.get();
- } catch (InterruptedException | ExecutionException e) {
- Log.e(TAG, "Failed running callable.", e);
}
- return false;
}
@Override
public boolean isHardwareGeofenceSupported() {
- return runOnHandlerThread(mNative::isGeofenceSupported);
+ synchronized (mLock) {
+ return mNative.isGeofenceSupported();
+ }
}
@Override
public boolean addCircularHardwareGeofence(int geofenceId, double latitude,
double longitude, double radius, int lastTransition, int monitorTransitions,
int notificationResponsiveness, int unknownTimer) {
- return runOnHandlerThread(() -> {
+ synchronized (mLock) {
boolean added = mNative.addGeofence(geofenceId, latitude, longitude, radius,
lastTransition, monitorTransitions, notificationResponsiveness,
unknownTimer);
@@ -105,23 +90,23 @@
mGeofenceEntries.put(geofenceId, entry);
}
return added;
- });
+ }
}
@Override
public boolean removeHardwareGeofence(int geofenceId) {
- return runOnHandlerThread(() -> {
+ synchronized (mLock) {
boolean removed = mNative.removeGeofence(geofenceId);
if (removed) {
mGeofenceEntries.remove(geofenceId);
}
return removed;
- });
+ }
}
@Override
public boolean pauseHardwareGeofence(int geofenceId) {
- return runOnHandlerThread(() -> {
+ synchronized (mLock) {
boolean paused = mNative.pauseGeofence(geofenceId);
if (paused) {
GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
@@ -130,12 +115,12 @@
}
}
return paused;
- });
+ }
}
@Override
public boolean resumeHardwareGeofence(int geofenceId, int monitorTransitions) {
- return runOnHandlerThread(() -> {
+ synchronized (mLock) {
boolean resumed = mNative.resumeGeofence(geofenceId, monitorTransitions);
if (resumed) {
GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
@@ -145,7 +130,7 @@
}
}
return resumed;
- });
+ }
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index d5e4681..330d1d5 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -762,7 +762,7 @@
looper, this);
mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
mGnssBatchingProvider = new GnssBatchingProvider();
- mGnssGeofenceProvider = new GnssGeofenceProvider(looper);
+ mGnssGeofenceProvider = new GnssGeofenceProvider();
}
/**
@@ -1824,7 +1824,7 @@
/**
* Converts the GPS HAL status to the internal Geofence Hardware status.
*/
- private int getGeofenceStatus(int status) {
+ private static int getGeofenceStatus(int status) {
switch (status) {
case GPS_GEOFENCE_OPERATION_SUCCESS:
return GeofenceHardware.GEOFENCE_SUCCESS;
@@ -1849,75 +1849,87 @@
*/
private void reportGeofenceTransition(int geofenceId, Location location, int transition,
long transitionTimestamp) {
- if (mGeofenceHardwareImpl == null) {
- mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
- }
+ mHandler.post(() -> {
+ if (mGeofenceHardwareImpl == null) {
+ mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+ }
- mGeofenceHardwareImpl.reportGeofenceTransition(
- geofenceId,
- location,
- transition,
- transitionTimestamp,
- GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
- FusedBatchOptions.SourceTechnologies.GNSS);
+ mGeofenceHardwareImpl.reportGeofenceTransition(
+ geofenceId,
+ location,
+ transition,
+ transitionTimestamp,
+ GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
+ FusedBatchOptions.SourceTechnologies.GNSS);
+ });
}
/**
* called from native code to report GPS status change.
*/
private void reportGeofenceStatus(int status, Location location) {
- if (mGeofenceHardwareImpl == null) {
- mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
- }
- int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
- if (status == GPS_GEOFENCE_AVAILABLE) {
- monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
- }
- mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
- GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
- monitorStatus,
- location,
- FusedBatchOptions.SourceTechnologies.GNSS);
+ mHandler.post(() -> {
+ if (mGeofenceHardwareImpl == null) {
+ mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+ }
+ int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
+ if (status == GPS_GEOFENCE_AVAILABLE) {
+ monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
+ }
+ mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
+ GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
+ monitorStatus,
+ location,
+ FusedBatchOptions.SourceTechnologies.GNSS);
+ });
}
/**
* called from native code - Geofence Add callback
*/
private void reportGeofenceAddStatus(int geofenceId, int status) {
- if (mGeofenceHardwareImpl == null) {
- mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
- }
- mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
+ mHandler.post(() -> {
+ if (mGeofenceHardwareImpl == null) {
+ mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+ }
+ mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
+ });
}
/**
* called from native code - Geofence Remove callback
*/
private void reportGeofenceRemoveStatus(int geofenceId, int status) {
- if (mGeofenceHardwareImpl == null) {
- mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
- }
- mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
+ mHandler.post(() -> {
+ if (mGeofenceHardwareImpl == null) {
+ mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+ }
+ mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
+ });
}
/**
* called from native code - Geofence Pause callback
*/
private void reportGeofencePauseStatus(int geofenceId, int status) {
- if (mGeofenceHardwareImpl == null) {
- mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
- }
- mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
+ mHandler.post(() -> {
+ if (mGeofenceHardwareImpl == null) {
+ mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+ }
+ mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
+ });
}
/**
* called from native code - Geofence Resume callback
*/
private void reportGeofenceResumeStatus(int geofenceId, int status) {
- if (mGeofenceHardwareImpl == null) {
- mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
- }
- mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
+ mHandler.post(() -> {
+ if (mGeofenceHardwareImpl == null) {
+ mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
+ }
+ mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
+ });
}
//=============================================================
diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
index d32c299..0e195bc 100644
--- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
+++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java
@@ -29,6 +29,7 @@
import android.os.RemoteException;
import android.os.UserManager;
import android.security.GateKeeper;
+import android.security.Scrypt;
import android.service.gatekeeper.GateKeeperResponse;
import android.service.gatekeeper.IGateKeeperService;
import android.util.ArrayMap;
@@ -1173,11 +1174,10 @@
}
protected byte[] scrypt(String password, byte[] salt, int N, int r, int p, int outLen) {
- return nativeScrypt(password.getBytes(), salt, N, r, p, outLen);
+ return new Scrypt().scrypt(password.getBytes(), salt, N, r, p, outLen);
}
native long nativeSidFromPasswordHandle(byte[] handle);
- native byte[] nativeScrypt(byte[] password, byte[] salt, int N, int r, int p, int outLen);
protected static ArrayList<Byte> toByteArrayList(byte[] data) {
ArrayList<Byte> result = new ArrayList<Byte>(data.length);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 61eb9d4..0301a5b 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -6270,18 +6270,20 @@
finishInstrumentationCallback.run();
}
- mWindowManager.deferSurfaceLayout();
- try {
- if (!restarting && hasVisibleActivities
- && !mRootActivityContainer.resumeFocusedStacksTopActivities()) {
- // If there was nothing to resume, and we are not already restarting this
- // process, but there is a visible activity that is hosted by the process...
- // then make sure all visible activities are running, taking care of
- // restarting this process.
- mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
+ if (!restarting && hasVisibleActivities) {
+ mWindowManager.deferSurfaceLayout();
+ try {
+ if (!mRootActivityContainer.resumeFocusedStacksTopActivities()) {
+ // If there was nothing to resume, and we are not already restarting
+ // this process, but there is a visible activity that is hosted by the
+ // process...then make sure all visible activities are running, taking
+ // care of restarting this process.
+ mRootActivityContainer.ensureActivitiesVisible(null, 0,
+ !PRESERVE_WINDOWS);
+ }
+ } finally {
+ mWindowManager.continueSurfaceLayout();
}
- } finally {
- mWindowManager.continueSurfaceLayout();
}
}
}
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index b85489a..6d72191 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -126,7 +126,6 @@
static_libs: [
"android.hardware.broadcastradio@common-utils-1x-lib",
- "libscrypt_static",
],
product_variables: {
diff --git a/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp b/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp
index bc13fde..9dd6032 100644
--- a/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp
+++ b/services/core/jni/com_android_server_locksettings_SyntheticPasswordManager.cpp
@@ -27,10 +27,6 @@
#include <gatekeeper/password_handle.h>
-extern "C" {
-#include "crypto_scrypt.h"
-}
-
namespace android {
static jlong android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle(JNIEnv* env, jobject, jbyteArray handleArray) {
@@ -48,38 +44,9 @@
}
}
-static jbyteArray android_server_SyntheticPasswordManager_nativeScrypt(JNIEnv* env, jobject, jbyteArray password, jbyteArray salt, jint N, jint r, jint p, jint outLen) {
- if (!password || !salt) {
- return NULL;
- }
-
- int passwordLen = env->GetArrayLength(password);
- int saltLen = env->GetArrayLength(salt);
- jbyteArray ret = env->NewByteArray(outLen);
-
- jbyte* passwordPtr = (jbyte*)env->GetByteArrayElements(password, NULL);
- jbyte* saltPtr = (jbyte*)env->GetByteArrayElements(salt, NULL);
- jbyte* retPtr = (jbyte*)env->GetByteArrayElements(ret, NULL);
-
- int rc = crypto_scrypt((const uint8_t *)passwordPtr, passwordLen,
- (const uint8_t *)saltPtr, saltLen, N, r, p, (uint8_t *)retPtr,
- outLen);
- env->ReleaseByteArrayElements(password, passwordPtr, JNI_ABORT);
- env->ReleaseByteArrayElements(salt, saltPtr, JNI_ABORT);
- env->ReleaseByteArrayElements(ret, retPtr, 0);
-
- if (!rc) {
- return ret;
- } else {
- SLOGE("scrypt failed");
- return NULL;
- }
-}
-
static const JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"nativeSidFromPasswordHandle", "([B)J", (void*)android_server_SyntheticPasswordManager_nativeSidFromPasswordHandle},
- {"nativeScrypt", "([B[BIIII)[B", (void*)android_server_SyntheticPasswordManager_nativeScrypt},
};
int register_android_server_SyntheticPasswordManager(JNIEnv* env) {
diff --git a/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java b/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java
index beb5941..30c7336 100644
--- a/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java
+++ b/services/robotests/src/com/android/server/location/GnssGeofenceProviderTest.java
@@ -7,7 +7,6 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
-import android.os.Looper;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
@@ -44,7 +43,7 @@
when(mMockNative.pauseGeofence(anyInt())).thenReturn(true);
when(mMockNative.removeGeofence(anyInt())).thenReturn(true);
when(mMockNative.resumeGeofence(anyInt(), anyInt())).thenReturn(true);
- mTestProvider = new GnssGeofenceProvider(Looper.myLooper(), mMockNative);
+ mTestProvider = new GnssGeofenceProvider(mMockNative);
mTestProvider.addCircularHardwareGeofence(GEOFENCE_ID, LATITUDE,
LONGITUDE, RADIUS, LAST_TRANSITION, MONITOR_TRANSITIONS,
NOTIFICATION_RESPONSIVENESS,
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index ca0c854..7c52d38 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -27,6 +27,7 @@
import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.NetworkRegistrationState.Domain;
+import android.telephony.NetworkRegistrationState.NRStatus;
import android.text.TextUtils;
import java.lang.annotation.Retention;
@@ -1358,6 +1359,18 @@
}
/**
+ * Get the NR 5G status of the mobile data network.
+ * @return the NR 5G status.
+ * @hide
+ */
+ public @NRStatus int getNrStatus() {
+ final NetworkRegistrationState regState = getNetworkRegistrationState(
+ NetworkRegistrationState.DOMAIN_PS, AccessNetworkConstants.TransportType.WWAN);
+ if (regState == null) return NetworkRegistrationState.NR_STATUS_NONE;
+ return regState.getNrStatus();
+ }
+
+ /**
* @param nrFrequencyRange the frequency range of 5G NR.
* @hide
*/
@@ -1531,7 +1544,6 @@
}
}
-
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
public @TelephonyManager.NetworkType int getDataNetworkType() {