Skip to content

Most visited

Recently visited

navigation
BasicManagedProfile / src / com.example.android.basicmanagedprofile /

BasicManagedProfileFragment.java

1
/*
2
 * Copyright (C) 2014 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.example.android.basicmanagedprofile;
18
 
19
import android.app.Activity;
20
import android.app.AlertDialog;
21
import android.app.Fragment;
22
import android.app.admin.DevicePolicyManager;
23
import android.content.ActivityNotFoundException;
24
import android.content.Context;
25
import android.content.DialogInterface;
26
import android.content.Intent;
27
import android.content.IntentFilter;
28
import android.content.pm.ApplicationInfo;
29
import android.content.pm.PackageManager;
30
import android.os.Bundle;
31
import android.util.Log;
32
import android.view.LayoutInflater;
33
import android.view.View;
34
import android.view.ViewGroup;
35
import android.widget.Button;
36
import android.widget.CompoundButton;
37
import android.widget.ScrollView;
38
import android.widget.Switch;
39
import android.widget.TextView;
40
import android.widget.Toast;
41
 
42
import static android.app.admin.DevicePolicyManager.FLAG_MANAGED_CAN_ACCESS_PARENT;
43
import static android.app.admin.DevicePolicyManager.FLAG_PARENT_CAN_ACCESS_MANAGED;
44
 
45
/**
46
 * Provides several functions that are available in a managed profile. This includes
47
 * enabling/disabling other apps, setting app restrictions, enabling/disabling intent forwarding,
48
 * and wiping out all the data in the profile.
49
 */
50
public class BasicManagedProfileFragment extends Fragment
51
        implements View.OnClickListener,
52
        CompoundButton.OnCheckedChangeListener {
53
 
54
    /**
55
     * Tag for logging.
56
     */
57
    private static final String TAG = "BasicManagedProfileFragment";
58
 
59
    /**
60
     * Package name of calculator
61
     */
62
    private static final String PACKAGE_NAME_CALCULATOR = "com.android.calculator2";
63
 
64
    /**
65
     * Package name of Chrome
66
     */
67
    private static final String PACKAGE_NAME_CHROME = "com.android.chrome";
68
 
69
    /**
70
     * {@link Button} to remove this managed profile.
71
     */
72
    private Button mButtonRemoveProfile;
73
 
74
    /**
75
     * Whether the calculator app is enabled in this profile
76
     */
77
    private boolean mCalculatorEnabled;
78
 
79
    /**
80
     * Whether Chrome is enabled in this profile
81
     */
82
    private boolean mChromeEnabled;
83
 
84
    public BasicManagedProfileFragment() {
85
    }
86
 
87
    public static BasicManagedProfileFragment newInstance() {
88
        return new BasicManagedProfileFragment();
89
    }
90
 
91
    @Override
92
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
93
                             Bundle savedInstanceState) {
94
        return inflater.inflate(R.layout.fragment_main, container, false);
95
    }
96
 
97
    @Override
98
    public void onAttach(Activity activity) {
99
        super.onAttach(activity);
100
        // Retrieves whether the calculator app is enabled in this profile
101
        mCalculatorEnabled = isApplicationEnabled(PACKAGE_NAME_CALCULATOR);
102
        // Retrieves whether Chrome is enabled in this profile
103
        mChromeEnabled = isApplicationEnabled(PACKAGE_NAME_CHROME);
104
    }
105
 
106
    /**
107
     * Checks if the application is available in this profile.
108
     *
109
     * @param packageName The package name
110
     * @return True if the application is available in this profile.
111
     */
112
    private boolean isApplicationEnabled(String packageName) {
113
        Activity activity = getActivity();
114
        PackageManager packageManager = activity.getPackageManager();
115
        try {
116
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(
117
                    packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
118
            // Return false if the app is not installed in this profile
119
            if (0 == (applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)) {
120
                return false;
121
            }
122
            // Check if the app is not hidden in this profile
123
            DevicePolicyManager devicePolicyManager =
124
                    (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
125
            return !devicePolicyManager.isApplicationHidden(
126
                    BasicDeviceAdminReceiver.getComponentName(activity), packageName);
127
        } catch (PackageManager.NameNotFoundException e) {
128
            return false;
129
        }
130
    }
131
 
132
    @Override
133
    public void onViewCreated(View view, Bundle savedInstanceState) {
134
        // Bind event listeners and initial states
135
        view.findViewById(R.id.set_chrome_restrictions).setOnClickListener(this);
136
        view.findViewById(R.id.clear_chrome_restrictions).setOnClickListener(this);
137
        view.findViewById(R.id.enable_forwarding).setOnClickListener(this);
138
        view.findViewById(R.id.disable_forwarding).setOnClickListener(this);
139
        view.findViewById(R.id.send_intent).setOnClickListener(this);
140
        mButtonRemoveProfile = (Button) view.findViewById(R.id.remove_profile);
141
        mButtonRemoveProfile.setOnClickListener(this);
142
        Switch toggleCalculator = (Switch) view.findViewById(R.id.toggle_calculator);
143
        toggleCalculator.setChecked(mCalculatorEnabled);
144
        toggleCalculator.setOnCheckedChangeListener(this);
145
        Switch toggleChrome = (Switch) view.findViewById(R.id.toggle_chrome);
146
        toggleChrome.setChecked(mChromeEnabled);
147
        toggleChrome.setOnCheckedChangeListener(this);
148
    }
149
 
150
    @Override
151
    public void onClick(View view) {
152
        switch (view.getId()) {
153
            case R.id.set_chrome_restrictions: {
154
                setChromeRestrictions();
155
                break;
156
            }
157
            case R.id.clear_chrome_restrictions: {
158
                clearChromeRestrictions();
159
                break;
160
            }
161
            case R.id.enable_forwarding: {
162
                enableForwarding();
163
                break;
164
            }
165
            case R.id.disable_forwarding: {
166
                disableForwarding();
167
                break;
168
            }
169
            case R.id.send_intent: {
170
                sendIntent();
171
                break;
172
            }
173
            case R.id.remove_profile: {
174
                mButtonRemoveProfile.setEnabled(false);
175
                removeProfile();
176
                break;
177
            }
178
        }
179
    }
180
 
181
    @Override
182
    public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
183
        switch (compoundButton.getId()) {
184
            case R.id.toggle_calculator: {
185
                setAppEnabled(PACKAGE_NAME_CALCULATOR, checked);
186
                mCalculatorEnabled = checked;
187
                break;
188
            }
189
            case R.id.toggle_chrome: {
190
                setAppEnabled(PACKAGE_NAME_CHROME, checked);
191
                mChromeEnabled = checked;
192
                break;
193
            }
194
        }
195
    }
196
 
197
    /**
198
     * Enables or disables the specified app in this profile.
199
     *
200
     * @param packageName The package name of the target app.
201
     * @param enabled     Pass true to enable the app.
202
     */
203
    private void setAppEnabled(String packageName, boolean enabled) {
204
        Activity activity = getActivity();
205
        if (null == activity) {
206
            return;
207
        }
208
        PackageManager packageManager = activity.getPackageManager();
209
        DevicePolicyManager devicePolicyManager =
210
                (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
211
        try {
212
            ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName,
213
                    PackageManager.GET_UNINSTALLED_PACKAGES);
214
            // Here, we check the ApplicationInfo of the target app, and see if the flags have
215
            // ApplicationInfo.FLAG_INSTALLED turned on using bitwise operation.
216
            if (0 == (applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED)) {
217
                // If the app is not installed in this profile, we can enable it by
218
                // DPM.enableSystemApp
219
                if (enabled) {
220
                    devicePolicyManager.enableSystemApp(
221
                            BasicDeviceAdminReceiver.getComponentName(activity), packageName);
222
                } else {
223
                    // But we cannot disable the app since it is already disabled
224
                    Log.e(TAG, "Cannot disable this app: " + packageName);
225
                    return;
226
                }
227
            } else {
228
                // If the app is already installed, we can enable or disable it by
229
                // DPM.setApplicationHidden
230
                devicePolicyManager.setApplicationHidden(
231
                        BasicDeviceAdminReceiver.getComponentName(activity), packageName, !enabled);
232
            }
233
            Toast.makeText(activity, enabled ? R.string.enabled : R.string.disabled,
234
                    Toast.LENGTH_SHORT).show();
235
        } catch (PackageManager.NameNotFoundException e) {
236
            Log.e(TAG, "The app cannot be found: " + packageName, e);
237
        }
238
    }
239
 
240
    /**
241
     * Sets restrictions to Chrome
242
     */
243
    private void setChromeRestrictions() {
244
        final Activity activity = getActivity();
245
        if (null == activity) {
246
            return;
247
        }
248
        final DevicePolicyManager manager =
249
            (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
250
        final Bundle settings = new Bundle();
251
        settings.putString("EditBookmarksEnabled", "false");
252
        settings.putString("IncognitoModeAvailability", "1");
253
        settings.putString("ManagedBookmarks",
254
                           "[{\"name\": \"Chromium\", \"url\": \"http://chromium.org\"}, " +
255
                           "{\"name\": \"Google\", \"url\": \"https://www.google.com\"}]");
256
        settings.putString("DefaultSearchProviderEnabled", "true");
257
        settings.putString("DefaultSearchProviderName", "\"LMGTFY\"");
258
        settings.putString("DefaultSearchProviderSearchURL",
259
                "\"http://lmgtfy.com/?q={searchTerms}\"");
260
        settings.putString("URLBlacklist", "[\"example.com\", \"example.org\"]");
261
        StringBuilder message = new StringBuilder("Setting Chrome restrictions:");
262
        for (String key : settings.keySet()) {
263
            message.append("\n");
264
            message.append(key);
265
            message.append(": ");
266
            message.append(settings.getString(key));
267
        }
268
        ScrollView view = new ScrollView(activity);
269
        TextView text = new TextView(activity);
270
        text.setText(message);
271
        int size = (int) activity.getResources().getDimension(R.dimen.activity_horizontal_margin);
272
        view.setPadding(size, size, size, size);
273
        view.addView(text);
274
        new AlertDialog.Builder(activity)
275
                .setView(view)
276
                .setNegativeButton(android.R.string.cancel, null)
277
                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
278
                    @Override
279
                    public void onClick(DialogInterface dialogInterface, int i) {
280
                        // This is how you can set restrictions to an app.
281
                        // The format for settings in Bundle differs from app to app.
282
                        manager.setApplicationRestrictions
283
                                (BasicDeviceAdminReceiver.getComponentName(activity),
284
                                        PACKAGE_NAME_CHROME, settings);
285
                        Toast.makeText(activity, R.string.restrictions_set,
286
                                Toast.LENGTH_SHORT).show();
287
                    }
288
                })
289
                .show();
290
    }
291
 
292
    /**
293
     * Clears restrictions to Chrome
294
     */
295
    private void clearChromeRestrictions() {
296
        final Activity activity = getActivity();
297
        if (null == activity) {
298
            return;
299
        }
300
        final DevicePolicyManager manager =
301
                (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
302
        // In order to clear restrictions, pass null as the restriction Bundle for
303
        // setApplicationRestrictions
304
        manager.setApplicationRestrictions
305
                (BasicDeviceAdminReceiver.getComponentName(activity),
306
                        PACKAGE_NAME_CHROME, null);
307
        Toast.makeText(activity, R.string.cleared, Toast.LENGTH_SHORT).show();
308
    }
309
 
310
    /**
311
     * Enables forwarding of share intent between private account and managed profile.
312
     */
313
    private void enableForwarding() {
314
        Activity activity = getActivity();
315
        if (null == activity || activity.isFinishing()) {
316
            return;