Merge "Fix NPE in NotificationLogger for real this time"
diff --git a/api/system-current.txt b/api/system-current.txt
index e27c29f..f130c69 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -7983,6 +7983,7 @@
method public void callDrawGlFunction(android.graphics.Canvas, long, java.lang.Runnable);
method public boolean canInvokeDrawGlFunctor(android.view.View);
method public void detachDrawGlFunctor(android.view.View, long);
+ method public void drawWebViewFunctor(android.graphics.Canvas, int);
method public android.app.Application getApplication();
method public java.lang.String getDataDirectorySuffix();
method public java.lang.String getErrorString(android.content.Context, int);
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index 6ab7f66..ef69b63 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -138,6 +138,20 @@
}
/**
+ * Call webview draw functor. See API in draw_fn.h.
+ * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()}).
+ * @param functor created by AwDrawFn_CreateFunctor in draw_fn.h.
+ */
+ public void drawWebViewFunctor(@NonNull Canvas canvas, int functor) {
+ if (!(canvas instanceof RecordingCanvas)) {
+ // Canvas#isHardwareAccelerated() is only true for subclasses of RecordingCanvas.
+ throw new IllegalArgumentException(canvas.getClass().getName()
+ + " is not a RecordingCanvas canvas");
+ }
+ ((RecordingCanvas) canvas).drawWebViewFunctor(functor);
+ }
+
+ /**
* Detaches the draw GL functor.
*
* @param nativeDrawGLFunctor the pointer to the native functor that implements
diff --git a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
index 78d366c..2995a8f 100644
--- a/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
+++ b/core/java/com/android/internal/hardware/AmbientDisplayConfiguration.java
@@ -16,14 +16,14 @@
package com.android.internal.hardware;
-import com.android.internal.R;
-
import android.content.Context;
import android.os.Build;
import android.os.SystemProperties;
import android.provider.Settings;
import android.text.TextUtils;
+import com.android.internal.R;
+
public class AmbientDisplayConfiguration {
private final Context mContext;
@@ -37,7 +37,8 @@
public boolean enabled(int user) {
return pulseOnNotificationEnabled(user)
|| pulseOnLongPressEnabled(user)
- || alwaysOnEnabled(user);
+ || alwaysOnEnabled(user)
+ || wakeLockScreenGestureEnabled(user);
}
public boolean pulseOnNotificationEnabled(int user) {
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index 7e69e3a..96798f9 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -61,6 +61,7 @@
"libstatslog",
"libutils",
"libEGL",
+ "libGLESv1_CM",
"libGLESv2",
"libGLESv3",
"libvulkan",
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 20e77b4..5b7ae70 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -37,7 +37,8 @@
}
}
-int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode functorMode) {
+int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype,
+ RenderMode functorMode) {
if (functorMode != RenderMode::OpenGL_ES && functorMode != RenderMode::Vulkan) {
ALOGW("Unknown rendermode %d", (int)functorMode);
return -1;
@@ -47,7 +48,7 @@
ALOGW("Unable to map from GLES platform to a vulkan functor");
return -1;
}
- return WebViewFunctorManager::instance().createFunctor(prototype, functorMode);
+ return WebViewFunctorManager::instance().createFunctor(data, prototype, functorMode);
}
void WebViewFunctor_release(int functor) {
@@ -56,7 +57,9 @@
static std::atomic_int sNextId{1};
-WebViewFunctor::WebViewFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode) {
+WebViewFunctor::WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
+ RenderMode functorMode)
+ : mData(data) {
mFunctor = sNextId++;
mCallbacks = callbacks;
mMode = functorMode;
@@ -66,12 +69,12 @@
destroyContext();
ATRACE_NAME("WebViewFunctor::onDestroy");
- mCallbacks.onDestroyed(mFunctor);
+ mCallbacks.onDestroyed(mFunctor, mData);
}
void WebViewFunctor::sync(const WebViewSyncData& syncData) const {
ATRACE_NAME("WebViewFunctor::sync");
- mCallbacks.onSync(mFunctor, syncData);
+ mCallbacks.onSync(mFunctor, mData, syncData);
}
void WebViewFunctor::drawGl(const DrawGlInfo& drawInfo) {
@@ -79,14 +82,14 @@
if (!mHasContext) {
mHasContext = true;
}
- mCallbacks.gles.draw(mFunctor, drawInfo);
+ mCallbacks.gles.draw(mFunctor, mData, drawInfo);
}
void WebViewFunctor::destroyContext() {
if (mHasContext) {
mHasContext = false;
ATRACE_NAME("WebViewFunctor::onContextDestroyed");
- mCallbacks.onContextDestroyed(mFunctor);
+ mCallbacks.onContextDestroyed(mFunctor, mData);
}
}
@@ -95,9 +98,9 @@
return sInstance;
}
-int WebViewFunctorManager::createFunctor(const WebViewFunctorCallbacks& callbacks,
+int WebViewFunctorManager::createFunctor(void* data, const WebViewFunctorCallbacks& callbacks,
RenderMode functorMode) {
- auto object = std::make_unique<WebViewFunctor>(callbacks, functorMode);
+ auto object = std::make_unique<WebViewFunctor>(data, callbacks, functorMode);
int id = object->id();
auto handle = object->createHandle();
{
@@ -164,4 +167,4 @@
return nullptr;
}
-} // namespace android::uirenderer
\ No newline at end of file
+} // namespace android::uirenderer
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index 2a621dd..1719ce7 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -29,7 +29,7 @@
class WebViewFunctor {
public:
- WebViewFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode);
+ WebViewFunctor(void* data, const WebViewFunctorCallbacks& callbacks, RenderMode functorMode);
~WebViewFunctor();
class Handle : public LightRefBase<Handle> {
@@ -63,6 +63,7 @@
private:
WebViewFunctorCallbacks mCallbacks;
+ void* const mData;
int mFunctor;
RenderMode mMode;
bool mHasContext = false;
@@ -73,7 +74,7 @@
public:
static WebViewFunctorManager& instance();
- int createFunctor(const WebViewFunctorCallbacks& callbacks, RenderMode functorMode);
+ int createFunctor(void* data, const WebViewFunctorCallbacks& callbacks, RenderMode functorMode);
void releaseFunctor(int functor);
void onContextDestroyed();
void destroyFunctor(int functor);
diff --git a/libs/hwui/private/hwui/WebViewFunctor.h b/libs/hwui/private/hwui/WebViewFunctor.h
index e5346aa..da3d06a 100644
--- a/libs/hwui/private/hwui/WebViewFunctor.h
+++ b/libs/hwui/private/hwui/WebViewFunctor.h
@@ -17,6 +17,7 @@
#ifndef FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H
#define FRAMEWORKS_BASE_WEBVIEWFUNCTOR_H
+#include <cutils/compiler.h>
#include <private/hwui/DrawGlInfo.h>
namespace android::uirenderer {
@@ -27,7 +28,7 @@
};
// Static for the lifetime of the process
-RenderMode WebViewFunctor_queryPlatformRenderMode();
+ANDROID_API RenderMode WebViewFunctor_queryPlatformRenderMode();
struct WebViewSyncData {
bool applyForceDark;
@@ -35,21 +36,21 @@
struct WebViewFunctorCallbacks {
// kModeSync, called on RenderThread
- void (*onSync)(int functor, const WebViewSyncData& syncData);
+ void (*onSync)(int functor, void* data, const WebViewSyncData& syncData);
// Called when either the context is destroyed _or_ when the functor's last reference goes
// away. Will always be called with an active context and always on renderthread.
- void (*onContextDestroyed)(int functor);
+ void (*onContextDestroyed)(int functor, void* data);
// Called when the last reference to the handle goes away and the handle is considered
// irrevocably destroyed. Will always be proceeded by a call to onContextDestroyed if
// this functor had ever been drawn.
- void (*onDestroyed)(int functor);
+ void (*onDestroyed)(int functor, void* data);
union {
struct {
// Called on RenderThread. initialize is guaranteed to happen before this call
- void (*draw)(int functor, const DrawGlInfo& params);
+ void (*draw)(int functor, void* data, const DrawGlInfo& params);
} gles;
// TODO: VK support. The current DrawVkInfo is monolithic and needs to be split up for
// what params are valid on what callbacks
@@ -70,12 +71,12 @@
// Creates a new WebViewFunctor from the given prototype. The prototype is copied after
// this function returns. Caller retains full ownership of it.
// Returns -1 if the creation fails (such as an unsupported functorMode + platform mode combination)
-int WebViewFunctor_create(const WebViewFunctorCallbacks& prototype, RenderMode functorMode);
+ANDROID_API int WebViewFunctor_create(void* data, const WebViewFunctorCallbacks& prototype, RenderMode functorMode);
// May be called on any thread to signal that the functor should be destroyed.
// The functor will receive an onDestroyed when the last usage of it is released,
// and it should be considered alive & active until that point.
-void WebViewFunctor_release(int functor);
+ANDROID_API void WebViewFunctor_release(int functor);
} // namespace android::uirenderer
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 5ff8993..6a1ca5a 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -315,24 +315,24 @@
static WebViewFunctorCallbacks createMockFunctor(RenderMode mode) {
auto callbacks = WebViewFunctorCallbacks{
.onSync =
- [](int functor, const WebViewSyncData& data) {
+ [](int functor, void* client_data, const WebViewSyncData& data) {
expectOnRenderThread();
sMockFunctorCounts[functor].sync++;
},
.onContextDestroyed =
- [](int functor) {
+ [](int functor, void* client_data) {
expectOnRenderThread();
sMockFunctorCounts[functor].contextDestroyed++;
},
.onDestroyed =
- [](int functor) {
+ [](int functor, void* client_data) {
expectOnRenderThread();
sMockFunctorCounts[functor].destroyed++;
},
};
switch (mode) {
case RenderMode::OpenGL_ES:
- callbacks.gles.draw = [](int functor, const DrawGlInfo& params) {
+ callbacks.gles.draw = [](int functor, void* client_data, const DrawGlInfo& params) {
expectOnRenderThread();
sMockFunctorCounts[functor].glesDraw++;
};
diff --git a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
index 53bf84f..1b4cf7e 100644
--- a/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
+++ b/libs/hwui/tests/unit/SkiaDisplayListTests.cpp
@@ -100,8 +100,8 @@
GLFunctorDrawable functorDrawable(&functor, nullptr, &dummyCanvas);
skiaDL.mChildFunctors.push_back(&functorDrawable);
- int functor2 = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES),
- RenderMode::OpenGL_ES);
+ int functor2 = WebViewFunctor_create(
+ nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES);
auto& counts = TestUtils::countsForFunctor(functor2);
skiaDL.mChildFunctors.push_back(
skiaDL.allocateDrawable<GLFunctorDrawable>(functor2, &dummyCanvas));
diff --git a/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp b/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp
index c8169af..e1fb8b7 100644
--- a/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp
+++ b/libs/hwui/tests/unit/WebViewFunctorManagerTests.cpp
@@ -27,8 +27,8 @@
using namespace android::uirenderer;
TEST(WebViewFunctor, createDestroyGLES) {
- int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES),
- RenderMode::OpenGL_ES);
+ int functor = WebViewFunctor_create(
+ nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES);
ASSERT_NE(-1, functor);
WebViewFunctor_release(functor);
TestUtils::runOnRenderThreadUnmanaged([](renderthread::RenderThread&) {
@@ -41,8 +41,8 @@
}
TEST(WebViewFunctor, createSyncHandleGLES) {
- int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES),
- RenderMode::OpenGL_ES);
+ int functor = WebViewFunctor_create(
+ nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES);
ASSERT_NE(-1, functor);
auto handle = WebViewFunctorManager::instance().handleFor(functor);
ASSERT_TRUE(handle);
@@ -82,8 +82,8 @@
}
TEST(WebViewFunctor, createSyncDrawGLES) {
- int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES),
- RenderMode::OpenGL_ES);
+ int functor = WebViewFunctor_create(
+ nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES);
ASSERT_NE(-1, functor);
auto handle = WebViewFunctorManager::instance().handleFor(functor);
ASSERT_TRUE(handle);
@@ -109,8 +109,8 @@
}
TEST(WebViewFunctor, contextDestroyed) {
- int functor = WebViewFunctor_create(TestUtils::createMockFunctor(RenderMode::OpenGL_ES),
- RenderMode::OpenGL_ES);
+ int functor = WebViewFunctor_create(
+ nullptr, TestUtils::createMockFunctor(RenderMode::OpenGL_ES), RenderMode::OpenGL_ES);
ASSERT_NE(-1, functor);
auto handle = WebViewFunctorManager::instance().handleFor(functor);
ASSERT_TRUE(handle);
@@ -151,4 +151,4 @@
EXPECT_EQ(2, counts.glesDraw);
EXPECT_EQ(2, counts.contextDestroyed);
EXPECT_EQ(1, counts.destroyed);
-}
\ No newline at end of file
+}
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 5c1915b..f0db1b4 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -47,9 +47,9 @@
PendingIntent getLaunchPendingIntent();
long getFlags();
ParcelableVolumeInfo getVolumeAttributes();
- void adjustVolume(String packageName, in ControllerCallbackLink caller,
+ void adjustVolume(String packageName, String opPackageName, in ControllerCallbackLink caller,
boolean asSystemService, int direction, int flags);
- void setVolumeTo(String packageName, in ControllerCallbackLink caller,
+ void setVolumeTo(String packageName, String opPackageName, in ControllerCallbackLink caller,
int value, int flags);
// These commands are for the TransportControls
diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl
index 5801967..f2c0e32 100644
--- a/media/java/android/media/session/ISessionManager.aidl
+++ b/media/java/android/media/session/ISessionManager.aidl
@@ -35,9 +35,10 @@
List<IBinder> getSessions(in ComponentName compName, int userId);
void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent,
boolean needWakeLock);
- void dispatchVolumeKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent,
- int stream, boolean musicOnly);
- void dispatchAdjustVolume(String packageName, int suggestedStream, int delta, int flags);
+ void dispatchVolumeKeyEvent(String packageName, String opPackageName, boolean asSystemService,
+ in KeyEvent keyEvent, int stream, boolean musicOnly);
+ void dispatchAdjustVolume(String packageName, String opPackageName, int suggestedStream,
+ int delta, int flags);
void addSessionsListener(in IActiveSessionsListener listener, in ComponentName compName,
int userId);
void removeSessionsListener(in IActiveSessionsListener listener);
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 5eb77f9..7b061fe 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -154,7 +154,7 @@
return false;
}
try {
- return mSessionBinder.sendMediaButton(mContext.getOpPackageName(), mCbStub,
+ return mSessionBinder.sendMediaButton(mContext.getPackageName(), mCbStub,
asSystemService, keyEvent);
} catch (RemoteException e) {
// System is dead. =(
@@ -187,8 +187,12 @@
break;
}
try {
- mSessionBinder.adjustVolume(mContext.getOpPackageName(), mCbStub, true,
- direction, AudioManager.FLAG_SHOW_UI);
+ // Note: Need both package name and OP package name. Package name is used for
+ // RemoteUserInfo, and OP package name is used for AudioService's internal
+ // AppOpsManager usages.
+ mSessionBinder.adjustVolume(mContext.getPackageName(),
+ mContext.getOpPackageName(), mCbStub, true, direction,
+ AudioManager.FLAG_SHOW_UI);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling adjustVolumeBy", e);
}
@@ -198,8 +202,11 @@
final int flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE
| AudioManager.FLAG_FROM_KEY;
try {
- mSessionBinder.adjustVolume(mContext.getOpPackageName(), mCbStub, true, 0,
- flags);
+ // Note: Need both package name and OP package name. Package name is used for
+ // RemoteUserInfo, and OP package name is used for AudioService's internal
+ // AppOpsManager usages.
+ mSessionBinder.adjustVolume(mContext.getPackageName(),
+ mContext.getOpPackageName(), mCbStub, true, 0, flags);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling adjustVolumeBy", e);
}
@@ -365,7 +372,11 @@
*/
public void setVolumeTo(int value, int flags) {
try {
- mSessionBinder.setVolumeTo(mContext.getOpPackageName(), mCbStub, value, flags);
+ // Note: Need both package name and OP package name. Package name is used for
+ // RemoteUserInfo, and OP package name is used for AudioService's internal
+ // AppOpsManager usages.
+ mSessionBinder.setVolumeTo(mContext.getPackageName(), mContext.getOpPackageName(),
+ mCbStub, value, flags);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling setVolumeTo.", e);
}
@@ -386,8 +397,11 @@
*/
public void adjustVolume(int direction, int flags) {
try {
- mSessionBinder.adjustVolume(mContext.getOpPackageName(), mCbStub, false, direction,
- flags);
+ // Note: Need both package name and OP package name. Package name is used for
+ // RemoteUserInfo, and OP package name is used for AudioService's internal
+ // AppOpsManager usages.
+ mSessionBinder.adjustVolume(mContext.getPackageName(), mContext.getOpPackageName(),
+ mCbStub, false, direction, flags);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
}
@@ -453,7 +467,7 @@
throw new IllegalArgumentException("command cannot be null or empty");
}
try {
- mSessionBinder.sendCommand(mContext.getOpPackageName(), mCbStub, command, args, cb);
+ mSessionBinder.sendCommand(mContext.getPackageName(), mCbStub, command, args, cb);
} catch (RemoteException e) {
Log.d(TAG, "Dead object in sendCommand.", e);
}
@@ -519,7 +533,7 @@
if (!mCbRegistered) {
try {
- mSessionBinder.registerCallbackListener(mContext.getOpPackageName(), mCbStub);
+ mSessionBinder.registerCallbackListener(mContext.getPackageName(), mCbStub);
mCbRegistered = true;
} catch (RemoteException e) {
Log.e(TAG, "Dead object in registerCallback", e);
@@ -666,7 +680,7 @@
*/
public void prepare() {
try {
- mSessionBinder.prepare(mContext.getOpPackageName(), mCbStub);
+ mSessionBinder.prepare(mContext.getPackageName(), mCbStub);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling prepare.", e);
}
@@ -690,7 +704,7 @@
"You must specify a non-empty String for prepareFromMediaId.");
}
try {
- mSessionBinder.prepareFromMediaId(mContext.getOpPackageName(), mCbStub, mediaId,
+ mSessionBinder.prepareFromMediaId(mContext.getPackageName(), mCbStub, mediaId,
extras);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e);
@@ -717,7 +731,7 @@
query = "";
}
try {
- mSessionBinder.prepareFromSearch(mContext.getOpPackageName(), mCbStub, query,
+ mSessionBinder.prepareFromSearch(mContext.getPackageName(), mCbStub, query,
extras);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling prepare(" + query + ").", e);
@@ -742,7 +756,7 @@
"You must specify a non-empty Uri for prepareFromUri.");
}
try {
- mSessionBinder.prepareFromUri(mContext.getOpPackageName(), mCbStub, uri, extras);
+ mSessionBinder.prepareFromUri(mContext.getPackageName(), mCbStub, uri, extras);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling prepare(" + uri + ").", e);
}
@@ -753,7 +767,7 @@
*/
public void play() {
try {
- mSessionBinder.play(mContext.getOpPackageName(), mCbStub);
+ mSessionBinder.play(mContext.getPackageName(), mCbStub);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling play.", e);
}
@@ -772,7 +786,7 @@
"You must specify a non-empty String for playFromMediaId.");
}
try {
- mSessionBinder.playFromMediaId(mContext.getOpPackageName(), mCbStub, mediaId,
+ mSessionBinder.playFromMediaId(mContext.getPackageName(), mCbStub, mediaId,
extras);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling play(" + mediaId + ").", e);
@@ -795,7 +809,7 @@
query = "";
}
try {
- mSessionBinder.playFromSearch(mContext.getOpPackageName(), mCbStub, query, extras);
+ mSessionBinder.playFromSearch(mContext.getPackageName(), mCbStub, query, extras);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling play(" + query + ").", e);
}
@@ -814,7 +828,7 @@
"You must specify a non-empty Uri for playFromUri.");
}
try {
- mSessionBinder.playFromUri(mContext.getOpPackageName(), mCbStub, uri, extras);
+ mSessionBinder.playFromUri(mContext.getPackageName(), mCbStub, uri, extras);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling play(" + uri + ").", e);
}
@@ -826,7 +840,7 @@
*/
public void skipToQueueItem(long id) {
try {
- mSessionBinder.skipToQueueItem(mContext.getOpPackageName(), mCbStub, id);
+ mSessionBinder.skipToQueueItem(mContext.getPackageName(), mCbStub, id);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
}
@@ -838,7 +852,7 @@
*/
public void pause() {
try {
- mSessionBinder.pause(mContext.getOpPackageName(), mCbStub);
+ mSessionBinder.pause(mContext.getPackageName(), mCbStub);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling pause.", e);
}
@@ -850,7 +864,7 @@
*/
public void stop() {
try {
- mSessionBinder.stop(mContext.getOpPackageName(), mCbStub);
+ mSessionBinder.stop(mContext.getPackageName(), mCbStub);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling stop.", e);
}
@@ -863,7 +877,7 @@
*/
public void seekTo(long pos) {
try {
- mSessionBinder.seekTo(mContext.getOpPackageName(), mCbStub, pos);
+ mSessionBinder.seekTo(mContext.getPackageName(), mCbStub, pos);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling seekTo.", e);
}
@@ -875,7 +889,7 @@
*/
public void fastForward() {
try {
- mSessionBinder.fastForward(mContext.getOpPackageName(), mCbStub);
+ mSessionBinder.fastForward(mContext.getPackageName(), mCbStub);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling fastForward.", e);
}
@@ -886,7 +900,7 @@
*/
public void skipToNext() {
try {
- mSessionBinder.next(mContext.getOpPackageName(), mCbStub);
+ mSessionBinder.next(mContext.getPackageName(), mCbStub);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling next.", e);
}
@@ -898,7 +912,7 @@
*/
public void rewind() {
try {
- mSessionBinder.rewind(mContext.getOpPackageName(), mCbStub);
+ mSessionBinder.rewind(mContext.getPackageName(), mCbStub);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling rewind.", e);
}
@@ -909,7 +923,7 @@
*/
public void skipToPrevious() {
try {
- mSessionBinder.previous(mContext.getOpPackageName(), mCbStub);
+ mSessionBinder.previous(mContext.getPackageName(), mCbStub);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling previous.", e);
}
@@ -924,7 +938,7 @@
*/
public void setRating(Rating rating) {
try {
- mSessionBinder.rate(mContext.getOpPackageName(), mCbStub, rating);
+ mSessionBinder.rate(mContext.getPackageName(), mCbStub, rating);
} catch (RemoteException e) {
Log.wtf(TAG, "Error calling rate.", e);
}
@@ -959,7 +973,7 @@
throw new IllegalArgumentException("CustomAction cannot be null.");
}
try {
- mSessionBinder.sendCustomAction(mContext.getOpPackageName(), mCbStub, action, args);
+ mSessionBinder.sendCustomAction(mContext.getPackageName(), mCbStub, action, args);
} catch (RemoteException e) {
Log.d(TAG, "Dead object in sendCustomAction.", e);
}
diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java
index 73dd55c..7a4116f 100644
--- a/media/java/android/media/session/MediaSessionManager.java
+++ b/media/java/android/media/session/MediaSessionManager.java
@@ -312,7 +312,7 @@
private void dispatchMediaKeyEventInternal(boolean asSystemService, @NonNull KeyEvent keyEvent,
boolean needWakeLock) {
try {
- mService.dispatchMediaKeyEvent(mContext.getOpPackageName(), asSystemService, keyEvent,
+ mService.dispatchMediaKeyEvent(mContext.getPackageName(), asSystemService, keyEvent,
needWakeLock);
} catch (RemoteException e) {
Log.e(TAG, "Failed to send key event.", e);
@@ -348,8 +348,8 @@
private void dispatchVolumeKeyEventInternal(boolean asSystemService, @NonNull KeyEvent keyEvent,
int stream, boolean musicOnly) {
try {
- mService.dispatchVolumeKeyEvent(mContext.getOpPackageName(), asSystemService, keyEvent,
- stream, musicOnly);
+ mService.dispatchVolumeKeyEvent(mContext.getPackageName(), mContext.getOpPackageName(),
+ asSystemService, keyEvent, stream, musicOnly);
} catch (RemoteException e) {
Log.e(TAG, "Failed to send volume key event.", e);
}
@@ -369,8 +369,8 @@
*/
public void dispatchAdjustVolume(int suggestedStream, int direction, int flags) {
try {
- mService.dispatchAdjustVolume(mContext.getOpPackageName(), suggestedStream, direction,
- flags);
+ mService.dispatchAdjustVolume(mContext.getPackageName(), mContext.getOpPackageName(),
+ suggestedStream, direction, flags);
} catch (RemoteException e) {
Log.e(TAG, "Failed to send adjust volume.", e);
}
diff --git a/native/webview/plat_support/Android.bp b/native/webview/plat_support/Android.bp
index 96c9c1c..0936256 100644
--- a/native/webview/plat_support/Android.bp
+++ b/native/webview/plat_support/Android.bp
@@ -22,6 +22,7 @@
name: "libwebviewchromium_plat_support",
srcs: [
+ "draw_functor.cpp",
"draw_gl_functor.cpp",
"draw_vk_functor.cpp",
"functor_utils.cpp",
diff --git a/native/webview/plat_support/draw_fn.h b/native/webview/plat_support/draw_fn.h
index 8d48a58..6afd883 100644
--- a/native/webview/plat_support/draw_fn.h
+++ b/native/webview/plat_support/draw_fn.h
@@ -129,31 +129,31 @@
// Called on render thread while UI thread is blocked. Called for both GL and
// VK.
-typedef void AwDrawFn_OnSync(int functor, AwDrawFn_OnSyncParams* params);
+typedef void AwDrawFn_OnSync(int functor, void* data, AwDrawFn_OnSyncParams* params);
// Called on render thread when either the context is destroyed _or_ when the
// functor's last reference goes away. Will always be called with an active
// context. Called for both GL and VK.
-typedef void AwDrawFn_OnContextDestroyed(int functor);
+typedef void AwDrawFn_OnContextDestroyed(int functor, void* data);
// Called on render thread when the last reference to the handle goes away and
-// the handle is considered irrevocably destroyed. Will always be proceeded by
+// the handle is considered irrevocably destroyed. Will always be preceded by
// a call to OnContextDestroyed if this functor had ever been drawn. Called for
// both GL and VK.
-typedef void AwDrawFn_OnDestroyed(int functor);
+typedef void AwDrawFn_OnDestroyed(int functor, void* data);
// Only called for GL.
-typedef void AwDrawFn_DrawGL(int functor, AwDrawFn_DrawGLParams* params);
+typedef void AwDrawFn_DrawGL(int functor, void* data, AwDrawFn_DrawGLParams* params);
// Initialize vulkan state. Needs to be called again after any
// OnContextDestroyed. Only called for Vulkan.
-typedef void AwDrawFn_InitVk(int functor, AwDrawFn_InitVkParams* params);
+typedef void AwDrawFn_InitVk(int functor, void* data, AwDrawFn_InitVkParams* params);
// Only called for Vulkan.
-typedef void AwDrawFn_DrawVk(int functor, AwDrawFn_DrawVkParams* params);
+typedef void AwDrawFn_DrawVk(int functor, void* data, AwDrawFn_DrawVkParams* params);
// Only called for Vulkan.
-typedef void AwDrawFn_PostDrawVk(int functor,
+typedef void AwDrawFn_PostDrawVk(int functor, void* data,
AwDrawFn_PostDrawVkParams* params);
struct AwDrawFnFunctorCallbacks {
@@ -176,7 +176,7 @@
typedef AwDrawFnRenderMode AwDrawFn_QueryRenderMode(void);
// Create a functor. |functor_callbacks| should be valid until OnDestroyed.
-typedef int AwDrawFn_CreateFunctor(AwDrawFnFunctorCallbacks* functor_callbacks);
+typedef int AwDrawFn_CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks);
// May be called on any thread to signal that the functor should be destroyed.
// The functor will receive an onDestroyed when the last usage of it is
diff --git a/native/webview/plat_support/draw_functor.cpp b/native/webview/plat_support/draw_functor.cpp
new file mode 100644
index 0000000..820bac5
--- /dev/null
+++ b/native/webview/plat_support/draw_functor.cpp
@@ -0,0 +1,144 @@
+/*
+ * 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 "draw_fn.h"
+
+#include <jni.h>
+#include <private/hwui/WebViewFunctor.h>
+#include <utils/Log.h>
+
+#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
+#define COMPILE_ASSERT(expr, err) \
+__unused static const char (err)[(expr) ? 1 : -1] = "";
+
+namespace android {
+namespace {
+
+struct SupportData {
+ void* const data;
+ AwDrawFnFunctorCallbacks callbacks;
+};
+
+void onSync(int functor, void* data,
+ const uirenderer::WebViewSyncData& syncData) {
+ AwDrawFn_OnSyncParams params = {
+ .version = kAwDrawFnVersion,
+ .apply_force_dark = syncData.applyForceDark,
+ };
+ SupportData* support = static_cast<SupportData*>(data);
+ support->callbacks.on_sync(functor, support->data, ¶ms);
+}
+
+void onContextDestroyed(int functor, void* data) {
+ SupportData* support = static_cast<SupportData*>(data);
+ support->callbacks.on_context_destroyed(functor, support->data);
+}
+
+void onDestroyed(int functor, void* data) {
+ SupportData* support = static_cast<SupportData*>(data);
+ support->callbacks.on_destroyed(functor, support->data);
+ delete support;
+}
+
+void draw_gl(int functor, void* data,
+ const uirenderer::DrawGlInfo& draw_gl_params) {
+ AwDrawFn_DrawGLParams params = {
+ .version = kAwDrawFnVersion,
+ .clip_left = draw_gl_params.clipLeft,
+ .clip_top = draw_gl_params.clipTop,
+ .clip_right = draw_gl_params.clipRight,
+ .clip_bottom = draw_gl_params.clipBottom,
+ .width = draw_gl_params.width,
+ .height = draw_gl_params.height,
+ .is_layer = draw_gl_params.isLayer,
+ };
+ COMPILE_ASSERT(NELEM(params.transform) == NELEM(draw_gl_params.transform),
+ mismatched_transform_matrix_sizes);
+ for (int i = 0; i < NELEM(params.transform); ++i) {
+ params.transform[i] = draw_gl_params.transform[i];
+ }
+ SupportData* support = static_cast<SupportData*>(data);
+ support->callbacks.draw_gl(functor, support->data, ¶ms);
+}
+
+int CreateFunctor(void* data, AwDrawFnFunctorCallbacks* functor_callbacks) {
+ static bool callbacks_initialized = false;
+ static uirenderer::WebViewFunctorCallbacks webview_functor_callbacks = {
+ .onSync = &onSync,
+ .onContextDestroyed = &onContextDestroyed,
+ .onDestroyed = &onDestroyed,
+ };
+ if (!callbacks_initialized) {
+ switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) {
+ case uirenderer::RenderMode::OpenGL_ES:
+ webview_functor_callbacks.gles.draw = &draw_gl;
+ break;
+ case uirenderer::RenderMode::Vulkan:
+ break;
+ }
+ callbacks_initialized = true;
+ }
+ SupportData* support = new SupportData{
+ .data = data,
+ .callbacks = *functor_callbacks,
+ };
+ int functor = uirenderer::WebViewFunctor_create(
+ support, webview_functor_callbacks,
+ uirenderer::WebViewFunctor_queryPlatformRenderMode());
+ if (functor <= 0) delete support;
+ return functor;
+}
+
+void ReleaseFunctor(int functor) {
+ uirenderer::WebViewFunctor_release(functor);
+}
+
+AwDrawFnRenderMode QueryRenderMode(void) {
+ switch (uirenderer::WebViewFunctor_queryPlatformRenderMode()) {
+ case uirenderer::RenderMode::OpenGL_ES:
+ return AW_DRAW_FN_RENDER_MODE_OPENGL_ES;
+ case uirenderer::RenderMode::Vulkan:
+ return AW_DRAW_FN_RENDER_MODE_VULKAN;
+ }
+}
+
+jlong GetDrawFnFunctionTable() {
+ static AwDrawFnFunctionTable function_table = {
+ .version = kAwDrawFnVersion,
+ .query_render_mode = &QueryRenderMode,
+ .create_functor = &CreateFunctor,
+ .release_functor = &ReleaseFunctor,
+ };
+ return reinterpret_cast<intptr_t>(&function_table);
+}
+
+const char kClassName[] = "com/android/webview/chromium/DrawFunctor";
+const JNINativeMethod kJniMethods[] = {
+ {"nativeGetFunctionTable", "()J",
+ reinterpret_cast<void*>(GetDrawFnFunctionTable)},
+};
+
+} // namespace
+
+void RegisterDrawFunctor(JNIEnv* env) {
+ jclass clazz = env->FindClass(kClassName);
+ LOG_ALWAYS_FATAL_IF(!clazz, "Unable to find class '%s'", kClassName);
+
+ int res = env->RegisterNatives(clazz, kJniMethods, NELEM(kJniMethods));
+ LOG_ALWAYS_FATAL_IF(res < 0, "register native methods failed: res=%d", res);
+}
+
+} // namespace android
diff --git a/native/webview/plat_support/jni_entry_point.cpp b/native/webview/plat_support/jni_entry_point.cpp
index 4771be1..9599fa6 100644
--- a/native/webview/plat_support/jni_entry_point.cpp
+++ b/native/webview/plat_support/jni_entry_point.cpp
@@ -21,6 +21,7 @@
namespace android {
+void RegisterDrawFunctor(JNIEnv* env);
void RegisterDrawGLFunctor(JNIEnv* env);
void RegisterGraphicsUtils(JNIEnv* env);
@@ -30,6 +31,7 @@
JNIEnv* env = NULL;
jint ret = vm->AttachCurrentThread(&env, NULL);
LOG_ALWAYS_FATAL_IF(ret != JNI_OK, "AttachCurrentThread failed");
+ android::RegisterDrawFunctor(env);
android::RegisterDrawGLFunctor(env);
android::RegisterGraphicsUtils(env);
diff --git a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
index cbebbb3..d6dc211 100644
--- a/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
+++ b/packages/SettingsLib/SettingsSpinner/res/drawable/settings_spinner_background.xml
@@ -18,12 +18,11 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingMode="stack">
<item>
- <shape
- android:tint="?android:attr/colorForeground">
+ <shape>
<corners
android:radius="20dp"/>
<solid
- android:color="@android:color/transparent"/>
+ android:color="?android:attr/colorPrimary"/>
<stroke
android:color="#1f000000"
android:width="1dp"/>
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 04362c1..b6fc355 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -85,6 +85,7 @@
mProxCallback = proxCallback;
mResolver = mContext.getContentResolver();
+ boolean alwaysOn = mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT);
mSensors = new TriggerSensor[] {
new TriggerSensor(
mSensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION),
@@ -116,7 +117,7 @@
new PluginSensor(
new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
Settings.Secure.DOZE_WAKE_SCREEN_GESTURE,
- mConfig.wakeScreenGestureAvailable(),
+ mConfig.wakeScreenGestureAvailable() && alwaysOn,
DozeLog.REASON_SENSOR_WAKE_UP,
false /* reports touch coordinates */,
false /* touchscreen */),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 1b18c6c..fd34ac5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -2803,6 +2803,11 @@
if (animatePulse) {
mAnimateNextPositionUpdate = true;
}
+ // Do not animate the clock when waking up from a pulse.
+ // The height callback will take care of pushing the clock to the right position.
+ if (!mPulsing && !mDozing) {
+ mAnimateNextPositionUpdate = false;
+ }
mNotificationStackScroller.setPulsing(pulsing, animatePulse);
mKeyguardStatusView.setPulsing(pulsing, animatePulse);
mKeyguardBottomArea.setPulsing(pulsing, animatePulse);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 2c756ce..d404982 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -33,6 +33,7 @@
import android.os.Bundle;
import android.os.SystemClock;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.TypedValue;
import android.view.HapticFeedbackConstants;
import android.view.InputDevice;
@@ -304,6 +305,10 @@
.setSubtype(mCode)
.addTaggedData(MetricsEvent.FIELD_NAV_ACTION, action)
.addTaggedData(MetricsEvent.FIELD_FLAGS, flags));
+ // TODO(b/122195391): Added logs to make sure sysui is sending back button events
+ if (mCode == KeyEvent.KEYCODE_BACK && flags != KeyEvent.FLAG_LONG_PRESS) {
+ Log.i(TAG, "Back button event: " + KeyEvent.actionToString(action));
+ }
final int repeatCount = (flags & KeyEvent.FLAG_LONG_PRESS) != 0 ? 1 : 0;
final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, repeatCount,
0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index dd2abde..d49c4a9 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -236,6 +236,7 @@
* {@link AudioManager#ADJUST_SAME}.
*
* @param packageName The package that made the original volume request.
+ * @param opPackageName The op package that made the original volume request.
* @param pid The pid that made the original volume request.
* @param uid The uid that made the original volume request.
* @param caller caller binder. can be {@code null} if it's from the volume key.
@@ -248,7 +249,7 @@
* @param flags Any of the flags from {@link AudioManager}.
* @param useSuggested True to use adjustSuggestedStreamVolume instead of
*/
- public void adjustVolume(String packageName, int pid, int uid,
+ public void adjustVolume(String packageName, String opPackageName, int pid, int uid,
ControllerCallbackLink caller, boolean asSystemService, int direction, int flags,
boolean useSuggested) {
int previousFlagPlaySound = flags & AudioManager.FLAG_PLAY_SOUND;
@@ -258,8 +259,8 @@
if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
// Adjust the volume with a handler not to be blocked by other system service.
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
- postAdjustLocalVolume(stream, direction, flags, packageName, uid, asSystemService,
- useSuggested, previousFlagPlaySound);
+ postAdjustLocalVolume(stream, direction, flags, opPackageName, pid, uid,
+ asSystemService, useSuggested, previousFlagPlaySound);
} else {
if (mVolumeControlType == VolumeProvider.VOLUME_CONTROL_FIXED) {
// Nothing to do, the volume cannot be changed
@@ -290,11 +291,23 @@
}
}
- private void setVolumeTo(String packageName, int pid, int uid,
+ private void setVolumeTo(String packageName, String opPackageName, int pid, int uid,
ControllerCallbackLink caller, int value, int flags) {
if (mVolumeType == PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
int stream = AudioAttributes.toLegacyStreamType(mAudioAttrs);
- mAudioManagerInternal.setStreamVolumeForUid(stream, value, flags, packageName, uid);
+ final int volumeValue = value;
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mAudioManagerInternal.setStreamVolumeForUid(stream, volumeValue, flags,
+ opPackageName, uid);
+ } catch (IllegalArgumentException | SecurityException e) {
+ Log.e(TAG, "Cannot set volume: stream=" + stream + ", value=" + volumeValue
+ + ", flags=" + flags, e);
+ }
+ }
+ });
} else {
if (mVolumeControlType != VolumeProvider.VOLUME_CONTROL_ABSOLUTE) {
// Nothing to do. The volume can't be set directly.
@@ -465,11 +478,19 @@
}
private void postAdjustLocalVolume(final int stream, final int direction, final int flags,
- final String callingPackageName, final int callingUid, final boolean asSystemService,
- final boolean useSuggested, final int previousFlagPlaySound) {
- final String packageName = asSystemService
- ? mContext.getOpPackageName() : callingPackageName;
- final int uid = asSystemService ? Process.SYSTEM_UID : callingUid;
+ final String callingOpPackageName, final int callingPid, final int callingUid,
+ final boolean asSystemService, final boolean useSuggested,
+ final int previousFlagPlaySound) {
+ // Must use opPackageName for adjusting volumes with UID.
+ final String opPackageName;
+ final int uid;
+ if (asSystemService) {
+ opPackageName = mContext.getOpPackageName();
+ uid = Process.SYSTEM_UID;
+ } else {
+ opPackageName = callingOpPackageName;
+ uid = callingUid;
+ }
mHandler.post(new Runnable() {
@Override
public void run() {
@@ -477,19 +498,19 @@
if (useSuggested) {
if (AudioSystem.isStreamActive(stream, 0)) {
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(stream,
- direction, flags, packageName, uid);
+ direction, flags, opPackageName, uid);
} else {
mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(
AudioManager.USE_DEFAULT_STREAM_TYPE, direction,
- flags | previousFlagPlaySound, packageName, uid);
+ flags | previousFlagPlaySound, opPackageName, uid);
}
} else {
mAudioManagerInternal.adjustStreamVolumeForUid(stream, direction, flags,
- packageName, uid);
+ opPackageName, uid);
}
} catch (IllegalArgumentException | SecurityException e) {
Log.e(TAG, "Cannot adjust volume: direction=" + direction + ", stream="
- + stream + ", flags=" + flags + ", packageName=" + packageName
+ + stream + ", flags=" + flags + ", opPackageName=" + opPackageName
+ ", uid=" + uid + ", useSuggested=" + useSuggested
+ ", previousFlagPlaySound=" + previousFlagPlaySound, e);
}
@@ -1256,27 +1277,28 @@
}
@Override
- public void adjustVolume(String packageName, ControllerCallbackLink caller,
- boolean asSystemService, int direction, int flags) {
+ public void adjustVolume(String packageName, String opPackageName,
+ ControllerCallbackLink caller, boolean asSystemService, int direction, int flags) {
int pid = Binder.getCallingPid();
int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
- MediaSessionRecord.this.adjustVolume(packageName, pid, uid, caller, asSystemService,
- direction, flags, false /* useSuggested */);
+ MediaSessionRecord.this.adjustVolume(packageName, opPackageName, pid, uid, caller,
+ asSystemService, direction, flags, false /* useSuggested */);
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override
- public void setVolumeTo(String packageName, ControllerCallbackLink caller,
- int value, int flags) {
+ public void setVolumeTo(String packageName, String opPackageName,
+ ControllerCallbackLink caller, int value, int flags) {
int pid = Binder.getCallingPid();
int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
- MediaSessionRecord.this.setVolumeTo(packageName, pid, uid, caller, value, flags);
+ MediaSessionRecord.this.setVolumeTo(packageName, opPackageName, pid, uid, caller,
+ value, flags);
} finally {
Binder.restoreCallingIdentity(token);
}
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index b807c47..7dbabda 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -35,6 +35,7 @@
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.media.AudioManager;
+import android.media.AudioManagerInternal;
import android.media.AudioPlaybackConfiguration;
import android.media.AudioSystem;
import android.media.IAudioService;
@@ -72,6 +73,7 @@
import android.view.ViewConfiguration;
import com.android.internal.util.DumpUtils;
+import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.Watchdog;
import com.android.server.Watchdog.Monitor;
@@ -108,6 +110,8 @@
private KeyguardManager mKeyguardManager;
private IAudioService mAudioService;
+ private AudioManagerInternal mAudioManagerInternal;
+ private ActivityManager mActivityManager;
private ContentResolver mContentResolver;
private SettingsObserver mSettingsObserver;
private boolean mHasFeatureLeanback;
@@ -139,6 +143,9 @@
mKeyguardManager =
(KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
mAudioService = getAudioService();
+ mAudioManagerInternal = LocalServices.getService(AudioManagerInternal.class);
+ mActivityManager =
+ (ActivityManager) getContext().getSystemService(Context.ACTIVITY_SERVICE);
mAudioPlayerStateMonitor = AudioPlayerStateMonitor.getInstance();
mAudioPlayerStateMonitor.registerListener(
(config, isRemoved) -> {
@@ -1202,7 +1209,8 @@
* there's no active global priority session, long-pressess will be sent to the
* long-press listener instead of adjusting volume.
*
- * @param packageName The caller package.
+ * @param packageName The caller's package name, obtained by Context#getPackageName()
+ * @param opPackageName The caller's op package name, obtained by Context#getOpPackageName()
* @param asSystemService {@code true} if the event sent to the session as if it was come
* from the system service instead of the app process. This helps sessions to
* distinguish between the key injection by the app and key events from the
@@ -1217,8 +1225,8 @@
* @param musicOnly true if both UI nor haptic feedback aren't needed when adjust volume.
*/
@Override
- public void dispatchVolumeKeyEvent(String packageName, boolean asSystemService,
- KeyEvent keyEvent, int stream, boolean musicOnly) {
+ public void dispatchVolumeKeyEvent(String packageName, String opPackageName,
+ boolean asSystemService, KeyEvent keyEvent, int stream, boolean musicOnly) {
if (keyEvent == null ||
(keyEvent.getKeyCode() != KeyEvent.KEYCODE_VOLUME_UP
&& keyEvent.getKeyCode() != KeyEvent.KEYCODE_VOLUME_DOWN
@@ -1240,8 +1248,8 @@
synchronized (mLock) {
if (isGlobalPriorityActiveLocked()
|| mCurrentFullUserRecord.mOnVolumeKeyLongPressListener == null) {
- dispatchVolumeKeyEventLocked(packageName, pid, uid, asSystemService,
- keyEvent, stream, musicOnly);
+ dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid,
+ asSystemService, keyEvent, stream, musicOnly);
} else {
// TODO: Consider the case when both volume up and down keys are pressed
// at the same time.
@@ -1274,12 +1282,13 @@
&& mCurrentFullUserRecord.mInitialDownVolumeKeyEvent
.getDownTime() == keyEvent.getDownTime()) {
// Short-press. Should change volume.
- dispatchVolumeKeyEventLocked(packageName, pid, uid, asSystemService,
+ dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid,
+ asSystemService,
mCurrentFullUserRecord.mInitialDownVolumeKeyEvent,
mCurrentFullUserRecord.mInitialDownVolumeStream,
mCurrentFullUserRecord.mInitialDownMusicOnly);
- dispatchVolumeKeyEventLocked(packageName, pid, uid, asSystemService,
- keyEvent, stream, musicOnly);
+ dispatchVolumeKeyEventLocked(packageName, opPackageName, pid, uid,
+ asSystemService, keyEvent, stream, musicOnly);
} else {
dispatchVolumeKeyLongPressLocked(keyEvent);
}
@@ -1291,8 +1300,9 @@
}
}
- private void dispatchVolumeKeyEventLocked(String packageName, int pid, int uid,
- boolean asSystemService, KeyEvent keyEvent, int stream, boolean musicOnly) {
+ private void dispatchVolumeKeyEventLocked(String packageName, String opPackageName, int pid,
+ int uid, boolean asSystemService, KeyEvent keyEvent, int stream,
+ boolean musicOnly) {
boolean down = keyEvent.getAction() == KeyEvent.ACTION_DOWN;
boolean up = keyEvent.getAction() == KeyEvent.ACTION_UP;
int direction = 0;
@@ -1326,26 +1336,26 @@
if (up) {
direction = 0;
}
- dispatchAdjustVolumeLocked(packageName, pid, uid, asSystemService, stream,
- direction, flags);
+ dispatchAdjustVolumeLocked(packageName, opPackageName, pid, uid,
+ asSystemService, stream, direction, flags);
} else if (isMute) {
if (down && keyEvent.getRepeatCount() == 0) {
- dispatchAdjustVolumeLocked(packageName, pid, uid, asSystemService, stream,
- AudioManager.ADJUST_TOGGLE_MUTE, flags);
+ dispatchAdjustVolumeLocked(packageName, opPackageName, pid, uid,
+ asSystemService, stream, AudioManager.ADJUST_TOGGLE_MUTE, flags);
}
}
}
}
@Override
- public void dispatchAdjustVolume(String packageName, int suggestedStream, int delta,
- int flags) {
+ public void dispatchAdjustVolume(String packageName, String opPackageName,
+ int suggestedStream, int delta, int flags) {
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- dispatchAdjustVolumeLocked(packageName, pid, uid, false,
+ dispatchAdjustVolumeLocked(packageName, opPackageName, pid, uid, false,
suggestedStream, delta, flags);
}
} finally {
@@ -1409,24 +1419,14 @@
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
- int controllerUserId = UserHandle.getUserId(controllerUid);
- int controllerUidFromPackageName;
- try {
- controllerUidFromPackageName = getContext().getPackageManager()
- .getPackageUidAsUser(controllerPackageName, controllerUserId);
- } catch (NameNotFoundException e) {
- if (DEBUG) {
- Log.d(TAG, "Package " + controllerPackageName + " doesn't exist");
- }
- return false;
- }
- if (controllerUidFromPackageName != controllerUid) {
- if (DEBUG) {
- Log.d(TAG, "Package name " + controllerPackageName
- + " doesn't match with the uid " + controllerUid);
- }
- return false;
- }
+ // Don't perform sanity check between controllerPackageName and controllerUid.
+ // When an (activity|service) runs on the another apps process by specifying
+ // android:process in the AndroidManifest.xml, then PID and UID would have the
+ // running process' information instead of the (activity|service) that has created
+ // MediaController.
+ // Note that we can use Context#getOpPackageName() instead of
+ // Context#getPackageName() for getting package name that matches with the PID/UID,
+ // but it doesn't tell which package has created the MediaController, so useless.
return hasMediaControlPermission(UserHandle.getUserId(uid), controllerPackageName,
controllerPid, controllerUid);
} finally {
@@ -1497,8 +1497,8 @@
return false;
}
- private void dispatchAdjustVolumeLocked(String packageName, int pid, int uid,
- boolean asSystemService, int suggestedStream, int direction, int flags) {
+ private void dispatchAdjustVolumeLocked(String packageName, String opPackageName, int pid,
+ int uid, boolean asSystemService, int suggestedStream, int direction, int flags) {
MediaSessionRecord session = isGlobalPriorityActiveLocked() ? mGlobalPrioritySession
: mCurrentFullUserRecord.mPriorityStack.getDefaultVolumeSession();
@@ -1529,21 +1529,28 @@
mHandler.post(new Runnable() {
@Override
public void run() {
+ final String callingOpPackageName;
+ final int callingUid;
+ if (asSystemService) {
+ callingOpPackageName = getContext().getOpPackageName();
+ callingUid = Process.myUid();
+ } else {
+ callingOpPackageName = opPackageName;
+ callingUid = uid;
+ }
try {
- String packageName = getContext().getOpPackageName();
- mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream,
- flags, packageName, TAG);
- } catch (RemoteException|SecurityException e) {
- Log.e(TAG, "Error adjusting default volume.", e);
- } catch (IllegalArgumentException e) {
+ mAudioManagerInternal.adjustSuggestedStreamVolumeForUid(suggestedStream,
+ direction, flags, callingOpPackageName, callingUid);
+ } catch (SecurityException | IllegalArgumentException e) {
Log.e(TAG, "Cannot adjust volume: direction=" + direction
- + ", suggestedStream=" + suggestedStream + ", flags=" + flags,
- e);
+ + ", suggestedStream=" + suggestedStream + ", flags=" + flags
+ + ", packageName=" + packageName + ", uid=" + uid
+ + ", asSystemService=" + asSystemService, e);
}
}
});
} else {
- session.adjustVolume(packageName, pid, uid, null, asSystemService,
+ session.adjustVolume(packageName, opPackageName, pid, uid, null, asSystemService,
direction, flags, true);
}
}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 6187583..88d73fb 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -558,7 +558,7 @@
if (pkgList != null && (pkgList.length > 0)) {
boolean anyServicesInvolved = false;
// Remove notification settings for uninstalled package
- if (removingPackage) {
+ if (removingPackage && uidList != null) {
int size = Math.min(pkgList.length, uidList.length);
for (int i = 0; i < size; i++) {
final String pkg = pkgList[i];
@@ -570,9 +570,11 @@
if (mEnabledServicesPackageNames.contains(pkgName)) {
anyServicesInvolved = true;
}
- for (int uid : uidList) {
- if (isPackageAllowed(pkgName, UserHandle.getUserId(uid))) {
- anyServicesInvolved = true;
+ if (uidList != null && uidList.length > 0) {
+ for (int uid : uidList) {
+ if (isPackageAllowed(pkgName, UserHandle.getUserId(uid))) {
+ anyServicesInvolved = true;
+ }
}
}
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index f370edf..c792863 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -844,7 +844,7 @@
}
private void interceptBackKeyDown() {
- MetricsLogger.count(mContext, "key_back_down", 1);
+ mLogger.count("key_back_down", 1);
// Reset back key state for long press
mBackKeyHandled = false;
@@ -858,6 +858,7 @@
// returns true if the key was handled and should not be passed to the user
private boolean interceptBackKeyUp(KeyEvent event) {
+ mLogger.count("key_back_up", 1);
// Cache handled state
boolean handled = mBackKeyHandled;
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a5ceee2..fecc8da 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2506,6 +2506,7 @@
mWmService.mAnimator.removeDisplayLocked(mDisplayId);
mWindowingLayer.release();
mOverlayLayer.release();
+ mInputMonitor.onDisplayRemoved();
} finally {
mDisplayReady = false;
mRemovingDisplay = false;
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index fc1c65c..632db38 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -32,6 +32,7 @@
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.graphics.Rect;
+import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Process;
@@ -45,7 +46,9 @@
import android.view.InputEventReceiver;
import android.view.InputWindowHandle;
import android.view.SurfaceControl;
+import android.view.animation.Animation;
+import com.android.server.AnimationThread;
import com.android.server.policy.WindowManagerPolicy;
import java.io.PrintWriter;
@@ -60,6 +63,7 @@
// When true, need to call updateInputWindowsLw().
private boolean mUpdateInputWindowsNeeded = true;
+ private boolean mUpdateInputWindowsPending;
// Currently focused input window handle.
private InputWindowHandle mFocusedInputWindowHandle;
@@ -70,8 +74,11 @@
new UpdateInputForAllWindowsConsumer();
private final int mDisplayId;
+ private final DisplayContent mDisplayContent;
+ private boolean mDisplayRemoved;
private final SurfaceControl.Transaction mInputTransaction;
+ private final Handler mHandler;
/**
* The set of input consumer added to the window manager by name, which consumes input events
@@ -105,10 +112,64 @@
}
}
+ private final Runnable mUpdateInputWindows = new Runnable() {
+ @Override
+ public void run() {
+ synchronized (mService.mGlobalLock) {
+ mUpdateInputWindowsPending = false;
+ mUpdateInputWindowsNeeded = false;
+
+ if (mDisplayRemoved) {
+ return;
+ }
+
+ // Populate the input window list with information about all of the windows that
+ // could potentially receive input.
+ // As an optimization, we could try to prune the list of windows but this turns
+ // out to be difficult because only the native code knows for sure which window
+ // currently has touch focus.
+
+ // If there's a drag in flight, provide a pseudo-window to catch drag input
+ final boolean inDrag = mService.mDragDropController.dragDropActiveLocked();
+ if (inDrag) {
+ if (DEBUG_DRAG) {
+ Log.d(TAG_WM, "Inserting drag window");
+ }
+ mService.mDragDropController.showInputSurface(mInputTransaction, mDisplayId);
+ } else {
+ mService.mDragDropController.hideInputSurface(mInputTransaction, mDisplayId);
+ }
+
+ final boolean inPositioning =
+ mService.mTaskPositioningController.isPositioningLocked();
+ if (inPositioning) {
+ if (DEBUG_TASK_POSITIONING) {
+ Log.d(TAG_WM, "Inserting window handle for repositioning");
+ }
+ mService.mTaskPositioningController.showInputSurface(mInputTransaction,
+ mDisplayId);
+ } else {
+ mService.mTaskPositioningController.hideInputSurface(mInputTransaction,
+ mDisplayId);
+ }
+
+ // Add all windows on the default display.
+ mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag);
+ }
+ }
+ };
+
public InputMonitor(WindowManagerService service, int displayId) {
mService = service;
+ mDisplayContent = mService.mRoot.getDisplayContent(displayId);
mDisplayId = displayId;
- mInputTransaction = mService.mRoot.getDisplayContent(mDisplayId).getPendingTransaction();
+ mInputTransaction = mDisplayContent.getPendingTransaction();
+ mHandler = AnimationThread.getHandler();
+ }
+
+ void onDisplayRemoved() {
+ mHandler.removeCallbacks(mUpdateInputWindows);
+ mDisplayRemoved = true;
}
private void addInputConsumer(String name, InputConsumerImpl consumer) {
@@ -248,41 +309,18 @@
if (!force && !mUpdateInputWindowsNeeded) {
return;
}
- mUpdateInputWindowsNeeded = false;
+ scheduleUpdateInputWindows();
+ }
- if (false) Slog.d(TAG_WM, ">>>>>> ENTERED updateInputWindowsLw");
-
- // Populate the input window list with information about all of the windows that
- // could potentially receive input.
- // As an optimization, we could try to prune the list of windows but this turns
- // out to be difficult because only the native code knows for sure which window
- // currently has touch focus.
-
- // If there's a drag in flight, provide a pseudo-window to catch drag input
- final boolean inDrag = mService.mDragDropController.dragDropActiveLocked();
- if (inDrag) {
- if (DEBUG_DRAG) {
- Log.d(TAG_WM, "Inserting drag window");
- }
- mService.mDragDropController.showInputSurface(mInputTransaction, mDisplayId);
- } else {
- mService.mDragDropController.hideInputSurface(mInputTransaction, mDisplayId);
+ private void scheduleUpdateInputWindows() {
+ if (mDisplayRemoved) {
+ return;
}
- final boolean inPositioning = mService.mTaskPositioningController.isPositioningLocked();
- if (inPositioning) {
- if (DEBUG_TASK_POSITIONING) {
- Log.d(TAG_WM, "Inserting window handle for repositioning");
- }
- mService.mTaskPositioningController.showInputSurface(mInputTransaction, mDisplayId);
- } else {
- mService.mTaskPositioningController.hideInputSurface(mInputTransaction, mDisplayId);
+ if (!mUpdateInputWindowsPending) {
+ mUpdateInputWindowsPending = true;
+ mHandler.post(mUpdateInputWindows);
}
-
- // Add all windows on the default display.
- mUpdateInputForAllWindowsConsumer.updateInputWindows(inDrag);
-
- if (false) Slog.d(TAG_WM, "<<<<<<< EXITED updateInputWindowsLw");
}
/* Called when the current input focus changes.
@@ -385,19 +423,18 @@
mTmpRect.setEmpty();
mDisableWallpaperTouchEvents = false;
this.inDrag = inDrag;
- final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
- wallpaperController = dc.mWallpaperController;
+ wallpaperController = mDisplayContent.mWallpaperController;
resetInputConsumers(mInputTransaction);
- dc.forAllWindows(this,
+ mDisplayContent.forAllWindows(this,
true /* traverseTopToBottom */);
if (mAddWallpaperInputConsumerHandle) {
wallpaperInputConsumer.show(mInputTransaction, 0);
}
- dc.scheduleAnimation();
+ mDisplayContent.scheduleAnimation();
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
index 659c6e7..8b65e76 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java
@@ -859,6 +859,19 @@
assertTrue(componentsToBind.get(10).contains(ComponentName.unflattenFromString("c/c")));
}
+ @Test
+ public void testOnPackagesChanged_nullValuesPassed_noNullPointers() {
+ for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
+ ManagedServices service = new TestManagedServices(getContext(), mLock, mUserProfiles,
+ mIpm, approvalLevel);
+ // null uid list
+ service.onPackagesChanged(true, new String[]{"this.is.a.package.name"}, null);
+
+ // null package list
+ service.onPackagesChanged(true, null, new int[]{103});
+ }
+ }
+
private void loadXml(ManagedServices service) throws Exception {
final StringBuffer xml = new StringBuffer();
xml.append("<" + service.getConfig().xmlTag + ">\n");