• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.apprestrictionenforcer;
18 
19 import android.app.Activity;
20 import android.app.admin.DevicePolicyManager;
21 import android.content.Context;
22 import android.content.RestrictionEntry;
23 import android.content.RestrictionsManager;
24 import android.content.SharedPreferences;
25 import android.content.pm.ApplicationInfo;
26 import android.content.pm.PackageManager;
27 import android.os.Bundle;
28 import android.support.annotation.Nullable;
29 import android.support.v4.app.Fragment;
30 import android.view.LayoutInflater;
31 import android.view.View;
32 import android.view.ViewGroup;
33 import android.widget.Button;
34 import android.widget.CompoundButton;
35 import android.widget.Switch;
36 import android.widget.TextView;
37 import android.widget.Toast;
38 
39 import java.util.List;
40 
41 /**
42  * This fragment provides UI and functionality to set restrictions on the AppRestrictionSchema
43  * sample.
44  */
45 public class AppRestrictionEnforcerFragment extends Fragment implements View.OnClickListener,
46         CompoundButton.OnCheckedChangeListener {
47 
48     /**
49      * Package name of the AppRestrictionSchema sample.
50      */
51     private static final String PACKAGE_NAME_APP_RESTRICTION_SCHEMA
52             = "com.example.android.apprestrictionschema";
53 
54     /**
55      * Key for {@link SharedPreferences}
56      */
57     private static final String PREFS_KEY = "AppRestrictionEnforcerFragment";
58 
59     /**
60      * Key for the boolean restriction in AppRestrictionSchema.
61      */
62     private static final String RESTRICTION_KEY_SAY_HELLO = "can_say_hello";
63 
64     /**
65      * Default boolean value for "can_say_hello" restriction. The actual value is loaded in
66      * {@link #loadRestrictions(android.app.Activity)}.
67      */
68     private boolean mDefaultValueRestrictionSayHello;
69 
70     // UI Components
71     private TextView mTextStatus;
72     private Button mButtonUnhide;
73     private Switch mSwitchSayHello;
74 
75     @Override
onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)76     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
77                              @Nullable Bundle savedInstanceState) {
78         return inflater.inflate(R.layout.fragment_app_restriction_enforcer, container, false);
79     }
80 
81     @Override
onViewCreated(View view, @Nullable Bundle savedInstanceState)82     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
83         mTextStatus = (TextView) view.findViewById(R.id.status);
84         mButtonUnhide = (Button) view.findViewById(R.id.unhide);
85         mSwitchSayHello = (Switch) view.findViewById(R.id.say_hello);
86         mButtonUnhide.setOnClickListener(this);
87         mSwitchSayHello.setOnCheckedChangeListener(this);
88     }
89 
90     @Override
onResume()91     public void onResume() {
92         super.onResume();
93         updateUi(getActivity());
94     }
95 
96     @Override
onClick(View view)97     public void onClick(View view) {
98         switch (view.getId()) {
99             case R.id.unhide: {
100                 unhideApp(getActivity());
101                 break;
102             }
103         }
104     }
105 
106     @Override
onCheckedChanged(CompoundButton compoundButton, boolean checked)107     public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
108         switch (compoundButton.getId()) {
109             case R.id.say_hello: {
110                 allowSayHello(getActivity(), checked);
111                 break;
112             }
113         }
114     }
115 
116     /**
117      * Updates the UI components according to the current status of AppRestrictionSchema and its
118      * restriction.
119      *
120      * @param activity The activity
121      */
updateUi(Activity activity)122     private void updateUi(Activity activity) {
123         PackageManager packageManager = activity.getPackageManager();
124         try {
125             ApplicationInfo info = packageManager.getApplicationInfo(
126                     PACKAGE_NAME_APP_RESTRICTION_SCHEMA, PackageManager.GET_UNINSTALLED_PACKAGES);
127             DevicePolicyManager devicePolicyManager =
128                     (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
129             if (0 < (info.flags & ApplicationInfo.FLAG_INSTALLED)) {
130                 if (!devicePolicyManager.isApplicationHidden(
131                         EnforcerDeviceAdminReceiver.getComponentName(activity),
132                         PACKAGE_NAME_APP_RESTRICTION_SCHEMA)) {
133                     // The app is ready
134                     loadRestrictions(activity);
135                     mTextStatus.setVisibility(View.GONE);
136                     mButtonUnhide.setVisibility(View.GONE);
137                     mSwitchSayHello.setVisibility(View.VISIBLE);
138                     mSwitchSayHello.setOnCheckedChangeListener(null);
139                     mSwitchSayHello.setChecked(canSayHello(activity));
140                     mSwitchSayHello.setOnCheckedChangeListener(this);
141                 } else {
142                     // The app is installed but hidden in this profile
143                     mTextStatus.setText(R.string.status_not_activated);
144                     mTextStatus.setVisibility(View.VISIBLE);
145                     mButtonUnhide.setVisibility(View.VISIBLE);
146                     mSwitchSayHello.setVisibility(View.GONE);
147                 }
148             } else {
149                 // Need to reinstall the sample app
150                 mTextStatus.setText(R.string.status_need_reinstall);
151                 mTextStatus.setVisibility(View.VISIBLE);
152                 mButtonUnhide.setVisibility(View.GONE);
153                 mSwitchSayHello.setVisibility(View.GONE);
154             }
155         } catch (PackageManager.NameNotFoundException e) {
156             mTextStatus.setText(R.string.status_not_installed);
157             mTextStatus.setVisibility(View.VISIBLE);
158             mButtonUnhide.setVisibility(View.GONE);
159             mSwitchSayHello.setVisibility(View.GONE);
160         }
161     }
162 
163     /**
164      * Unhides the AppRestrictionSchema sample in case it is hidden in this profile.
165      *
166      * @param activity The activity
167      */
unhideApp(Activity activity)168     private void unhideApp(Activity activity) {
169         DevicePolicyManager devicePolicyManager =
170                 (DevicePolicyManager) activity.getSystemService(Activity.DEVICE_POLICY_SERVICE);
171         devicePolicyManager.setApplicationHidden(
172                 EnforcerDeviceAdminReceiver.getComponentName(activity),
173                 PACKAGE_NAME_APP_RESTRICTION_SCHEMA, false);
174         Toast.makeText(activity, "Enabled the app", Toast.LENGTH_SHORT).show();
175         updateUi(activity);
176     }
177 
178     /**
179      * Loads the restrictions for the AppRestrictionSchema sample. In this implementation, we just
180      * read the default value for the "can_say_hello" restriction.
181      *
182      * @param activity The activity
183      */
loadRestrictions(Activity activity)184     private void loadRestrictions(Activity activity) {
185         RestrictionsManager restrictionsManager =
186                 (RestrictionsManager) activity.getSystemService(Context.RESTRICTIONS_SERVICE);
187         List<RestrictionEntry> restrictions =
188                 restrictionsManager.getManifestRestrictions(PACKAGE_NAME_APP_RESTRICTION_SCHEMA);
189         for (RestrictionEntry restriction : restrictions) {
190             if (RESTRICTION_KEY_SAY_HELLO.equals(restriction.getKey())) {
191                 mDefaultValueRestrictionSayHello = restriction.getSelectedState();
192             }
193         }
194     }
195 
196     /**
197      * Returns whether the AppRestrictionSchema is currently allowed to say hello to its user. Note
198      * that a profile/device owner needs to remember each restriction value on its own.
199      *
200      * @param activity The activity
201      * @return True if the AppRestrictionSchema is allowed to say hello
202      */
canSayHello(Activity activity)203     private boolean canSayHello(Activity activity) {
204         SharedPreferences prefs = activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
205         return prefs.getBoolean(RESTRICTION_KEY_SAY_HELLO, mDefaultValueRestrictionSayHello);
206     }
207 
208     /**
209      * Sets the value for the "cay_say_hello" restriction of AppRestrictionSchema.
210      *
211      * @param activity The activity
212      * @param allow    The value to be set for the restriction.
213      */
allowSayHello(Activity activity, boolean allow)214     private void allowSayHello(Activity activity, boolean allow) {
215         DevicePolicyManager devicePolicyManager
216                 = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
217         Bundle restrictions = new Bundle();
218         restrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, allow);
219         devicePolicyManager.setApplicationRestrictions(
220                 EnforcerDeviceAdminReceiver.getComponentName(activity),
221                 PACKAGE_NAME_APP_RESTRICTION_SCHEMA, restrictions);
222         // The profile/device owner needs to remember the current state of restrictions on its own
223         activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE)
224                 .edit()
225                 .putBoolean(RESTRICTION_KEY_SAY_HELLO, allow)
226                 .apply();
227         Toast.makeText(activity, allow ? R.string.allowed : R.string.disallowed,
228                 Toast.LENGTH_SHORT).show();
229     }
230 
231 }
232