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) {