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