I'm trying to active the device owner of my system application using hidden API from DevicePolicyManager
method dpm.setDeviceOwner(cmpName)
. This method is throwing illegalStateException. I also tried Settings.Global.putInt(context.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0);
and Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0);
. But android studio is still throwing an error.
Note : I have both permission in manifest <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
and <uses-permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS" />
I received that error when calling dpm.setProfileOwner
before dpm.setActiveAdmin
; after all, a profile owner must first be an active admin. However, you'll quickly find that, even if you issue the appropriate sequence of commands you'll then receive the error: java.lang.IllegalStateException: Unable to set non-default profile owner post-setup
.
If you check your logcat, though, I suspect you'll also find a warning similar to one I received: avc: denied { write } for name="com.myorg.mapp-0AMhJFjDAJrJ-KmxrLiEPA==" dev="dm-3" ino=3558 scontext=u:r:system_app:s0 tcontext=u:object_r:apk_data_file:s0 tclass=dir permissive=0
This message is the key... The problem is that selinux rules prevent the apk from making changes directly to the /data/system directory, which is where the xml files (device_owner_2.xml and device_policies.xml) that define profile ownership are located.
In short, you're out of luck. You have a few workaround options:
dpm set-profile-owner
command from within a rooted shell. Since it is run as root this will bypass selinux rules. This is a great option for quick testsIf you're building a system app (which you must be with those permissions), you're almost certainly rooted or building a ROM, so one of the above options should work.
I've encountered a very similar problem using Android Q. I know it's been answered already, but I found another thing that I did that worked, based on DPM implementation in this link . I implemented a platform priv-app with this method:
private void setDeviceOwnerAndAdmin() {
int mUserId = UserHandle.USER_SYSTEM;
try {
//Get the Stub implementation for device policy service
IDevicePolicyManager mDevicePolicyManager = IDevicePolicyManager.Stub.asInterface(
ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
//Get the admin component from DeviceAdmin class
ComponentName component = new ComponentName(mContext, DeviceAdmin.class);
//Set active system admin
mDevicePolicyManager.setActiveAdmin(component, true /*refreshing*/, mUserId);
//Set the device owner for this component
if (!mDevicePolicyManager.setDeviceOwner(component, "OwnerName", mUserId)) {
throw new RuntimeException(
"Can't set package " + component + " as device owner.");
}
//Set provisioning state
mDevicePolicyManager.setUserProvisioningState(
DevicePolicyManager.STATE_USER_SETUP_FINALIZED, mUserId);
} catch (Exception e) {
Log.e(TAG, "Error at setting Owner and Admin", e);
}
}
Then the exception occured with the message
Cannot set the device owner if the device is already set-up
I then added <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
and <uses-permission android:name="android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS" />
to the Manifest.
Also, added the priv-app package to /frameworks/base/data/etc/privapp-permissions-platform.xml
with the right permissions.
After all that, I still had the same exception message, until I figured out that the frameworks/base/packages/SettingsProvider/res/values/defaults.xml
had the value <bool name="def_user_setup_complete">true</bool>
. That was preventing me from adding a device owner, so I changed this value to false
and it worked.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.