Skip to content

Commit d5d7e4f

Browse files
Yueming WangAndroid (Google) Code Review
authored andcommitted
Merge "Add cross profile calendar whitelist funcionalities in TestDPC." into ub-testdpc-qt
2 parents 7e04f71 + 9432a9c commit d5d7e4f

File tree

5 files changed

+286
-3
lines changed

5 files changed

+286
-3
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
/*
2+
* Copyright (C) 2018 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.afwsamples.testdpc.policy;
18+
19+
import android.annotation.TargetApi;
20+
import android.app.Activity;
21+
import android.app.AlertDialog;
22+
import android.app.admin.DevicePolicyManager;
23+
import android.content.ComponentName;
24+
import android.content.Context;
25+
import android.content.DialogInterface;
26+
import android.os.Bundle;
27+
import android.support.v7.preference.Preference;
28+
import android.util.ArraySet;
29+
import android.util.Log;
30+
import android.view.View;
31+
import android.widget.EditText;
32+
import android.widget.Toast;
33+
34+
import com.afwsamples.testdpc.DeviceAdminReceiver;
35+
import com.afwsamples.testdpc.R;
36+
import com.afwsamples.testdpc.common.AppInfoArrayAdapter;
37+
import com.afwsamples.testdpc.common.BaseSearchablePolicyPreferenceFragment;
38+
import com.afwsamples.testdpc.common.ReflectionUtil;
39+
import com.afwsamples.testdpc.common.ReflectionUtil.ReflectionIsTemporaryException;
40+
41+
import java.util.ArrayList;
42+
import java.util.Set;
43+
44+
/**
45+
* TODO: Cleanup reflection usages once SDK is updated. b/120765156.
46+
*/
47+
@TargetApi(29)
48+
public class CrossProfileCalendarFragment extends BaseSearchablePolicyPreferenceFragment implements
49+
Preference.OnPreferenceClickListener {
50+
51+
private static String LOG_TAG = "CrossProfileCalendarFragment";
52+
53+
private static final String CROSS_PROFILE_CALENDAR_ADD_PACKAGE_KEY =
54+
"cross_profile_calendar_add_package";
55+
private static final String CROSS_PROFILE_CALENDAR_DELETE_PACKAGE_KEY =
56+
"cross_profile_calendar_delete_package";
57+
private static final String CROSS_PROFILE_CALENDAR_LIST_PACKAGE_KEY =
58+
"cross_profile_calendar_list_package";
59+
60+
private DevicePolicyManager mDevicePolicyManager;
61+
private ComponentName mAdminComponentName;
62+
63+
@Override
64+
public void onCreate(Bundle savedInstanceState) {
65+
mDevicePolicyManager = (DevicePolicyManager) getActivity().getSystemService(
66+
Context.DEVICE_POLICY_SERVICE);
67+
mAdminComponentName = DeviceAdminReceiver.getComponentName(getActivity());
68+
getActivity().getActionBar().setTitle(R.string.cross_profile_calendar);
69+
super.onCreate(savedInstanceState);
70+
}
71+
72+
@Override
73+
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
74+
addPreferencesFromResource(R.xml.cross_profile_calendar_preferences);
75+
76+
findPreference(CROSS_PROFILE_CALENDAR_ADD_PACKAGE_KEY).setOnPreferenceClickListener(this);
77+
findPreference(CROSS_PROFILE_CALENDAR_DELETE_PACKAGE_KEY)
78+
.setOnPreferenceClickListener(this);
79+
findPreference(CROSS_PROFILE_CALENDAR_LIST_PACKAGE_KEY).setOnPreferenceClickListener(this);
80+
}
81+
82+
@Override
83+
public boolean isAvailable(Context context) {
84+
return true;
85+
}
86+
87+
@Override
88+
public boolean onPreferenceClick(Preference preference) {
89+
String key = preference.getKey();
90+
switch (key) {
91+
case CROSS_PROFILE_CALENDAR_ADD_PACKAGE_KEY:
92+
showAddPackageDialog();
93+
return true;
94+
case CROSS_PROFILE_CALENDAR_DELETE_PACKAGE_KEY:
95+
showDeletePackageDialog();
96+
return true;
97+
case CROSS_PROFILE_CALENDAR_LIST_PACKAGE_KEY:
98+
showListPackageDialog();
99+
return true;
100+
}
101+
return false;
102+
}
103+
104+
/**
105+
* Shows a dialog that asks the user for a package name to be whitelisted.
106+
*/
107+
private void showAddPackageDialog() {
108+
if (getActivity() == null || getActivity().isFinishing()) {
109+
return;
110+
}
111+
112+
final View dialogView = getActivity().getLayoutInflater().inflate(
113+
R.layout.simple_edittext, null);
114+
final EditText addPackageEditText = (EditText) dialogView.findViewById(
115+
R.id.input);
116+
117+
new AlertDialog.Builder(getActivity())
118+
.setTitle(R.string.cross_profile_calendar_add_package)
119+
.setView(dialogView)
120+
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
121+
final String packageName = addPackageEditText.getText().toString();
122+
if (packageName.isEmpty()) {
123+
showToast(R.string.cross_profile_calendar_no_package);
124+
return;
125+
}
126+
try {
127+
ReflectionUtil.invoke(mDevicePolicyManager, "addCrossProfileCalendarPackage",
128+
mAdminComponentName, packageName);
129+
showToast(String.format("Successfully whitelisted package %s for cross profile "
130+
+ "calendar", packageName));
131+
} catch (ReflectionIsTemporaryException e) {
132+
Log.e(LOG_TAG, "Failed to invoke addCrossProfileCalendarPackage", e);
133+
}
134+
})
135+
.setNegativeButton(android.R.string.cancel, null)
136+
.show();
137+
}
138+
139+
/**
140+
* Shows a dialog that asks the user for a package name to be removed from the whitelist.
141+
*/
142+
private void showDeletePackageDialog() {
143+
if (getActivity() == null || getActivity().isFinishing()) {
144+
return;
145+
}
146+
147+
final View dialogView = getActivity().getLayoutInflater().inflate(
148+
R.layout.simple_edittext, null);
149+
final EditText deletePackageEditText = (EditText) dialogView.findViewById(
150+
R.id.input);
151+
152+
new AlertDialog.Builder(getActivity())
153+
.setTitle(R.string.cross_profile_calendar_delete_package)
154+
.setView(dialogView)
155+
.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
156+
final String packageName = deletePackageEditText.getText().toString();
157+
if (packageName.isEmpty()) {
158+
showToast(R.string.cross_profile_calendar_no_package);
159+
return;
160+
}
161+
try {
162+
boolean succeed = (Boolean) ReflectionUtil.invoke(mDevicePolicyManager,
163+
"removeCrossProfileCalendarPackage", mAdminComponentName, packageName);
164+
if (succeed) {
165+
showToast(String.format("Successfully removed package %s for cross profile "
166+
+ "calendar", packageName));
167+
} else {
168+
showToast(String.format("Failed to remove package %s for cross profile "
169+
+ "calendar", packageName));
170+
}
171+
} catch (ReflectionIsTemporaryException e) {
172+
Log.e(LOG_TAG, "Failed to invoke removeCrossProfileCalendarPackage", e);
173+
}
174+
})
175+
.setNegativeButton(android.R.string.cancel, null)
176+
.show();
177+
}
178+
179+
/**
180+
* Shows a dialog that displays all the packages that have been whitelisted.
181+
*/
182+
private void showListPackageDialog() {
183+
Set<String> packages = new ArraySet<String>();
184+
try {
185+
packages = (Set<String>) ReflectionUtil.invoke(mDevicePolicyManager,
186+
"getCrossProfileCalendarPackages", mAdminComponentName);
187+
} catch (ReflectionIsTemporaryException e) {
188+
Log.e(LOG_TAG, "Failed to invoke getCrossProfileCalendarPackages", e);
189+
}
190+
191+
if (packages.isEmpty()) {
192+
showToast(R.string.cross_profile_calendar_list_package_empty);
193+
} else {
194+
AppInfoArrayAdapter appInfoArrayAdapter = new AppInfoArrayAdapter(getActivity(),
195+
R.id.pkg_name, new ArrayList<String>(packages), true);
196+
new AlertDialog.Builder(getActivity())
197+
.setTitle(getString(R.string.cross_profile_calendar_list_package_title))
198+
.setAdapter(appInfoArrayAdapter, new DialogInterface.OnClickListener() {
199+
@Override
200+
public void onClick(DialogInterface dialog, int position) {
201+
// Do nothing.
202+
}
203+
})
204+
.show();
205+
}
206+
}
207+
208+
private void showToast(int msgId, Object... args) {
209+
showToast(getString(msgId, args), Toast.LENGTH_SHORT);
210+
}
211+
212+
private void showToast(String msg) {
213+
showToast(msg, Toast.LENGTH_SHORT);
214+
}
215+
216+
private void showToast(String msg, int duration) {
217+
Activity activity = getActivity();
218+
if (activity == null || activity.isFinishing()) {
219+
return;
220+
}
221+
Toast.makeText(activity, msg, duration).show();
222+
}
223+
}

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616

1717
package com.afwsamples.testdpc.policy;
1818

19+
import static android.os.UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES;
20+
import static com.afwsamples.testdpc.common.preference.DpcPreferenceHelper.NO_CUSTOM_CONSTRIANT;
21+
1922
import android.accessibilityservice.AccessibilityServiceInfo;
2023
import android.accounts.Account;
2124
import android.accounts.AccountManager;
@@ -150,9 +153,6 @@
150153
import java.util.TimeZone;
151154
import java.util.stream.Collectors;
152155

153-
import static android.os.UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES;
154-
import static com.afwsamples.testdpc.common.preference.DpcPreferenceHelper.NO_CUSTOM_CONSTRIANT;
155-
156156
/**
157157
* Provides several device management functions.
158158
*
@@ -359,6 +359,7 @@ public class PolicyManagementFragment extends BaseSearchablePolicyPreferenceFrag
359359

360360
private static final String SET_SCREEN_BRIGHTNESS_KEY = "set_screen_brightness";
361361
private static final String AUTO_BRIGHTNESS_KEY = "auto_brightness";
362+
private static final String CROSS_PROFILE_CALENDAR_KEY = "cross_profile_calendar";
362363
private static final String SET_SCREEN_OFF_TIMEOUT_KEY = "set_screen_off_timeout";
363364

364365
private static final String SET_TIME_KEY = "set_time";
@@ -615,6 +616,8 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
615616

616617
findPreference(MANAGE_OVERRIDE_APN_KEY).setOnPreferenceClickListener(this);
617618

619+
findPreference(CROSS_PROFILE_CALENDAR_KEY).setOnPreferenceClickListener(this);
620+
618621
DpcPreference bindDeviceAdminPreference =
619622
(DpcPreference) findPreference(BIND_DEVICE_ADMIN_POLICIES);
620623
bindDeviceAdminPreference.setCustomConstraint(
@@ -1046,6 +1049,9 @@ public void onPositiveButtonClicked(String[] lockTaskArray) {
10461049
case MANAGE_OVERRIDE_APN_KEY:
10471050
showFragment(new OverrideApnFragment());
10481051
return true;
1052+
case CROSS_PROFILE_CALENDAR_KEY:
1053+
showFragment(new CrossProfileCalendarFragment());
1054+
return true;
10491055
}
10501056
return false;
10511057
}

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,15 @@
242242
<string name="apn_wrong_inetaddress">Cannot parse proxy address or MMS proxy address</string>
243243
<string name="apn_wrong_port">Cannot parse proxy port or MMS proxy port</string>
244244

245+
<!-- Strings for Cross Profile Calendar -->
246+
<string name="cross_profile_calendar">Cross-profile calendar</string>
247+
<string name="cross_profile_calendar_add_package">Whitelist a package</string>
248+
<string name="cross_profile_calendar_delete_package">Remove a package from whitelist</string>
249+
<string name="cross_profile_calendar_list_package">View all whitelisted packages</string>
250+
<string name="cross_profile_calendar_list_package_empty">No package in the whitelist</string>
251+
<string name="cross_profile_calendar_list_package_title">Cross-profile calendar whitelist</string>
252+
<string name="cross_profile_calendar_no_package">Please enter a package name</string>
253+
245254
<string-array name="apn_auth_type_choices">
246255
<item>Not specified</item>
247256
<!-- Do not translate. -->
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
Copyright (C) 2018 The Android Open Source Project
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
17+
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
18+
xmlns:testdpc="http://schemas.android.com/apk/res-auto"
19+
android:title="@string/cross_profile_calendar">
20+
<PreferenceCategory android:title="@string/cross_profile_calendar">
21+
<com.afwsamples.testdpc.common.preference.DpcPreference
22+
android:key="cross_profile_calendar_add_package"
23+
android:title="@string/cross_profile_calendar_add_package"
24+
testdpc:admin="profileOwner"
25+
testdpc:minSdkVersion="Q"/>
26+
<com.afwsamples.testdpc.common.preference.DpcPreference
27+
android:key="cross_profile_calendar_delete_package"
28+
android:title="@string/cross_profile_calendar_delete_package"
29+
testdpc:admin="profileOwner"
30+
testdpc:minSdkVersion="Q"/>
31+
<com.afwsamples.testdpc.common.preference.DpcPreference
32+
android:key="cross_profile_calendar_list_package"
33+
android:title="@string/cross_profile_calendar_list_package"
34+
testdpc:admin="profileOwner"
35+
testdpc:minSdkVersion="Q"/>
36+
</PreferenceCategory>
37+
</PreferenceScreen>

app/src/main/res/xml/device_policy_header.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,14 @@
7272
testdpc:minSdkVersion="P" />
7373
</PreferenceCategory>
7474

75+
<PreferenceCategory android:title="@string/cross_profile_calendar">
76+
<com.afwsamples.testdpc.common.preference.DpcPreference
77+
android:key="cross_profile_calendar"
78+
android:title="@string/cross_profile_calendar"
79+
testdpc:admin="any"
80+
testdpc:minSdkVersion="Q" />
81+
</PreferenceCategory>
82+
7583
<PreferenceCategory android:title="@string/account_management_title">
7684
<com.afwsamples.testdpc.common.preference.DpcPreference
7785
android:key="set_disable_account_management"

0 commit comments

Comments
 (0)