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