1 /* 2 * Copyright (C) 2013 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.apprestrictions; 18 19 import android.app.Activity; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.RestrictionEntry; 24 import android.content.res.Resources; 25 import android.os.Bundle; 26 import android.preference.PreferenceManager; 27 import android.util.Log; 28 29 import java.util.ArrayList; 30 31 public class GetRestrictionsReceiver extends BroadcastReceiver { 32 private static final String TAG = GetRestrictionsReceiver.class.getSimpleName(); 33 34 // Keys for referencing app restriction settings from the platform. 35 public static final String KEY_BOOLEAN = "boolean_key"; 36 public static final String KEY_CHOICE = "choice_key"; 37 public static final String KEY_MULTI_SELECT = "multi_key"; 38 39 @Override 40 public void onReceive(final Context context, Intent intent) { 41 final PendingResult result = goAsync(); 42 43 // If app restriction settings are already created, they will be included in the Bundle 44 // as key/value pairs. 45 final Bundle existingRestrictions = 46 intent.getBundleExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE); 47 Log.i(TAG, "existingRestrictions = " + existingRestrictions); 48 49 new Thread() { 50 public void run() { 51 createRestrictions(context, result, existingRestrictions); 52 } 53 }.start(); 54 } 55 56 // Initializes a boolean type restriction entry. 57 public static void populateBooleanEntry(Resources res, RestrictionEntry entry) { 58 entry.setType(RestrictionEntry.TYPE_BOOLEAN); 59 entry.setTitle(res.getString(R.string.boolean_entry_title)); 60 } 61 62 // Initializes a single choice type restriction entry. 63 public static void populateChoiceEntry(Resources res, RestrictionEntry reSingleChoice) { 64 String[] choiceEntries = res.getStringArray(R.array.choice_entry_entries); 65 String[] choiceValues = res.getStringArray(R.array.choice_entry_values); 66 if (reSingleChoice.getSelectedString() == null) { 67 reSingleChoice.setSelectedString(choiceValues[0]); 68 } 69 reSingleChoice.setTitle(res.getString(R.string.choice_entry_title)); 70 reSingleChoice.setChoiceEntries(choiceEntries); 71 reSingleChoice.setChoiceValues(choiceValues); 72 reSingleChoice.setType(RestrictionEntry.TYPE_CHOICE); 73 } 74 75 // Initializes a multi-select type restriction entry. 76 public static void populateMultiEntry(Resources res, RestrictionEntry reMultiSelect) { 77 String[] multiEntries = res.getStringArray(R.array.multi_entry_entries); 78 String[] multiValues = res.getStringArray(R.array.multi_entry_values); 79 if (reMultiSelect.getAllSelectedStrings() == null) { 80 reMultiSelect.setAllSelectedStrings(new String[0]); 81 } 82 reMultiSelect.setTitle(res.getString(R.string.multi_entry_title)); 83 reMultiSelect.setChoiceEntries(multiEntries); 84 reMultiSelect.setChoiceValues(multiValues); 85 reMultiSelect.setType(RestrictionEntry.TYPE_MULTI_SELECT); 86 } 87 88 // Demonstrates the creation of standard app restriction types: boolean, single choice, and 89 // multi-select. 90 private ArrayList<RestrictionEntry> initRestrictions(Context context) { 91 ArrayList<RestrictionEntry> newRestrictions = new ArrayList<RestrictionEntry>(); 92 Resources res = context.getResources(); 93 94 RestrictionEntry reBoolean = new RestrictionEntry(KEY_BOOLEAN, false); 95 populateBooleanEntry(res, reBoolean); 96 newRestrictions.add(reBoolean); 97 98 RestrictionEntry reSingleChoice = new RestrictionEntry(KEY_CHOICE, (String) null); 99 populateChoiceEntry(res, reSingleChoice); 100 newRestrictions.add(reSingleChoice); 101 102 RestrictionEntry reMultiSelect = new RestrictionEntry(KEY_MULTI_SELECT, (String[]) null); 103 populateMultiEntry(res, reMultiSelect); 104 newRestrictions.add(reMultiSelect); 105 106 return newRestrictions; 107 } 108 109 private void createRestrictions(Context context, PendingResult result, 110 Bundle existingRestrictions) { 111 // The incoming restrictions bundle contains key/value pairs representing existing app 112 // restrictions for this package. In order to retain existing app restrictions, you need to 113 // construct new restriction entries and then copy in any existing values for the new keys. 114 ArrayList<RestrictionEntry> newEntries = initRestrictions(context); 115 116 // If app restrictions were not previously configured for the package, create the default 117 // restrictions entries and return them. 118 if (existingRestrictions == null) { 119 Bundle extras = new Bundle(); 120 extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST, newEntries); 121 result.setResult(Activity.RESULT_OK, null, extras); 122 result.finish(); 123 return; 124 } 125 126 // Retains current restriction settings by transferring existing restriction entries to 127 // new ones. 128 for (RestrictionEntry entry : newEntries) { 129 final String key = entry.getKey(); 130 if (KEY_BOOLEAN.equals(key)) { 131 entry.setSelectedState(existingRestrictions.getBoolean(KEY_BOOLEAN)); 132 } else if (KEY_CHOICE.equals(key)) { 133 if (existingRestrictions.containsKey(KEY_CHOICE)) { 134 entry.setSelectedString(existingRestrictions.getString(KEY_CHOICE)); 135 } 136 } else if (KEY_MULTI_SELECT.equals(key)) { 137 if (existingRestrictions.containsKey(KEY_MULTI_SELECT)) { 138 entry.setAllSelectedStrings(existingRestrictions.getStringArray(key)); 139 } 140 } 141 } 142 143 final Bundle extras = new Bundle(); 144 145 // This path demonstrates the use of a custom app restriction activity instead of standard 146 // types. When a custom activity is set, the standard types will not be available under 147 // app restriction settings. 148 // 149 // If your app has an existing activity for app restriction configuration, you can set it 150 // up with the intent here. 151 if (PreferenceManager.getDefaultSharedPreferences(context) 152 .getBoolean(MainActivity.CUSTOM_CONFIG_KEY, false)) { 153 final Intent customIntent = new Intent(); 154 customIntent.setClass(context, CustomRestrictionsActivity.class); 155 extras.putParcelable(Intent.EXTRA_RESTRICTIONS_INTENT, customIntent); 156 } 157 158 extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST, newEntries); 159 result.setResult(Activity.RESULT_OK, null, extras); 160 result.finish(); 161 } 162 } 163