Skip to content

Commit a0a9a93

Browse files
author
Rubin Xu
committed
Introduce admin constraints for org-owned profile owner
* Convert some existing preferences to use this new constraint * Allow security logging to be called by org-owned profile owner * Small tweaks to security logging event date printing * Remove redundant constaints "deviceOwner|profileOwner" (which is the default behaviour) from preferences * Remove unused constaints "notDeviceOwner" and "notProfileOwner" * Update constraints for some API * Enabling backup service is callable by PO since Q * Setting time & timezone is callbele by org-owned profile owner * WiFi config lockdown is callable by org-owned profile owner * Setting system update policy is callably by org-owned profile owner * Installing system update is callable by org-owned profile owner * Setting organization name is callable by PO and DO * Setting lockscreen message is callable by org-owned profile owner * Changing location mode is callable by DO only * Setting auto time and timezone is callable by org-owned profile owner * Factory resetting device is callable by org-owned profile owner * Document custom constraints for some preferences Bug: 149916080 Test: manual Change-Id: Ic7bc08405a586de2d675ffa3b3e392ea63385d43
1 parent d8963f3 commit a0a9a93

File tree

8 files changed

+102
-90
lines changed

8 files changed

+102
-90
lines changed

app/src/main/java/com/afwsamples/testdpc/common/preference/DpcPreferenceHelper.java

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import android.view.View;
3030
import android.widget.TextView;
3131
import com.afwsamples.testdpc.R;
32+
import com.afwsamples.testdpc.common.ReflectionUtil;
33+
import com.afwsamples.testdpc.common.ReflectionUtil.ReflectionIsTemporaryException;
3234
import com.afwsamples.testdpc.common.Util;
3335
import java.lang.annotation.Retention;
3436
import java.lang.annotation.RetentionPolicy;
@@ -47,15 +49,18 @@
4749
*/
4850
public class DpcPreferenceHelper {
4951
@Retention(RetentionPolicy.SOURCE)
50-
@IntDef(flag = true, value = {ADMIN_NONE, ADMIN_DEVICE_OWNER, ADMIN_PROFILE_OWNER})
52+
@IntDef(flag = true, value = {ADMIN_NONE, ADMIN_DEVICE_OWNER, ADMIN_BYOD_PROFILE_OWNER,
53+
ADMIN_ORG_OWNED_PROFILE_OWNER})
5154
public @interface AdminKind {}
5255
public static final int ADMIN_NONE = 0x1;
5356
public static final int ADMIN_DEVICE_OWNER = 0x2;
54-
public static final int ADMIN_PROFILE_OWNER = 0x4;
55-
public static final int ADMIN_ANY = ADMIN_NONE | ADMIN_DEVICE_OWNER | ADMIN_PROFILE_OWNER;
57+
public static final int ADMIN_BYOD_PROFILE_OWNER = 0x4;
58+
public static final int ADMIN_ORG_OWNED_PROFILE_OWNER = 0x8;
59+
public static final int ADMIN_PROFILE_OWNER =
60+
ADMIN_BYOD_PROFILE_OWNER | ADMIN_ORG_OWNED_PROFILE_OWNER;
61+
public static final int ADMIN_ANY =
62+
ADMIN_NONE | ADMIN_DEVICE_OWNER | ADMIN_PROFILE_OWNER | ADMIN_ORG_OWNED_PROFILE_OWNER;
5663
public static final int ADMIN_NOT_NONE = ADMIN_ANY & ~ADMIN_NONE;
57-
public static final int ADMIN_NOT_DEVICE_OWNER = ADMIN_ANY & ~ADMIN_DEVICE_OWNER;
58-
public static final int ADMIN_NOT_PROFILE_OWNER = ADMIN_ANY & ~ADMIN_PROFILE_OWNER;
5964
public static final @AdminKind int ADMIN_DEFAULT = ADMIN_NOT_NONE;
6065
public static final int NO_CUSTOM_CONSTRIANT = 0;
6166

@@ -252,6 +257,16 @@ private int getCurrentAdmin() {
252257
if (dpm.isDeviceOwnerApp(packageName)) {
253258
return ADMIN_DEVICE_OWNER;
254259
}
260+
Boolean orgOwned;
261+
try {
262+
orgOwned = (Boolean) ReflectionUtil.invoke(dpm,
263+
"isOrganizationOwnedDeviceWithManagedProfile");
264+
} catch (ReflectionIsTemporaryException e) {
265+
orgOwned = false;
266+
}
267+
if (orgOwned) {
268+
return ADMIN_ORG_OWNED_PROFILE_OWNER;
269+
}
255270
if (dpm.isProfileOwnerApp(packageName)) {
256271
return ADMIN_PROFILE_OWNER;
257272
}
@@ -304,7 +319,12 @@ private String getAdminConstraintSummary() {
304319
if (isEnabledForAdmin(ADMIN_DEVICE_OWNER)) {
305320
admins.add(mContext.getString(R.string.device_owner));
306321
}
307-
if (isEnabledForAdmin(ADMIN_PROFILE_OWNER)) {
322+
// Only add the org-owned profile message if the constraint is specific to org-owned profile
323+
// and not all profile types, to reduce verbosity of the message.
324+
if (isEnabledForAdmin(ADMIN_ORG_OWNED_PROFILE_OWNER) &&
325+
!isEnabledForAdmin(ADMIN_PROFILE_OWNER)) {
326+
admins.add(mContext.getString(R.string.org_owned_profile_owner));
327+
} else if (isEnabledForAdmin(ADMIN_PROFILE_OWNER)) {
308328
admins.add(mContext.getString(R.string.profile_owner));
309329
}
310330
if (!TextUtils.isEmpty(mDelegationConstraint)) {

app/src/main/java/com/afwsamples/testdpc/policy/PolicyManagementFragment.java

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ public class PolicyManagementFragment extends BaseSearchablePolicyPreferenceFrag
457457
private SwitchPreference mStayOnWhilePluggedInSwitchPreference;
458458
private DpcSwitchPreference mInstallNonMarketAppsPreference;
459459

460-
private SwitchPreference mEnableBackupServicePreference;
460+
private DpcSwitchPreference mEnableBackupServicePreference;
461461
private SwitchPreference mEnableSecurityLoggingPreference;
462462
private SwitchPreference mEnableNetworkLoggingPreference;
463463
private DpcSwitchPreference mSetAutoTimeRequiredPreference;
@@ -558,8 +558,6 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
558558
mDisableCameraOnParentSwitchPreference = (DpcSwitchPreference)
559559
findPreference(DISABLE_CAMERA_ON_PARENT_KEY);
560560
mDisableCameraOnParentSwitchPreference.setOnPreferenceChangeListener(this);
561-
mDisableCameraOnParentSwitchPreference
562-
.setCustomConstraint(this::validateProfileOwnerOfOrganizationOwnedDevice);
563561
findPreference(CAPTURE_IMAGE_KEY).setOnPreferenceClickListener(this);
564562
findPreference(CAPTURE_VIDEO_KEY).setOnPreferenceClickListener(this);
565563
mDisableScreenCaptureSwitchPreference = (SwitchPreference) findPreference(
@@ -568,8 +566,6 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
568566
mDisableScreenCaptureOnParentSwitchPreference = (DpcSwitchPreference) findPreference(
569567
DISABLE_SCREEN_CAPTURE_ON_PARENT_KEY);
570568
mDisableScreenCaptureOnParentSwitchPreference.setOnPreferenceChangeListener(this);
571-
mDisableScreenCaptureOnParentSwitchPreference
572-
.setCustomConstraint(this::validateProfileOwnerOfOrganizationOwnedDevice);
573569
mMuteAudioSwitchPreference = (SwitchPreference) findPreference(
574570
MUTE_AUDIO_KEY);
575571
mMuteAudioSwitchPreference.setOnPreferenceChangeListener(this);
@@ -608,8 +604,10 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
608604
findPreference(WIPE_DATA_KEY).setOnPreferenceClickListener(this);
609605
findPreference(PERSISTENT_DEVICE_OWNER_KEY).setOnPreferenceClickListener(this);
610606
findPreference(REMOVE_DEVICE_OWNER_KEY).setOnPreferenceClickListener(this);
611-
mEnableBackupServicePreference = (SwitchPreference) findPreference(ENABLE_BACKUP_SERVICE);
607+
mEnableBackupServicePreference = (DpcSwitchPreference) findPreference(
608+
ENABLE_BACKUP_SERVICE);
612609
mEnableBackupServicePreference.setOnPreferenceChangeListener(this);
610+
mEnableBackupServicePreference.setCustomConstraint(this::validateDeviceOwnerBeforeQ);
613611
findPreference(REQUEST_BUGREPORT_KEY).setOnPreferenceClickListener(this);
614612
mEnableSecurityLoggingPreference =
615613
(SwitchPreference) findPreference(ENABLE_SECURITY_LOGGING);
@@ -657,13 +655,9 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
657655
findPreference(HIDE_APPS_KEY).setOnPreferenceClickListener(this);
658656
mHideAppsParentPreference = (DpcPreference) findPreference(HIDE_APPS_PARENT_KEY);
659657
mHideAppsParentPreference.setOnPreferenceClickListener(this);
660-
mHideAppsParentPreference.setCustomConstraint(
661-
this::validateProfileOwnerOfOrganizationOwnedDevice);
662658
findPreference(UNHIDE_APPS_KEY).setOnPreferenceClickListener(this);
663659
mUnhideAppsParentPreference = (DpcPreference) findPreference(UNHIDE_APPS_PARENT_KEY);
664660
mUnhideAppsParentPreference.setOnPreferenceClickListener(this);
665-
mUnhideAppsParentPreference.setCustomConstraint(
666-
this::validateProfileOwnerOfOrganizationOwnedDevice);
667661
findPreference(SUSPEND_APPS_KEY).setOnPreferenceClickListener(this);
668662
findPreference(UNSUSPEND_APPS_KEY).setOnPreferenceClickListener(this);
669663
findPreference(CLEAR_APP_DATA_KEY).setOnPreferenceClickListener(this);
@@ -702,7 +696,6 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
702696
findPreference(SET_USER_RESTRICTIONS_KEY).setOnPreferenceClickListener(this);
703697
mUserRestrictionsParentPreference = (DpcPreference) findPreference(SET_USER_RESTRICTIONS_PARENT_KEY);
704698
mUserRestrictionsParentPreference.setOnPreferenceClickListener(this);
705-
mUserRestrictionsParentPreference.setCustomConstraint(this::validateProfileOwnerOfOrganizationOwnedDevice);
706699

707700
findPreference(REBOOT_KEY).setOnPreferenceClickListener(this);
708701
findPreference(SET_SHORT_SUPPORT_MESSAGE_KEY).setOnPreferenceClickListener(this);
@@ -757,13 +750,9 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
757750

758751
mSuspendPersonalApps = (DpcSwitchPreference) findPreference(SUSPEND_PERSONAL_APPS_KEY);
759752
mSuspendPersonalApps.setOnPreferenceChangeListener(this);
760-
mSuspendPersonalApps.setCustomConstraint(
761-
this::validateProfileOwnerOfOrganizationOwnedDevice);
762753

763754
mProfileMaxTimeOff = (DpcEditTextPreference) findPreference(PROFILE_MAX_TIME_OFF_KEY);
764755
mProfileMaxTimeOff.setOnPreferenceChangeListener(this);
765-
mProfileMaxTimeOff.setCustomConstraint(
766-
this::validateProfileOwnerOfOrganizationOwnedDevice);
767756
maybeUpdateProfileMaxTimeOff();
768757

769758
onCreateSetNewPasswordWithComplexityPreference();
@@ -2359,7 +2348,11 @@ private void loadAppFeedbackNotifications() {
23592348
private void loadAppStatus() {
23602349
final @StringRes int appStatusStringId;
23612350
if (mDevicePolicyManager.isProfileOwnerApp(mPackageName)) {
2362-
appStatusStringId = R.string.this_is_a_profile_owner;
2351+
if (isOrganizationOwnedDeviceWithManagedProfile()) {
2352+
appStatusStringId = R.string.this_is_an_org_owned_profile_owner;
2353+
} else {
2354+
appStatusStringId = R.string.this_is_a_profile_owner;
2355+
}
23632356
} else if (mDevicePolicyManager.isDeviceOwnerApp(mPackageName)) {
23642357
appStatusStringId = R.string.this_is_a_device_owner;
23652358
} else if (isDelegatedApp()) {
@@ -4021,6 +4014,15 @@ private int validateDeviceOwnerBeforeP() {
40214014
return NO_CUSTOM_CONSTRIANT;
40224015
}
40234016

4017+
private int validateDeviceOwnerBeforeQ() {
4018+
if (Util.SDK_INT < VERSION_CODES.Q) {
4019+
if (!mDevicePolicyManager.isDeviceOwnerApp(mPackageName)) {
4020+
return R.string.requires_device_owner;
4021+
}
4022+
}
4023+
return NO_CUSTOM_CONSTRIANT;
4024+
}
4025+
40244026
// TODO: nuke it when R sdk is available
40254027
private boolean isOrganizationOwnedDeviceWithManagedProfile() {
40264028
try {
@@ -4032,13 +4034,6 @@ private boolean isOrganizationOwnedDeviceWithManagedProfile() {
40324034
}
40334035
}
40344036

4035-
private int validateProfileOwnerOfOrganizationOwnedDevice() {
4036-
if (Util.SDK_INT < Util.R_VERSION_CODE || !isOrganizationOwnedDeviceWithManagedProfile()) {
4037-
return R.string.requires_profile_owner_organization_owned_device;
4038-
}
4039-
return NO_CUSTOM_CONSTRIANT;
4040-
}
4041-
40424037
abstract static class ManageLockTaskListCallback {
40434038
public abstract void onPositiveButtonClicked(String[] lockTaskArray);
40444039
}

app/src/main/java/com/afwsamples/testdpc/policy/SecurityLogsFragment.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.afwsamples.testdpc.DeviceAdminReceiver;
3333
import com.afwsamples.testdpc.R;
3434
import com.afwsamples.testdpc.common.Util;
35+
import java.text.SimpleDateFormat;
3536
import java.util.ArrayList;
3637
import java.util.Date;
3738
import java.util.List;
@@ -96,15 +97,16 @@ private void processEvents(List<SecurityEvent> logs) {
9697
: R.string.failed_to_retrieve_security_logs);
9798
mAdapter.add(message);
9899
} else {
100+
SimpleDateFormat formatter = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
99101
Log.d(TAG, "Incoming logs size: " + logs.size());
100102
for (SecurityEvent event : logs) {
101103
StringBuilder sb = new StringBuilder();
102-
sb.append(getStringEventTagFromId(event.getTag()));
103104
if (Util.SDK_INT >= VERSION_CODES.P) {
104-
sb.append(" (id: " + getEventId(event) + ")");
105+
sb.append(getEventId(event) + ": ");
105106
}
106-
sb.append(" (").append(new Date(TimeUnit.NANOSECONDS.toMillis(
107-
event.getTimeNanos()))).append("): ");
107+
sb.append(getStringEventTagFromId(event.getTag()));
108+
sb.append(" (").append(formatter.format(new Date(TimeUnit.NANOSECONDS.toMillis(
109+
event.getTimeNanos())))).append("): ");
108110
printData(sb, event.getData());
109111
mAdapter.add(sb.toString());
110112
}

app/src/main/res/values/attrs.xml

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,14 @@
3636
<attr name="admin">
3737
<flag name="none" value="0x1" />
3838
<flag name="deviceOwner" value="0x2" />
39-
<flag name="profileOwner" value="0x4" />
39+
<!-- A regular non-org-owned managed profile owner. -->
40+
<flag name="byodProfileOwner" value="0x4" />
41+
<flag name="orgOwnedProfileOwner" value="0x8" />
4042

41-
<flag name="notNone" value="0x6" /> <!-- default -->
42-
<flag name="notDeviceOwner" value="0x5" />
43-
<flag name="notProfileOwner" value="0x3" />
44-
45-
<flag name="any" value="0x7" />
43+
<!-- A regular or org-owned managed profile owner. -->
44+
<flag name="profileOwner" value="0xC" />
45+
<flag name="notNone" value="0xE" /> <!-- default -->
46+
<flag name="any" value="0xF" />
4647
</attr>
4748

4849
<!-- Constrain a preference to a delegated scope. -->

app/src/main/res/values/strings.xml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100
<string name="requires_delimiter">,\u0020</string>
101101
<string name="requires_or">\u0020or\u0020</string>
102102
<string name="device_owner">device owner</string>
103+
<string name="org_owned_profile_owner">organization-owned profile owner</string>
103104
<string name="profile_owner">profile owner</string>
104105
<string name="primary_user">primary user</string>
105106
<string name="secondary_user">secondary user</string>
@@ -115,6 +116,7 @@
115116

116117
<string name="this_is_a_device_owner">This app is the device owner.</string>
117118
<string name="this_is_a_profile_owner">This app is a profile owner.</string>
119+
<string name="this_is_an_org_owned_profile_owner">This app is a profile owner of an organization-owned device.</string>
118120
<string name="this_is_a_delegated_app">This app has delegated permissions.</string>
119121
<string name="this_is_not_an_admin">This app is not an admin.</string>
120122

@@ -316,7 +318,7 @@
316318
<string name="wifi_cancel">Cancel</string>
317319
<string name="wifi_config_success">WI-FI configuration saved.</string>
318320
<string name="wifi_config_fail">Failed to save the WI-FI configuration.</string>
319-
<string name="enable_wifi_config_lockdown">DO created WI-FI configs are modifiable only by DO.</string>
321+
<string name="enable_wifi_config_lockdown">DO created WI-FI configs are modifiable only by DO</string>
320322
<string name="modify_wifi_configuration">Modify WI-FI configuration</string>
321323
<string name="show_wifi_mac_address">Show Wi-Fi MAC address</string>
322324
<string name="show_wifi_mac_address_title">Wi-Fi MAC address</string>

0 commit comments

Comments
 (0)