blob: 89366cb9c51867602450b59bae444c0a67dbc115 [file] [log] [blame]
/*
* Copyright (C) 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.bedstead.remotedpc;
import android.content.ComponentName;
import android.content.Context;
import android.os.UserHandle;
import androidx.annotation.Nullable;
import com.android.bedstead.nene.TestApis;
import com.android.bedstead.nene.devicepolicy.DeviceOwner;
import com.android.bedstead.nene.devicepolicy.DevicePolicyController;
import com.android.bedstead.nene.devicepolicy.ProfileOwner;
import com.android.bedstead.nene.users.UserReference;
import com.android.bedstead.testapp.TestApp;
import com.android.bedstead.testapp.TestAppInstanceReference;
import com.android.bedstead.testapp.TestAppProvider;
/** Entry point to RemoteDPC. */
public final class RemoteDpc extends TestAppInstanceReference {
// This must be instrumentation not instrumented to access the resources
private static final Context sContext = TestApis.context().instrumentationContext();
public static final ComponentName DPC_COMPONENT_NAME = new ComponentName(
"com.android.RemoteDPC",
"com.android.eventlib.premade.EventLibDeviceAdminReceiver"
);
private static final TestAppProvider sTestAppProvider = new TestAppProvider();
private static final TestApp sTestApp = sTestAppProvider.query()
.wherePackageName().isEqualTo(DPC_COMPONENT_NAME.getPackageName())
.get();
/**
* Get the {@link RemoteDpc} instance for the Device Owner.
*
* <p>This will return {@code null} if there is no Device Owner or it is not a RemoteDPC app.
*/
@Nullable
public static RemoteDpc deviceOwner() {
DeviceOwner deviceOwner = TestApis.devicePolicy().getDeviceOwner();
if (deviceOwner == null || !deviceOwner.componentName().equals(DPC_COMPONENT_NAME)) {
return null;
}
return new RemoteDpc(deviceOwner);
}
/**
* Get the {@link RemoteDpc} instance for the Profile Owner of the current user.
*
* <p>This will return null if there is no Profile Owner or it is not a RemoteDPC app.
*/
@Nullable
public static RemoteDpc profileOwner() {
return profileOwner(TestApis.users().instrumented());
}
/**
* Get the {@link RemoteDpc} instance for the Profile Owner of the given {@code profile}.
*
* <p>This will return null if there is no Profile Owner or it is not a RemoteDPC app.
*/
@Nullable
public static RemoteDpc profileOwner(UserHandle profile) {
if (profile == null) {
throw new NullPointerException();
}
return profileOwner(TestApis.users().find(profile));
}
/**
* Get the {@link RemoteDpc} instance for the Profile Owner of the given {@code profile}.
*
* <p>This will return null if there is no Profile Owner or it is not a RemoteDPC app.
*/
@Nullable
public static RemoteDpc profileOwner(UserReference profile) {
if (profile == null) {
throw new NullPointerException();
}
ProfileOwner profileOwner = TestApis.devicePolicy().getProfileOwner(profile);
if (profileOwner == null || !profileOwner.componentName().equals(DPC_COMPONENT_NAME)) {
return null;
}
return new RemoteDpc(profileOwner);
}
/**
* Get the most specific {@link RemoteDpc} instance for the current user.
*
* <p>If the user has a RemoteDPC Profile Owner, this will refer to that. If it does not but
* has a RemoteDPC Device Owner it will refer to that. Otherwise it will return null.
*/
@Nullable
public static RemoteDpc any() {
return any(TestApis.users().instrumented());
}
/**
* Get the most specific {@link RemoteDpc} instance for the current user.
*
* <p>If the user has a RemoteDPC Profile Owner, this will refer to that. If it does not but
* has a RemoteDPC Device Owner it will refer to that. Otherwise it will return null.
*/
@Nullable
public static RemoteDpc any(UserHandle user) {
if (user == null) {
throw new NullPointerException();
}
return any(TestApis.users().find(user));
}
/**
* Get the most specific {@link RemoteDpc} instance for the current user.
*
* <p>If the user has a RemoteDPC Profile Owner, this will refer to that. If it does not but
* has a RemoteDPC Device Owner it will refer to that. Otherwise it will return null.
*/
@Nullable
public static RemoteDpc any(UserReference user) {
RemoteDpc remoteDPC = profileOwner(user);
if (remoteDPC != null) {
return remoteDPC;
}
return deviceOwner();
}
/**
* Get the {@link RemoteDpc} controller for the given {@link DevicePolicyController}.
*/
public static RemoteDpc forDevicePolicyController(DevicePolicyController controller) {
if (controller == null) {
throw new NullPointerException();
}
if (!controller.componentName().equals(DPC_COMPONENT_NAME)) {
throw new IllegalStateException("DevicePolicyController is not a RemoteDPC: "
+ controller);
}
return new RemoteDpc(controller);
}
/**
* Set RemoteDPC as the Device Owner.
*/
public static RemoteDpc setAsDeviceOwner() {
DeviceOwner deviceOwner = TestApis.devicePolicy().getDeviceOwner();
if (deviceOwner != null) {
if (deviceOwner.componentName().equals(DPC_COMPONENT_NAME)) {
return new RemoteDpc(deviceOwner); // Already set
}
deviceOwner.remove();
}
ensureInstalled(TestApis.users().system());
return new RemoteDpc(TestApis.devicePolicy().setDeviceOwner(DPC_COMPONENT_NAME));
}
/**
* Set RemoteDPC as the Profile Owner.
*/
public static RemoteDpc setAsProfileOwner(UserHandle user) {
if (user == null) {
throw new NullPointerException();
}
return setAsProfileOwner(TestApis.users().find(user));
}
/**
* Set RemoteDPC as the Profile Owner.
*/
public static RemoteDpc setAsProfileOwner(UserReference user) {
if (user == null) {
throw new NullPointerException();
}
ProfileOwner profileOwner = TestApis.devicePolicy().getProfileOwner(user);
if (profileOwner != null) {
if (profileOwner.componentName().equals(DPC_COMPONENT_NAME)) {
return new RemoteDpc(profileOwner); // Already set
}
profileOwner.remove();
}
ensureInstalled(user);
return new RemoteDpc(TestApis.devicePolicy().setProfileOwner(user, DPC_COMPONENT_NAME));
}
private static void ensureInstalled(UserReference user) {
sTestApp.install(user);
}
private final DevicePolicyController mDevicePolicyController;
private RemoteDpc(DevicePolicyController devicePolicyController) {
super(sTestApp, devicePolicyController == null ? null : devicePolicyController.user());
mDevicePolicyController = devicePolicyController;
}
/**
* Get the {@link DevicePolicyController} for this instance of RemoteDPC.
*/
public DevicePolicyController devicePolicyController() {
return mDevicePolicyController;
}
/**
* Remove RemoteDPC as Device Owner or Profile Owner and uninstall the APK from the user.
*/
public void remove() {
mDevicePolicyController.remove();
TestApis.packages().find(DPC_COMPONENT_NAME.getPackageName())
.uninstall(mDevicePolicyController.user());
}
/**
* Get the {@link TestAppInstanceReference} for the DPC.
*
*/
public TestAppInstanceReference app() {
return sTestApp.instance(mDevicePolicyController.user());
}
/**
* Get the {@link ComponentName} of the DPC.
*/
public ComponentName componentName() {
return DPC_COMPONENT_NAME;
}
@Override
public int hashCode() {
return mDevicePolicyController.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof RemoteDpc)) {
return false;
}
RemoteDpc other = (RemoteDpc) obj;
return other.mDevicePolicyController.equals(mDevicePolicyController);
}
@Override
public String toString() {
return "RemoteDpc{"
+ "devicePolicyController=" + mDevicePolicyController
+ ", testApp=" + super.toString()
+ '}';
}
}