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
This commit is contained in:
@@ -2398,8 +2398,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
* permission to add alert windows that aren't
|
||||
* {@link android.view.WindowManager.LayoutParams#TYPE_APPLICATION_OVERLAY}.
|
||||
*/
|
||||
return (mContext.checkCallingPermission(INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED)
|
||||
? ADD_OKAY : ADD_PERMISSION_DENIED;
|
||||
return (mContext.checkCallingOrSelfPermission(INTERNAL_SYSTEM_WINDOW)
|
||||
== PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
// check if user has enabled this operation. SecurityException will be thrown if this app
|
||||
@@ -2420,8 +2420,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
|
||||
default:
|
||||
// in the default mode, we will make a decision here based on
|
||||
// checkCallingPermission()
|
||||
return (mContext.checkCallingPermission(SYSTEM_ALERT_WINDOW) == PERMISSION_GRANTED)
|
||||
? ADD_OKAY : ADD_PERMISSION_DENIED;
|
||||
return (mContext.checkCallingOrSelfPermission(SYSTEM_ALERT_WINDOW)
|
||||
== PERMISSION_GRANTED) ? ADD_OKAY : ADD_PERMISSION_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.Intent;
|
||||
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 @@ class AlertWindowNotification {
|
||||
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 @@ class AlertWindowNotification {
|
||||
(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 @@ class AlertWindowNotification {
|
||||
.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) {
|
||||
|
||||
@@ -93,7 +93,7 @@ public class Session extends IWindowSession.Stub
|
||||
mUid = Binder.getCallingUid();
|
||||
mPid = Binder.getCallingPid();
|
||||
mLastReportedAnimatorScale = service.getCurrentAnimatorScale();
|
||||
mCanAddInternalSystemWindow = service.mContext.checkCallingPermission(
|
||||
mCanAddInternalSystemWindow = service.mContext.checkCallingOrSelfPermission(
|
||||
INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Session{");
|
||||
@@ -664,6 +664,7 @@ public class Session extends IWindowSession.Stub
|
||||
|
||||
void dump(PrintWriter pw, String prefix) {
|
||||
pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
|
||||
pw.print(" mCanAddInternalSystemWindow="); pw.print(mCanAddInternalSystemWindow);
|
||||
pw.print(" mAppOverlaySurfaces="); pw.print(mAppOverlaySurfaces);
|
||||
pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces);
|
||||
pw.print(" mClientDead="); pw.print(mClientDead);
|
||||
|
||||
Reference in New Issue
Block a user