Fixed some issues with alert window notifications
- Don't hold window manager lock while calling into notification
manager since it can end up calling into activity manager.
- Fixed issue with using checkCallingPermission() to check if the
system has the internal system window permission. This call fails
if it isn't a binder call. Change to use checkCallingorSelfPermission()
instead.
- Fixed class cast exception while getting app icon by using
IconUtilities class to the the drawable to bitmap convertion.
Change-Id: I4ef380618f558a8aac5b152d97536a614040397f
Fixes: 35780846
Fixes: 35846667
Fixes: 35854470
Bug: 35657567
Test: cts/hostsidetests/.../run-test CtsWindowManagerHostTestCases android.server.cts.AlertWindowsTests
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
index 0d282ef..b7b419b 100644
--- a/services/core/java/com/android/server/wm/AlertWindowNotification.java
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -16,7 +16,6 @@
package com.android.server.wm;
-import static android.app.Notification.VISIBILITY_PRIVATE;
import static android.app.NotificationManager.IMPORTANCE_MIN;
import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.content.Context.NOTIFICATION_SERVICE;
@@ -34,8 +33,10 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
-import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+
import com.android.internal.R;
+import com.android.server.policy.IconUtilities;
/** Displays an ongoing notification for a process displaying an alert window */
class AlertWindowNotification {
@@ -50,6 +51,7 @@
private final String mPackageName;
private final int mUid;
private boolean mCancelled;
+ private IconUtilities mIconUtilities;
AlertWindowNotification(WindowManagerService service, String packageName, int uid) {
mService = service;
@@ -59,20 +61,33 @@
(NotificationManager) mService.mContext.getSystemService(NOTIFICATION_SERVICE);
mNotificationTag = CHANNEL_PREFIX + mPackageName;
mRequestCode = sNextRequestCode++;
+ mIconUtilities = new IconUtilities(mService.mContext);
// We can't create/post the notification while the window manager lock is held since it will
// end up calling into activity manager. So, we post a message to do it later.
- mService.mH.post(this::postNotification);
+ mService.mH.post(this::onPostNotification);
}
/** Cancels the notification */
void cancel() {
+ // We can't call into NotificationManager with WM lock held since it might call into AM.
+ // So, we post a message to do it later.
+ mService.mH.post(this::onCancelNotification);
+ }
+
+ /** Don't call with the window manager lock held! */
+ private void onCancelNotification() {
mNotificationManager.cancel(mNotificationTag, NOTIFICATION_ID);
mCancelled = true;
}
/** Don't call with the window manager lock held! */
- private void postNotification() {
+ private void onPostNotification() {
+ if (mCancelled) {
+ // Notification was cancelled, so nothing more to do...
+ return;
+ }
+
final Context context = mService.mContext;
final PackageManager pm = context.getPackageManager();
final ApplicationInfo aInfo = getApplicationInfo(pm, mPackageName);
@@ -94,17 +109,14 @@
.addAction(getTurnOffAction(context, mPackageName, mUid));
if (aInfo != null) {
- final Bitmap bitmap = ((BitmapDrawable) pm.getApplicationIcon(aInfo)).getBitmap();
- builder.setLargeIcon(bitmap);
+ final Drawable drawable = pm.getApplicationIcon(aInfo);
+ if (drawable != null) {
+ final Bitmap bitmap = mIconUtilities.createIconBitmap(drawable);
+ builder.setLargeIcon(bitmap);
+ }
}
- synchronized (mService.mWindowMap) {
- if (mCancelled) {
- // Notification was cancelled, so nothing more to do...
- return;
- }
- mNotificationManager.notify(mNotificationTag, NOTIFICATION_ID, builder.build());
- }
+ mNotificationManager.notify(mNotificationTag, NOTIFICATION_ID, builder.build());
}
private Notification.Action getTurnOffAction(Context context, String packageName, int uid) {