Skip to content

Commit ec83ab1

Browse files
author
android-build-team Robot
committed
Snap for 6833135 from 7905bce6ca7f576a4feb8b3c01986a3b55667f6e to ub-testdpc-rvc-release
Change-Id: I1ffc878b9028a1e368fff590685f700bffd4a00f
2 parents 341e119 + cb954fb commit ec83ab1

17 files changed

+319
-204
lines changed

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ ext {
99
// exactly 1 digit
1010
versionMinor = 0
1111
// exactly 2 digits
12-
versionBuild = 01
12+
versionBuild = 02
1313
}
1414

1515
android {

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@
3131
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
3232
<uses-permission android:name="android.permission.REQUEST_PASSWORD_COMPLEXITY"/>
3333
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
34+
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
3435

3536
<application
3637
android:allowBackup="true"
3738
android:icon="@drawable/ic_launcher"
39+
android:banner="@drawable/ic_launcher"
3840
android:theme="@style/AppTheme"
3941
android:label="@string/app_name">
4042

@@ -47,6 +49,10 @@
4749
<action android:name="android.intent.action.MAIN"/>
4850
<category android:name="android.intent.category.LAUNCHER"/>
4951
</intent-filter>
52+
<intent-filter>
53+
<action android:name="android.intent.action.MAIN"/>
54+
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
55+
</intent-filter>
5056
<intent-filter>
5157
<action android:name="android.app.action.CHECK_POLICY_COMPLIANCE"/>
5258
<category android:name="android.intent.category.DEFAULT"/>
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright (C) 2020 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+
package com.afwsamples.testdpc;
17+
18+
import android.annotation.TargetApi;
19+
import android.app.Fragment;
20+
import android.app.admin.DevicePolicyManager;
21+
import android.content.ComponentName;
22+
import android.os.Build.VERSION_CODES;
23+
import android.os.Bundle;
24+
import android.view.LayoutInflater;
25+
import android.view.View;
26+
import android.view.ViewGroup;
27+
import android.widget.Button;
28+
import android.widget.EditText;
29+
import android.widget.TextView;
30+
import java.util.Collections;
31+
import java.util.Set;
32+
33+
/**
34+
* This fragment provides the ability to whitelist cross profile packages
35+
*
36+
* <p>APIs exercised:
37+
* <ul>
38+
* <li> {@link DevicePolicyManager#setCrossProfilePackages(ComponentName, Set)} </li>
39+
* <li> {@link DevicePolicyManager#getCrossProfilePackages(ComponentName)} </li>
40+
* </ul>
41+
*/
42+
@TargetApi(VERSION_CODES.R)
43+
public class CrossProfileAppsWhitelistFragment extends Fragment {
44+
private static final String DELIMITER = "\n";
45+
46+
private View mInflatedView;
47+
private EditText mAppNameEditText;
48+
private Button mResetButton;
49+
private Button mAddButton;
50+
private Button mRemoveButton;
51+
private TextView mAppsList;
52+
53+
private DevicePolicyManager mDevicePolicyManager;
54+
private ComponentName mAdminComponent;
55+
56+
@Override
57+
public View onCreateView(LayoutInflater inflater, ViewGroup container,
58+
Bundle savedInstanceState) {
59+
mDevicePolicyManager = getActivity().getSystemService(DevicePolicyManager.class);
60+
mAdminComponent = DeviceAdminReceiver.getComponentName(getActivity());
61+
mInflatedView = inflater.inflate(
62+
R.layout.cross_profile_apps_whitelist, container, false);
63+
64+
mAppNameEditText = mInflatedView.findViewById(R.id.cross_profile_app_whitelist_input);
65+
mResetButton = mInflatedView.findViewById(R.id.cross_profile_app_whitelist_reset_button);
66+
mAddButton = mInflatedView.findViewById(R.id.cross_profile_app_whitelist_add_button);
67+
mRemoveButton = mInflatedView.findViewById(R.id.cross_profile_app_whitelist_remove_button);
68+
mAppsList = mInflatedView.findViewById(R.id.cross_profile_app_list);
69+
70+
setOnClickListeners();
71+
updateCrossProfileAppsList();
72+
73+
return mInflatedView;
74+
}
75+
76+
private void setOnClickListeners() {
77+
mResetButton.setOnClickListener(view -> resetApps());
78+
mAddButton.setOnClickListener(
79+
view -> addApp(mAppNameEditText.getText().toString().toLowerCase().trim()));
80+
mRemoveButton.setOnClickListener(
81+
view -> removeApp(mAppNameEditText.getText().toString().toLowerCase().trim()));
82+
}
83+
84+
private void resetApps() {
85+
mDevicePolicyManager.setCrossProfilePackages(mAdminComponent, Collections.emptySet());
86+
updateCrossProfileAppsList();
87+
}
88+
89+
private void addApp(String app) {
90+
Set<String> currentApps = mDevicePolicyManager.getCrossProfilePackages(mAdminComponent);
91+
currentApps.add(app);
92+
mDevicePolicyManager.setCrossProfilePackages(mAdminComponent, currentApps);
93+
updateCrossProfileAppsList();
94+
}
95+
96+
private void removeApp(String app) {
97+
Set<String> currentApps = mDevicePolicyManager.getCrossProfilePackages(mAdminComponent);
98+
currentApps.remove(app);
99+
mDevicePolicyManager.setCrossProfilePackages(mAdminComponent, currentApps);
100+
updateCrossProfileAppsList();
101+
}
102+
103+
private void updateCrossProfileAppsList(){
104+
Set<String> currentApps = mDevicePolicyManager.getCrossProfilePackages(mAdminComponent);
105+
if (currentApps.isEmpty()) {
106+
mAppsList.setText(R.string.cross_profile_apps_no_whitelisted_apps);
107+
} else {
108+
mAppsList.setText(String.join(DELIMITER, currentApps));
109+
}
110+
}
111+
}

app/src/main/java/com/afwsamples/testdpc/common/ProfileOrParentFragment.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public void onCreate(Bundle savedInstanceState) {
6161
public View onCreateView(
6262
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
6363
FragmentTabHost tabHost = new FragmentTabHost(getActivity());
64-
tabHost.setup(getActivity(), getChildFragmentManager(), View.generateViewId());
64+
tabHost.setup(getActivity(), getChildFragmentManager(), container.getId());
6565

6666
final boolean showDualTabs =
6767
Util.isManagedProfileOwner(getActivity())

app/src/main/java/com/afwsamples/testdpc/common/Util.java

Lines changed: 18 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,18 @@
1818

1919
import android.annotation.TargetApi;
2020
import android.app.Service;
21+
import android.app.UiModeManager;
2122
import android.app.admin.DevicePolicyManager;
2223
import android.content.ActivityNotFoundException;
2324
import android.content.ComponentName;
2425
import android.content.Context;
2526
import android.content.Intent;
2627
import android.content.IntentFilter;
28+
import android.content.res.Configuration;
2729
import android.graphics.BitmapFactory;
2830
import android.net.Uri;
2931
import android.os.Build.VERSION;
3032
import android.os.Build.VERSION_CODES;
31-
import android.os.Bundle;
3233
import android.os.UserHandle;
3334
import android.os.UserManager;
3435
import androidx.preference.PreferenceFragment;
@@ -52,11 +53,6 @@ public class Util {
5253
private static final String TAG = "Util";
5354
private static final int DEFAULT_BUFFER_SIZE = 4096;
5455

55-
private static final String BROADCAST_ACTION_FRP_CONFIG_CHANGED =
56-
"com.google.android.gms.auth.FRP_CONFIG_CHANGED";
57-
private static final String GMSCORE_PACKAGE = "com.google.android.gms";
58-
private static final String PERSISTENT_DEVICE_OWNER_STATE = "persistentDeviceOwnerState";
59-
6056
// TODO: Update to S when VERSION_CODES.R becomes available.
6157
public static final int R_VERSION_CODE = 30;
6258

@@ -203,42 +199,6 @@ public static boolean installCaCertificate(InputStream certificateInputStream,
203199
return false;
204200
}
205201

206-
/**
207-
* Returns the persistent device owner state which has been set by the device owner as an app
208-
* restriction on GmsCore or null if there is no such restriction set.
209-
*/
210-
@TargetApi(VERSION_CODES.O)
211-
public static String getPersistentDoStateFromApplicationRestriction(
212-
DevicePolicyManager dpm, ComponentName admin) {
213-
Bundle restrictions = dpm.getApplicationRestrictions(admin, GMSCORE_PACKAGE);
214-
return restrictions.getString(PERSISTENT_DEVICE_OWNER_STATE);
215-
}
216-
217-
/**
218-
* Sets the persistent device owner state by setting a special app restriction on GmsCore and
219-
* notifies GmsCore about the change by sending a broadcast.
220-
*
221-
* @param state The device owner state to be preserved across factory resets. If null, the
222-
* persistent device owner state and the corresponding restiction are cleared.
223-
*/
224-
@TargetApi(VERSION_CODES.O)
225-
public static void setPersistentDoStateWithApplicationRestriction(
226-
Context context, DevicePolicyManager dpm, ComponentName admin, String state) {
227-
Bundle restrictions = dpm.getApplicationRestrictions(admin, GMSCORE_PACKAGE);
228-
if (state == null) {
229-
// Clear the restriction
230-
restrictions.remove(PERSISTENT_DEVICE_OWNER_STATE);
231-
} else {
232-
// Set the restriction
233-
restrictions.putString(PERSISTENT_DEVICE_OWNER_STATE, state);
234-
}
235-
dpm.setApplicationRestrictions(admin, GMSCORE_PACKAGE, restrictions);
236-
Intent broadcastIntent = new Intent(BROADCAST_ACTION_FRP_CONFIG_CHANGED);
237-
broadcastIntent.setPackage(GMSCORE_PACKAGE);
238-
broadcastIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
239-
context.sendBroadcast(broadcastIntent);
240-
}
241-
242202
/** @return Intent for the default home activity */
243203
public static Intent getHomeIntent() {
244204
final Intent intent = new Intent(Intent.ACTION_MAIN);
@@ -255,6 +215,17 @@ public static IntentFilter getHomeIntentFilter() {
255215
return filter;
256216
}
257217

218+
/** @return Intent for a launcher activity */
219+
public static Intent getLauncherIntent(Context context) {
220+
Intent launcherIntent = new Intent(Intent.ACTION_MAIN);
221+
if (Util.isRunningOnTvDevice(context)) {
222+
launcherIntent.addCategory(Intent.CATEGORY_LEANBACK_LAUNCHER);
223+
} else {
224+
launcherIntent.addCategory(Intent.CATEGORY_LAUNCHER);
225+
}
226+
return launcherIntent;
227+
}
228+
258229
private static DevicePolicyManager getDevicePolicyManager(Context context) {
259230
return (DevicePolicyManager)context.getSystemService(Service.DEVICE_POLICY_SERVICE);
260231
}
@@ -266,4 +237,9 @@ public static boolean hasDelegation(Context context, String delegation) {
266237
DevicePolicyManager dpm = context.getSystemService(DevicePolicyManager.class);
267238
return dpm.getDelegatedScopes(null, context.getPackageName()).contains(delegation);
268239
}
240+
241+
public static boolean isRunningOnTvDevice(Context context) {
242+
UiModeManager uiModeManager = (UiModeManager) context.getSystemService(Context.UI_MODE_SERVICE);
243+
return uiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_TELEVISION;
244+
}
269245
}

app/src/main/java/com/afwsamples/testdpc/common/keyvaluepair/KeyValueBundleArrayFragment.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.ArrayList;
3434
import java.util.Arrays;
3535
import java.util.List;
36+
import java.util.Set;
3637

3738
import static com.afwsamples.testdpc.common.EditDeleteArrayAdapter.OnDeleteButtonClickListener;
3839
import static com.afwsamples.testdpc.common.EditDeleteArrayAdapter.OnEditButtonClickListener;
@@ -130,10 +131,32 @@ protected void saveConfig() {
130131
@Override
131132
protected void addNewRow() {
132133
Bundle bundle = new Bundle();
134+
135+
if (mBundleList != null && mBundleList.size() > 0) {
136+
bundle = clearBundleValues((Bundle) mBundleList.get(0).clone());
137+
}
138+
133139
mAdapter.add(bundle);
134140
showEditDialog(bundle);
135141
}
136142

143+
private Bundle clearBundleValues(Bundle bundle) {
144+
Set<String> keySet = bundle.keySet();
145+
for(String key : keySet) {
146+
Object valueObject = bundle.get(key);
147+
if(valueObject instanceof String) {
148+
bundle.putString(key, "");
149+
} else if(valueObject instanceof Integer) {
150+
bundle.putInt(key, 0);
151+
} else if(valueObject instanceof Boolean) {
152+
bundle.putBoolean(key, false);
153+
} else if(valueObject instanceof Bundle) {
154+
bundle.putBundle(key, clearBundleValues((Bundle) valueObject));
155+
}
156+
}
157+
return bundle;
158+
}
159+
137160
@Override
138161
protected void loadDefault() {}
139162

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

Lines changed: 0 additions & 77 deletions
This file was deleted.

0 commit comments

Comments
 (0)