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