40

I've a strange android permission denial, here is it:

java.lang.SecurityException: Permission Denial: isUserRunning() from pid=1078, uid=10284 requires android.permission.INTERACT_ACROSS_USERS

I haven't found anything about android.permission.INTERACT_ACROSS_USERS only android.permission.INTERACT_ACROSS_USERS_FULL

Here is the full logcat:

java.lang.SecurityException: Permission Denial: isUserRunning() from pid=25403, uid=10310 requires android.permission.INTERACT_ACROSS_USERS
    at android.os.Parcel.readException(Parcel.java:1693)
    at android.os.Parcel.readException(Parcel.java:1646)
    at android.app.ActivityManagerProxy.isUserRunning(ActivityManagerNative.java:7000)
    at android.os.UserManager.isUserUnlocked(UserManager.java:1069)
    at android.os.UserManager.isUserUnlocked(UserManager.java:1063)
    at com.android.launcher3.compat.UserManagerCompatVN.isUserUnlocked(UserManagerCompatVN.java:39)
    at com.android.launcher3.LauncherModel$LoaderTask.loadWorkspace(LauncherModel.java:1759)
    at com.android.launcher3.LauncherModel$LoaderTask.loadAndBindWorkspace(LauncherModel.java:1387)
    at com.android.launcher3.LauncherModel$LoaderTask.run(LauncherModel.java:1486)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.os.HandlerThread.run(HandlerThread.java:61)

I've added this to my manifest:

<permission android:name="android.permission.INTERACT_ACROSS_USERS" android:protectionLevel="signature"/>
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/>
Michele Lacorte
  • 5,323
  • 7
  • 32
  • 54
  • Possible duplicate of [Android permission.INTERACT\_ACROSS\_USERS\_FULL](http://stackoverflow.com/questions/28134128/android-permission-interact-across-users-full) – cammando Apr 22 '17 at 08:17
  • Unless you are working on some fork of `com.android.launcher3`, that Java stack trace does not appear to be coming from your app. – CommonsWare May 15 '17 at 14:27
  • So @CommonsWare what I can do? – Michele Lacorte May 19 '17 at 07:14
  • You could start by explaining what that stack trace has to do with your app. – CommonsWare May 19 '17 at 10:41
  • When you open your manifest in Android Studio, you should see a "merged manifest" button. You will see a lot of different colors. Find the permission that declares INTERACT_ACROSS_USERS and find out what manifest it comes from. Meaning if you use a library, where does it come from? – Zoe May 21 '17 at 11:13
  • https://stackoverflow.com/questions/28134128/android-permission-interact-across-users-full/45057190#45057190 – varotariya vajsi Jul 12 '17 at 12:06
  • did you find answers for it? – Janardhan R May 20 '20 at 06:45

2 Answers2

5

TL;DR; Either this stack trace does not belong to your application or you need a permission that you don't have. To know about those permissions read the rest.

Although Michele probably has found the answer, I've decided to answer this question as it might be useful for others. Mentioned permissions are signature|system level permissions. To read more about different types of permissions read this: Permissions overview

Basically these permissions are needed to use multi-user APIs such as:

Context.startActivityAsUser(Intent, UserHandle)
Context.bindServiceAsUser(Intent, …, UserHandle)
Context.sendBroadcastAsUser(Intent, … , UserHandle)
Context.startServiceAsUser(Intent, …, UserHandle)

To know more, read this: Supporting Multiple Users and this: Building Multiuser-Aware Apps

Due to the error, Michele has come to this conclusion that he has to add these permissions to manifest (which we will see how it is possible for an application to have these permissions granted), but instead, he has defined these permissions(to know more about defining a permission read this: Define a Custom App Permission):

<permission android:name="android.permission.INTERACT_ACROSS_USERS" android:protectionLevel="signature"/>
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/>

I think you will end up seeing a run time error because you can't define these permissions since they have the same name as two system permission that are already defined. Want to be sure? Take a look at a part of a real system manifest:

<!-- @SystemApi @hide Allows an application to call APIs that allow it to do interactions
     across the users on the device, using singleton services and
     user-targeted broadcasts.  This permission is not available to
     third party applications. -->
<permission android:name="android.permission.INTERACT_ACROSS_USERS"
    android:protectionLevel="signature|system|privileged" />

<!-- @hide Fuller form of {@link android.Manifest.permission#INTERACT_ACROSS_USERS}
     that removes restrictions on where broadcasts can be sent and allows other
     types of interactions. -->
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
    android:protectionLevel="signature" />

You see in this manifest file of an android system, these permissions are defined already and to use them we should use the tag.

So now lets talk how theses permissions might be granted to your application. In my experience OEMs define system manifest in a way that these permissions could be granted to

  1. Apps which have the same signature as the system(practically only apps which are developed by the OEM)

  2. Privileged apps being under the /system/priv-app.

In the system manifest I mentioned above the second permission is only defined as signature so only apps with the same signature as system can have those permissions granted.

If you have write access on a device (probably it should be rooted, I don't know much about that), you can copy your apk in the priv-app folder by this command:

adb push path-to-your-app/your-app.apk /system/priv-app

Is that all? Not yet!

Since android 8.0 there are some complications about permissions being granted to applications under priv-app that you can read about it here: Privileged Permission Whitelisting

Sina
  • 2,683
  • 1
  • 13
  • 25
-8

You should implement permission request at run-time in Android, specifically for Marshmallow or higher version. If you don’t implement run-time permission, then your application will crash or will not work properly on the device having Marshmallow.

I hope you are now pretty much aware with Runtime Permission concept in Marshmallow. Let’s understand this code:

int currentAPIVersion = Build.VERSION.SDK_INT;
if(currentAPIVersion>=android.os.Build.VERSION_CODES.M)
 {
    if (ContextCompat.checkSelfPermission(context, Manifest.permission.INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
        if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.INTERACT_ACROSS_USERS)) {
            AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
            alertBuilder.setCancelable(true);
            alertBuilder.setTitle("Permission necessary");
            alertBuilder.setMessage("Interact across users permission is necessary to this app");
            alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.INTERACT_ACROSS_USERS}, MY_PERMISSIONS_REQUEST_INTERACT_ACROSS_USERS);
                }
            });
            AlertDialog alert = alertBuilder.create();
            alert.show();
        } else {
            ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.INTERACT_ACROSS_USERS}, MY_PERMISSIONS_REQUEST_INTERACT_ACROSS_USERS);
        }
    }
}


 @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
 case MY_PERMISSIONS_REQUEST_INTERACT_ACROSS_USERS:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               // do something here...
               Toast.makeText(getApplicationContext(), "Permission granted", Toast.LENGTH_SHORT).show();
        } else {
         //code for deny
         Toast.makeText(getApplicationContext(), "Permission denied", Toast.LENGTH_SHORT).show();

}
         break;
    }
}