Call PROFILE/DEVICE_OWNER_CHANGED broadcast and onTransferCompleted callback upon a successful transfer.
Test: cts-tradefed run cts-dev --module DevicePolicyManager --test com.android.cts.devicepolicy.MixedProfileOwnerHostSideTransferTest#testTransferOwnerChangedBroadcast Test: cts-tradefed run cts-dev --module DevicePolicyManager --test com.android.cts.devicepolicy.MixedProfileOwnerHostSideTransferTest#testTransferCompleteCallback Test: cts-tradefed run cts-dev --module DevicePolicyManager --test com.android.cts.devicepolicy.MixedDeviceOwnerHostSideTransferTest#testTransferOwnerChangedBroadcast Test: cts-tradefed run cts-dev --module DevicePolicyManager --test com.android.cts.devicepolicy.MixedDeviceOwnerHostSideTransferTest#testTransferCompleteCallback Bug: 69542936 Bug: 69543044 Change-Id: Ifbe3ac0029794eba185e538e5a490073d5309f0b
This commit is contained in:
@@ -6297,6 +6297,7 @@ package android.app.admin {
|
||||
method public void onReceive(android.content.Context, android.content.Intent);
|
||||
method public void onSecurityLogsAvailable(android.content.Context, android.content.Intent);
|
||||
method public void onSystemUpdatePending(android.content.Context, android.content.Intent, long);
|
||||
method public void onTransferOwnershipComplete(android.content.Context, android.os.PersistableBundle);
|
||||
method public void onUserAdded(android.content.Context, android.content.Intent, android.os.UserHandle);
|
||||
method public void onUserRemoved(android.content.Context, android.content.Intent, android.os.UserHandle);
|
||||
field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
|
||||
@@ -6314,6 +6315,7 @@ package android.app.admin {
|
||||
field public static final java.lang.String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
|
||||
field public static final java.lang.String EXTRA_DISABLE_WARNING = "android.app.extra.DISABLE_WARNING";
|
||||
field public static final java.lang.String EXTRA_LOCK_TASK_PACKAGE = "android.app.extra.LOCK_TASK_PACKAGE";
|
||||
field public static final java.lang.String EXTRA_TRANSFER_OWNER_ADMIN_EXTRAS_BUNDLE = "android.app.extra.TRANSFER_OWNER_ADMIN_EXTRAS_BUNDLE";
|
||||
}
|
||||
|
||||
public class DeviceAdminService extends android.app.Service {
|
||||
@@ -6506,6 +6508,7 @@ package android.app.admin {
|
||||
method public void setUserIcon(android.content.ComponentName, android.graphics.Bitmap);
|
||||
method public boolean stopUser(android.content.ComponentName, android.os.UserHandle);
|
||||
method public boolean switchUser(android.content.ComponentName, android.os.UserHandle);
|
||||
method public void transferOwnership(android.content.ComponentName, android.content.ComponentName, android.os.PersistableBundle);
|
||||
method public void uninstallAllUserCaCerts(android.content.ComponentName);
|
||||
method public void uninstallCaCert(android.content.ComponentName, byte[]);
|
||||
method public void wipeData(int);
|
||||
@@ -6515,6 +6518,7 @@ package android.app.admin {
|
||||
field public static final java.lang.String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
|
||||
field public static final java.lang.String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
|
||||
field public static final java.lang.String ACTION_MANAGED_PROFILE_PROVISIONED = "android.app.action.MANAGED_PROFILE_PROVISIONED";
|
||||
field public static final java.lang.String ACTION_PROFILE_OWNER_CHANGED = "android.app.action.PROFILE_OWNER_CHANGED";
|
||||
field public static final java.lang.String ACTION_PROVISIONING_SUCCESSFUL = "android.app.action.PROVISIONING_SUCCESSFUL";
|
||||
field public static final java.lang.String ACTION_PROVISION_MANAGED_DEVICE = "android.app.action.PROVISION_MANAGED_DEVICE";
|
||||
field public static final java.lang.String ACTION_PROVISION_MANAGED_PROFILE = "android.app.action.PROVISION_MANAGED_PROFILE";
|
||||
|
||||
@@ -29,10 +29,14 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.Process;
|
||||
import android.os.UserHandle;
|
||||
import android.security.KeyChain;
|
||||
|
||||
import libcore.util.NonNull;
|
||||
import libcore.util.Nullable;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
@@ -438,6 +442,31 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
|
||||
// TO DO: describe syntax.
|
||||
public static final String DEVICE_ADMIN_META_DATA = "android.app.device_admin";
|
||||
|
||||
/**
|
||||
* Broadcast action: notify the newly transferred administrator that the transfer
|
||||
* from the original administrator was successful.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_TRANSFER_OWNERSHIP_COMPLETE =
|
||||
"android.app.action.TRANSFER_OWNERSHIP_COMPLETE";
|
||||
|
||||
/**
|
||||
* A {@link android.os.Parcelable} extra of type {@link android.os.PersistableBundle} that
|
||||
* allows a mobile device management application to pass data to the management application
|
||||
* instance after owner transfer.
|
||||
*
|
||||
* <p>
|
||||
* If the transfer is successful, the new device owner receives the data in
|
||||
* {@link DeviceAdminReceiver#onTransferOwnershipComplete(Context, PersistableBundle)}.
|
||||
* The bundle is not changed during the ownership transfer.
|
||||
*
|
||||
* @see DevicePolicyManager#transferOwnership(ComponentName, ComponentName, PersistableBundle)
|
||||
*/
|
||||
public static final String EXTRA_TRANSFER_OWNER_ADMIN_EXTRAS_BUNDLE =
|
||||
"android.app.extra.TRANSFER_OWNER_ADMIN_EXTRAS_BUNDLE";
|
||||
|
||||
private DevicePolicyManager mManager;
|
||||
private ComponentName mWho;
|
||||
|
||||
@@ -859,6 +888,20 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
|
||||
public void onUserRemoved(Context context, Intent intent, UserHandle removedUser) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on the newly assigned owner (either device owner or profile owner) when the ownership
|
||||
* transfer has completed successfully.
|
||||
*
|
||||
* <p> The {@code bundle} parameter allows the original owner to pass data
|
||||
* to the new one.
|
||||
*
|
||||
* @param context the running context as per {@link #onReceive}
|
||||
* @param bundle the data to be passed to the new owner
|
||||
*/
|
||||
public void onTransferOwnershipComplete(@NonNull Context context,
|
||||
@Nullable PersistableBundle bundle) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Intercept standard device administrator broadcasts. Implementations
|
||||
* should not override this method; it is better to implement the
|
||||
@@ -921,6 +964,10 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
|
||||
onUserAdded(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
|
||||
} else if (ACTION_USER_REMOVED.equals(action)) {
|
||||
onUserRemoved(context, intent, intent.getParcelableExtra(Intent.EXTRA_USER));
|
||||
} else if (ACTION_TRANSFER_OWNERSHIP_COMPLETE.equals(action)) {
|
||||
PersistableBundle bundle =
|
||||
intent.getParcelableExtra(EXTRA_TRANSFER_OWNER_ADMIN_EXTRAS_BUNDLE);
|
||||
onTransferOwnershipComplete(context, bundle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1124,6 +1124,7 @@ public class DevicePolicyManager {
|
||||
*
|
||||
* This broadcast is sent only to the primary user.
|
||||
* @see #ACTION_PROVISION_MANAGED_DEVICE
|
||||
* @see DevicePolicyManager#transferOwnership(ComponentName, ComponentName, PersistableBundle)
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_DEVICE_OWNER_CHANGED
|
||||
@@ -1708,6 +1709,16 @@ public class DevicePolicyManager {
|
||||
*/
|
||||
public static final int ID_TYPE_MEID = 8;
|
||||
|
||||
/**
|
||||
* Broadcast action: sent when the profile owner is set, changed or cleared.
|
||||
*
|
||||
* This broadcast is sent only to the user managed by the new profile owner.
|
||||
* @see DevicePolicyManager#transferOwnership(ComponentName, ComponentName, PersistableBundle)
|
||||
*/
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_PROFILE_OWNER_CHANGED =
|
||||
"android.app.action.PROFILE_OWNER_CHANGED";
|
||||
|
||||
/**
|
||||
* Return true if the given administrator component is currently active (enabled) in the system.
|
||||
*
|
||||
@@ -8990,41 +9001,34 @@ public class DevicePolicyManager {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO STOPSHIP Add link to onTransferComplete callback when implemented.
|
||||
/**
|
||||
* Transfers the current administrator. All policies from the current administrator are
|
||||
* migrated to the new administrator. The whole operation is atomic - the transfer is either
|
||||
* complete or not done at all.
|
||||
* Changes the current administrator to another one. All policies from the current
|
||||
* administrator are migrated to the new administrator. The whole operation is atomic -
|
||||
* the transfer is either complete or not done at all.
|
||||
*
|
||||
* Depending on the current administrator (device owner, profile owner, corporate owned
|
||||
* profile owner), you have the following expected behaviour:
|
||||
* <p>Depending on the current administrator (device owner, profile owner), you have the
|
||||
* following expected behaviour:
|
||||
* <ul>
|
||||
* <li>A device owner can only be transferred to a new device owner</li>
|
||||
* <li>A profile owner can only be transferred to a new profile owner</li>
|
||||
* <li>A corporate owned managed profile can have two cases:
|
||||
* <ul>
|
||||
* <li>If the device owner and profile owner are the same package,
|
||||
* both will be transferred.</li>
|
||||
* <li>If the device owner and profile owner are different packages,
|
||||
* and if this method is called from the profile owner, only the profile owner
|
||||
* is transferred. Similarly, if it is called from the device owner, only
|
||||
* the device owner is transferred.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
|
||||
* @param target Which {@link DeviceAdminReceiver} we want the new administrator to be.
|
||||
* @param bundle Parameters - This bundle allows the current administrator to pass data to the
|
||||
* new administrator. The parameters will be received in the
|
||||
* onTransferComplete callback.
|
||||
* @hide
|
||||
* <p>Use the {@code bundle} parameter to pass data to the new administrator. The parameters
|
||||
* will be received in the
|
||||
* {@link DeviceAdminReceiver#onTransferOwnershipComplete(Context, PersistableBundle)} callback.
|
||||
*
|
||||
* @param admin which {@link DeviceAdminReceiver} this request is associated with
|
||||
* @param target which {@link DeviceAdminReceiver} we want the new administrator to be
|
||||
* @param bundle data to be sent to the new administrator
|
||||
* @throws SecurityException if {@code admin} is not a device owner nor a profile owner
|
||||
* @throws IllegalArgumentException if {@code admin} or {@code target} is {@code null},
|
||||
* both are components in the same package or {@code target} is not an active admin
|
||||
*/
|
||||
public void transferOwner(@NonNull ComponentName admin, @NonNull ComponentName target,
|
||||
public void transferOwnership(@NonNull ComponentName admin, @NonNull ComponentName target,
|
||||
PersistableBundle bundle) {
|
||||
throwIfParentInstance("transferOwner");
|
||||
throwIfParentInstance("transferOwnership");
|
||||
try {
|
||||
mService.transferOwner(admin, target, bundle);
|
||||
mService.transferOwnership(admin, target, bundle);
|
||||
} catch (RemoteException re) {
|
||||
throw re.rethrowFromSystemServer();
|
||||
}
|
||||
|
||||
@@ -387,5 +387,5 @@ interface IDevicePolicyManager {
|
||||
boolean isLogoutEnabled();
|
||||
|
||||
List<String> getDisallowedSystemApps(in ComponentName admin, int userId, String provisioningAction);
|
||||
void transferOwner(in ComponentName admin, in ComponentName target, in PersistableBundle bundle);
|
||||
void transferOwnership(in ComponentName admin, in ComponentName target, in PersistableBundle bundle);
|
||||
}
|
||||
|
||||
@@ -567,6 +567,10 @@
|
||||
<!-- Made protected in P (was introduced in JB-MR2) -->
|
||||
<protected-broadcast android:name="android.intent.action.GET_RESTRICTION_ENTRIES" />
|
||||
|
||||
<!-- Added in P -->
|
||||
<protected-broadcast android:name="android.app.action.PROFILE_OWNER_CHANGED" />
|
||||
<protected-broadcast android:name="android.app.action.TRANSFER_OWNER_COMPLETE" />
|
||||
|
||||
<!-- ====================================================================== -->
|
||||
<!-- RUNTIME PERMISSIONS -->
|
||||
<!-- ====================================================================== -->
|
||||
|
||||
@@ -64,7 +64,7 @@ abstract class BaseIDevicePolicyManager extends IDevicePolicyManager.Stub {
|
||||
|
||||
public void setSystemSetting(ComponentName who, String setting, String value){}
|
||||
|
||||
public void transferOwner(ComponentName admin, ComponentName target, PersistableBundle bundle) {}
|
||||
public void transferOwnership(ComponentName admin, ComponentName target, PersistableBundle bundle) {}
|
||||
|
||||
public boolean generateKeyPair(ComponentName who, String callerPackage, String algorithm,
|
||||
ParcelableKeyGenParameterSpec keySpec, int idAttestationFlags,
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.Manifest.permission.BIND_DEVICE_ADMIN;
|
||||
import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
|
||||
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
|
||||
import static android.app.ActivityManager.USER_OP_SUCCESS;
|
||||
import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNER_ADMIN_EXTRAS_BUNDLE;
|
||||
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_USER;
|
||||
import static android.app.admin.DevicePolicyManager.CODE_ACCOUNTS_NOT_EMPTY;
|
||||
import static android.app.admin.DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED;
|
||||
@@ -154,7 +155,6 @@ import android.provider.ContactsContract.QuickContact;
|
||||
import android.provider.ContactsInternal;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.Global;
|
||||
import android.security.Credentials;
|
||||
import android.security.IKeyChainAliasCallback;
|
||||
import android.security.IKeyChainService;
|
||||
import android.security.KeyChain;
|
||||
@@ -6506,13 +6506,36 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void sendDeviceOwnerCommand(String action, Bundle extras) {
|
||||
Intent intent = new Intent(action);
|
||||
intent.setComponent(mOwners.getDeviceOwnerComponent());
|
||||
void sendDeviceOwnerCommand(String action, Bundle extras) {
|
||||
int deviceOwnerUserId;
|
||||
ComponentName deviceOwnerComponent;
|
||||
synchronized (this) {
|
||||
deviceOwnerUserId = mOwners.getDeviceOwnerUserId();
|
||||
deviceOwnerComponent = mOwners.getDeviceOwnerComponent();
|
||||
}
|
||||
sendActiveAdminCommand(action, extras, deviceOwnerUserId,
|
||||
deviceOwnerComponent);
|
||||
}
|
||||
|
||||
private void sendProfileOwnerCommand(String action, Bundle extras, int userHandle) {
|
||||
sendActiveAdminCommand(action, extras, userHandle,
|
||||
mOwners.getProfileOwnerComponent(userHandle));
|
||||
}
|
||||
|
||||
private void sendActiveAdminCommand(String action, Bundle extras,
|
||||
int userHandle, ComponentName receiverComponent) {
|
||||
final Intent intent = new Intent(action);
|
||||
intent.setComponent(receiverComponent);
|
||||
if (extras != null) {
|
||||
intent.putExtras(extras);
|
||||
}
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.of(mOwners.getDeviceOwnerUserId()));
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.of(userHandle));
|
||||
}
|
||||
|
||||
private void sendOwnerChangedBroadcast(String broadcast, int userId) {
|
||||
final Intent intent = new Intent(broadcast)
|
||||
.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.of(userId));
|
||||
}
|
||||
|
||||
private synchronized String getDeviceOwnerRemoteBugreportUri() {
|
||||
@@ -6890,10 +6913,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
ident = mInjector.binderClearCallingIdentity();
|
||||
try {
|
||||
// TODO Send to system too?
|
||||
mContext.sendBroadcastAsUser(
|
||||
new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED)
|
||||
.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND),
|
||||
UserHandle.of(userId));
|
||||
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED, userId);
|
||||
} finally {
|
||||
mInjector.binderRestoreCallingIdentity(ident);
|
||||
}
|
||||
@@ -7044,9 +7064,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
try {
|
||||
clearDeviceOwnerLocked(admin, deviceOwnerUserId);
|
||||
removeActiveAdminLocked(deviceOwnerComponent, deviceOwnerUserId);
|
||||
Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED);
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
|
||||
mContext.sendBroadcastAsUser(intent, UserHandle.of(deviceOwnerUserId));
|
||||
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED,
|
||||
deviceOwnerUserId);
|
||||
} finally {
|
||||
mInjector.binderRestoreCallingIdentity(ident);
|
||||
}
|
||||
@@ -7131,6 +7150,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
ensureUnknownSourcesRestrictionForProfileOwnerLocked(userHandle, admin,
|
||||
true /* newOwner */);
|
||||
}
|
||||
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED,
|
||||
userHandle);
|
||||
} finally {
|
||||
mInjector.binderRestoreCallingIdentity(id);
|
||||
}
|
||||
@@ -7159,6 +7180,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
try {
|
||||
clearProfileOwnerLocked(admin, userId);
|
||||
removeActiveAdminLocked(who, userId);
|
||||
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED,
|
||||
userId);
|
||||
} finally {
|
||||
mInjector.binderRestoreCallingIdentity(ident);
|
||||
}
|
||||
@@ -11846,9 +11869,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
}
|
||||
|
||||
//TODO: Add callback information to the javadoc once it is completed.
|
||||
//TODO: Make transferOwner atomic.
|
||||
//TODO: Make transferOwnership atomic.
|
||||
@Override
|
||||
public void transferOwner(ComponentName admin, ComponentName target, PersistableBundle bundle) {
|
||||
public void transferOwnership(ComponentName admin, ComponentName target, PersistableBundle bundle) {
|
||||
if (!mHasFeature) {
|
||||
return;
|
||||
}
|
||||
@@ -11876,13 +11899,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
|
||||
final long id = mInjector.binderClearCallingIdentity();
|
||||
try {
|
||||
//STOPSHIP add support for COMP, edge cases when device is rebooted/work mode off,
|
||||
//transfer callbacks and broadcast
|
||||
//STOPSHIP add support for COMP, edge cases when device is rebooted/work mode off
|
||||
synchronized (this) {
|
||||
if (isProfileOwner(admin, callingUserId)) {
|
||||
transferProfileOwnerLocked(admin, target, callingUserId);
|
||||
transferProfileOwnerLocked(admin, target, callingUserId, bundle);
|
||||
} else if (isDeviceOwner(admin, callingUserId)) {
|
||||
transferDeviceOwnerLocked(admin, target, callingUserId);
|
||||
transferDeviceOwnerLocked(admin, target, callingUserId, bundle);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -11894,24 +11916,40 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
|
||||
* Transfers the profile owner for user with id profileOwnerUserId from admin to target.
|
||||
*/
|
||||
private void transferProfileOwnerLocked(ComponentName admin, ComponentName target,
|
||||
int profileOwnerUserId) {
|
||||
int profileOwnerUserId, PersistableBundle bundle) {
|
||||
transferActiveAdminUncheckedLocked(target, admin, profileOwnerUserId);
|
||||
mOwners.transferProfileOwner(target, profileOwnerUserId);
|
||||
Slog.i(LOG_TAG, "Profile owner set: " + target + " on user " + profileOwnerUserId);
|
||||
mOwners.writeProfileOwner(profileOwnerUserId);
|
||||
mDeviceAdminServiceController.startServiceForOwner(
|
||||
target.getPackageName(), profileOwnerUserId, "transfer-profile-owner");
|
||||
sendProfileOwnerCommand(DeviceAdminReceiver.ACTION_TRANSFER_OWNERSHIP_COMPLETE,
|
||||
getTransferOwnerAdminExtras(bundle), profileOwnerUserId);
|
||||
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_PROFILE_OWNER_CHANGED,
|
||||
profileOwnerUserId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfers the device owner for user with id userId from admin to target.
|
||||
*/
|
||||
private void transferDeviceOwnerLocked(ComponentName admin, ComponentName target, int userId) {
|
||||
private void transferDeviceOwnerLocked(ComponentName admin, ComponentName target, int userId,
|
||||
PersistableBundle bundle) {
|
||||
transferActiveAdminUncheckedLocked(target, admin, userId);
|
||||
mOwners.transferDeviceOwner(target);
|
||||
Slog.i(LOG_TAG, "Device owner set: " + target + " on user " + userId);
|
||||
mOwners.writeDeviceOwner();
|
||||
mDeviceAdminServiceController.startServiceForOwner(
|
||||
target.getPackageName(), userId, "transfer-device-owner");
|
||||
sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_TRANSFER_OWNERSHIP_COMPLETE,
|
||||
getTransferOwnerAdminExtras(bundle));
|
||||
sendOwnerChangedBroadcast(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED, userId);
|
||||
}
|
||||
|
||||
private Bundle getTransferOwnerAdminExtras(PersistableBundle bundle) {
|
||||
Bundle extras = new Bundle();
|
||||
if (bundle != null) {
|
||||
extras.putParcelable(EXTRA_TRANSFER_OWNER_ADMIN_EXTRAS_BUNDLE, bundle);
|
||||
}
|
||||
return extras;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user