Why NotificationManagerCompat::cancelAll() gets SecurityException?
Asked Answered
P

2

28

Using NotificationManagerCompat to cancel all notification.

NotificationManagerCompat manager =  
    NotificationManagerCompat.from(ctx.getApplicationContext());
manager.cancelAll();

It got exception some time (most time works).

on Andoid 6:

java.lang.SecurityException: Permission Denial: getCurrentUser() from pid=22994, uid=10184 requires android.permission.INTERACT_ACROSS_USERS

Fatal Exception: java.lang.SecurityException: Permission Denial: getCurrentUser() from pid=22994, uid=10184 requires android.permission.INTERACT_ACROSS_USERS
   at android.os.Parcel.readException(Parcel.java:1602)
   at android.os.Parcel.readException(Parcel.java:1555)
   at android.app.INotificationManager$Stub$Proxy.cancelAllNotifications(INotificationManager.java:649)
   at android.app.NotificationManager.cancelAll(NotificationManager.java:323)
   at android.support.v4.app.NotificationManagerCompat.cancelAll(NotificationManagerCompat.java:197)

on Android 5.0, 4.4.2:

ava.lang.SecurityException: Permission Denial: getIntentSender() from pid=5460, uid=10135, (need uid=1000) is not allowed to send as package android at android.os.Parcel.readException(Parcel.java:1465)

Fatal Exception: java.lang.SecurityException: Permission Denial: getIntentSender() from pid=3109, uid=10153, (need uid=1000) is not allowed to send as package android
   at android.os.Parcel.readException(Parcel.java:1472)
   at android.os.Parcel.readException(Parcel.java:1426)
   at android.app.INotificationManager$Stub$Proxy.cancelAllNotifications(INotificationManager.java:271)
   at android.app.NotificationManager.cancelAll(NotificationManager.java:220)
   at android.support.v4.app.NotificationManagerCompat.cancelAll(NotificationManagerCompat.java:197)

Questions:

  1. What could be the cause?
  2. What are those id here? Is it ctx.getApplicationContext().getApplicationInfo().uid or android.os.Process.myUid()?
Patency answered 14/4, 2016 at 21:6 Comment(17)
"is it ctx.getApplicationContext().getApplicationInfo().uid or android.os.Process.myUid()?" -- for most Android apps, those should be the same. Both of your errors are rather strange, though.Tullius
Thanks CommonsWare! It is strange, it just uses the app's context to removeAll notifications (posted from inside the same app), but get security exception. What could be the possible cause?Patency
@Patency Irrespective of the exceptions, are your notifications getting cancelled or not ?Chemotaxis
@ShadabAnsari, no.Patency
@Iannyg Did you find out solution?Gytle
Hey @Patency did you found a solution? I got the same problem with my app occasionally throws this exception when notifications are calcelled.Winifred
@ Rybzor, no. seems this question is not popular enough.Patency
So I guess gotta try-catch this cancer.Winifred
code.google.com/p/android/issues/…Piet
@66CLSjY I assume, depending on whether these pid and uid belong to your app OR not, this could be either a bug in "Binder synchronization" when, say, getIntentSender() was called with the uid's Binder identity while it was to be called with the system's one (uid=1000), OR while handling your call other object's Binders are called with the original callers (yours) identity without clearing it first. I guess there isn't much you can do about it but catching exceptions thrown by the problem calls.Dodeca
@Onik, that does shed some light on how this issue is arising. Thanks.Piet
@Dodeca I don't want the bounty to go to waste. Pls summarize your comments as an answer, I will give it to you.Piet
@66CLSjY I spent last weekend trying to figure out a possible cause and got nothing but the assumption which, by me, wasn't worth to post it as answer. So maybe it's fine to "go to waste"??? Sometimes we lose, sometimes we find :)... Yet if you insist, I'll gather all I've found and post the answer in hope it could be a good start for someone else in resolving the issue in future.Dodeca
@Dodeca Pls do. Even though it does not contain a solution, it does offer an insight to the problem and address part one of the question asked by lannyf.Piet
Can you post the manifest file and specify in which component you're trying to cancel the notifications?Illegalize
Can you add your manifest? I think i met this issue before only on Asus phoneFrobisher
According to our Crashlytics reports, it happens only on Android 6.0 on Huawei P8 and Blackview P2. Three users, 10 crashes.Rake
D
6

The answer does not provide a solid solution for the problem, it rather attempts to give an explanation of the cause both for the OP and @66CLSjY, who offered the bounty, with a similar issue.


Inspecting the stacktrace

According to the stacktrace SecurityException is thrown in the remote process: your app process' Binder object (e.g. INotificationManager.Stub, ActivityManagerProxy etc.) makes a Binder transaction (mRemote.transact()) * on the remote Binder object and read from the object an exception (_reply.readException()) occurred within the remote call(s). If any, the exception message is analyzed and a corresponding exception is thrown in your process.

Analyzing the exception message

Both the exception messages (one with getIntentSender() and another one with getCurrentUser()) are quite straightforward - your app didn't pass a permission check, or in other words, the code snippets of ActivityManagerService that were supposed to be called under the system_server process' identity (UID=1000) **, but, in fact, were called under your app process' identity.

Possible cause and workaround

It got exception some time (most time works).

Without making an assumption, what you get "some time" is improper Android behavior. Wrapping the problem call with try/catch seems to be a workaround until someone suggests a solid solution (if exists).


* ActivityManagerProxy.setRequestedOrientation() and IAccessibilityManager$Stub$Proxy.sendAccessibilityEvent()
** android.permission.INTERACT_ACROSS_USERS is of signature | system protection level

Dodeca answered 10/11, 2016 at 23:18 Comment(0)
K
0

To me it sounds like there are two different possibilities why this is not working:

The most likely cause is that you are using the wrong context to make the call; getApplicationContext() is not 100% reliable and sometimes produces strange errors, it is always best to avoid this call. If you are calling cancelAll() from a Service or Activity, use YourClass.this instead of getApplicationContext(), if it is from a BroadcastReceiver, use the supplied Context variable.

If this is still not working, it might be a bug in NotificationManagerCompat, try if you can reproduce the same problem with NotificationManager. A workaround for that would be to save all your Notification ids in a list and then cancel them each with manager.cancel(id). That way the system won't be trying to cancel any Notifications that do not belong to your app.

Kalimantan answered 10/11, 2016 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.