permissions-dispatcher / PermissionsDispatcher

A declarative API to handle Android runtime permissions.
https://github.com/permissions-dispatcher/PermissionsDispatcher
Apache License 2.0
11.22k stars 1.44k forks source link

Check permissions on xiaomi device with a version below api 23 #386

Closed sdroider closed 6 years ago

sdroider commented 7 years ago

As you know, Xiaomi devices have their own system of permissions. I'm testing my application on the device xiaomi redmi 3, api 22, android 5.1.1. I want to check if there is permission to access the camera and audio. boolean b = hasSelfPermissionForXiaomi(getActivity(),"android.permission.CAMERA");} `

private boolean hasSelfPermissionForXiaomi(Context context,String permission){
String permissionTop = AppOpsManagerCompat.permissionToOp(permission);
if(permissionTop == null){
    // not dangerous
    return true;
}
int noteOp = AppOpsManagerCompat.noteOp(context,permissionTop, Process.myUid(),context.getPackageName());
return noteOp == AppOpsManagerCompat.MODE_ALLOWED && checkSelfPermission(context,permission) == PackageManager.PERMISSION_GRANTED;}`

b = true, although this is not true.

hotchemi commented 7 years ago

@SergeyAppDroid thx. Do you mean current hasSelfPermissionForXiaomi has a bug?

sdroider commented 7 years ago

@hotchemi On the xiaomi device Redmi 3 API22, this method does not work correctly. When I send the value "android.permission.CAMERA" to the method, the permissionTop variable is null. Although permission to use the camera was not provided.

hotchemi commented 7 years ago

Umm...currently, we check Build.VERSION.SDK_INT >= 23 before calling hasSelfPermissionForXiaomi so if the device API level is below 23 the method never be called. Do you know why the method was called?

https://github.com/permissions-dispatcher/PermissionsDispatcher/blob/master/library/src/main/android/permissions/dispatcher/PermissionUtils.java#L99

sdroider commented 7 years ago

@hotchemi I called this method forcibly using the source code. Because my device has api22, but it also requires permission. How to deal with such devices?

shiraji commented 7 years ago

Are you asking the general question how to handle the permission in API 22 and above?

sdroider commented 7 years ago

@shiraji I'm asking why your library does not work with permissions on xiaomi devices with versions below 23.

shiraji commented 7 years ago

Then, why don't you answer what @hotchemi asked?

Do you know why the method was called?

You can put the break point https://github.com/permissions-dispatcher/PermissionsDispatcher/blob/master/library/src/main/android/permissions/dispatcher/PermissionUtils.java#L99 and see what value Build.VERSION.SDK_INT has.

I want to see how do you use our library. Could you give us the sample project that reproduces this problem?

sdroider commented 7 years ago

@shiraji I used the source code of the method hasSelfPermissionForXiaomi without checking for the version API using. You declare that the library supports xiaomi devices. But it only supports xiaomi devices with versions higher than 23. I want to know if you will upgrade the library so that it supports xiaomi devices with versions below 23?

P.S. There is no bug in your library. It's just not suitable for my device. How can I be with devices below version API23 ?

shiraji commented 7 years ago

If you set targetSdkVersion >= 23 and go thou README, then this library take care below 23 😉 Because https://github.com/permissions-dispatcher/PermissionsDispatcher/blob/master/library/src/main/android/permissions/dispatcher/PermissionUtils.java#L103 this would be true if the device is below 23. You don't need to have any special treatment for handling blow 23

sdroider commented 7 years ago

@shiraji You do not understand me. Xiaomi devices have a permission system, even on versions BELOW 23 API. I have xiaomi redmi 3, api 22. When the application uses the camera, a pop-up message appears informing you that you need to grant permission! you understand?

shiraji commented 7 years ago

So, why don't you give us the documentation that describe Xiaomi device blow 23 requires Runtime Permissions and how to handle it.

sdroider commented 7 years ago

Unfortunately, I have not yet figured out how to solve this problem, so I wrote to you about it.

shiraji commented 7 years ago

Well, then we cannot help you because none of maintainers have the Xiaomi devices.

By the way, are you really sure that API 22 device requires Runtime Permission?

sdroider commented 7 years ago

@shiraji Oh sure! screenshot_2017-09-18-19-56-12_com android settings screenshot_2017-09-18-19-55-37_com miui home

sdroider commented 7 years ago

screenshot_2017-09-18-20-01-00_com android settings screenshot_2017-09-18-20-01-58_com miui home

hotchemi commented 7 years ago

@SergeyAppDroid so then, could you try without our library and share the result of code that can deal with below 23 case thingy? If that sort of workaround can be integrated to our library I'd like to consider about it.

We have been trying to support Xiaomi as much as we can but none of us have enough amount of Xiaomi devices and this case hasn't been filed before so we're kind of stuck what to do to cope with the problem.

@shiraji Thx!

shiraji commented 7 years ago

Can developer control this popup? or getting the result of this popup? I suspect the OS imitates Runtime Permission in API 22 which has no control for developers.

Anyway, you need to give us information how to handle this case otherwise we cannot help you. Why don't you ask redmi official?

sdroider commented 7 years ago

@hotchemi I will continue to work in this direction! If I manage to solve the problem of these devices, I will inform you!

sdroider commented 7 years ago

@shiraji Until I found a way to manage the pop-up window. To date, for such devices, I open the activity on which the management of permissions is melting. I do not see other ways. Official xiaomi forums do not give the right answer

hotchemi commented 7 years ago

@SergeyAppDroid Thank you(Btw I didn't know Xiaomi is popular in Russia OMG) 🙇

sdroider commented 7 years ago

@hotchemi now in Russia, Chinese brands are very popular: huawei, xiaomi, meizu. But these devices with their own implementations of firmware. Therefore, developing applications for them is very unusual :)

hotchemi commented 7 years ago

Any update for this issue?

bappleug commented 7 years ago

I think the present implementation has no problem.

There are several Chinese brands mentioned above who customize their own permission control system before Google did(Base on AppOps as I know). Under SDK 23, it is controlled by their own logic such as popup dialog. The only thing we can do is to catch exceptions to avoid crash and show some hint if we need.

The real issue should be after SDK 23, as they put their permission control system above the new introduced one. When we check for permissions we have to check both systems(like what you did for xiaomi). And if we want to guide to user to open permissions manually when it is denied forever, usually we need to guide them to the customized control page(which needs adaptation for all brands).

sdroider commented 7 years ago

Hello! To solve this non-standard problem, I had to create methods for checking each permission from the list of required ones. I needed to check permissions for camera and sound recording: <uses-permission android: name = "android.permission.CAMERA" and <uses-permission android: name = "android.permission.RECORD_AUDIO". This method is not trivial and I do not recommend it to be used constantly, but this is the only thing I could think of:

public boolean hasSelfCameraPermissionForXiaomiLollipop(){

        boolean result = false;
        Camera camera = null;
        try {
            camera = Camera.open(0);
            result = true;
        }
        catch (RuntimeException e){
            Log.d(LOG_TAG,"Xiaomi lollipop not granted camera permission");
            result = false;
        }
        finally {
            if(camera!= null){
                camera.release();
            }
        }
        return result;
    }
brandall76 commented 6 years ago

I'm wondering if my query is related to this topic.

Android studio (lint) is highlighting this and informing me that:

    String permissionToOp = AppOpsManagerCompat.permissionToOp(permission);
    if (permissionToOp == null) {
        // in case of normal permissions(e.g. INTERNET)
        return true;
    }

Value 'permissionToOp' will always be null.

I'm puzzled by this, as checking AppOpsManagerCompat.permissionToOp(permission)

/**
 * Gets the app op name associated with a given permission.
 *
 * @param permission The permission.
 * @return The app op associated with the permission or null.
 */
@Nullable
public static String permissionToOp(@NonNull String permission) {
    if (SDK_INT >= 23) {
        return AppOpsManager.permissionToOp(permission);
    } else {
        return null;
    }
}

And checking AppOpsManager.permissionToOp(permission)

/**
 * Gets the app op name associated with a given permission.
 * The app op name is one of the public constants defined
 * in this class such as {@link #OPSTR_COARSE_LOCATION}.
 * This API is intended to be used for mapping runtime
 * permissions to the corresponding app op.
 *
 * @param permission The permission.
 * @return The app op associated with the permission or null.
 */
public static String permissionToOp(String permission) {
    final Integer opCode = sPermToOp.get(permission);
    if (opCode == null) {
        return null;
    }
    return sOpToString[opCode];
}

It would seem feasible that opCode would not always be null, but Android Studio (lint) disagrees.

Can anyone confirming this behaviour?

My concern is of course, that if it is correct, it will always return true for Xiaomi devices.

mainaviTech commented 6 years ago

@brandall76 yes that's true. I am facing the same issue for service sms read permission. AppOpsManager.MODE_ALLOWED is always returning 0 whether the user has accepted or denied to give the permission. Even I tried with startActivityForResult() and onActivityResult(), the resultCode is always been 0 for both the options i.e. accept or deny. It would be a great help if someone can help me on this.

hotchemi commented 6 years ago

it's been a long time.. 🙍

So long story short we have not supported Xiaomi devices up to API level 22 and the only way to cope with the problem is this. I suppose supporting the corner case like this is not a responsibility of a library so let us note we (try to) support Xiaomi which is over 23 👋

Please correct us if something is wrong since we're not Xiaomi expert.. 😇