• 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.os.Build;
26 import android.os.Bundle;
27 import android.os.Parcelable;
28 import android.support.annotation.NonNull;
29 import android.support.annotation.Nullable;
30 import android.support.v4.app.Fragment;
31 import android.text.Editable;
32 import android.text.TextUtils;
33 import android.text.TextWatcher;
34 import android.view.LayoutInflater;
35 import android.view.View;
36 import android.view.ViewGroup;
37 import android.widget.AdapterView;
38 import android.widget.ArrayAdapter;
39 import android.widget.Button;
40 import android.widget.CompoundButton;
41 import android.widget.EditText;
42 import android.widget.LinearLayout;
43 import android.widget.Spinner;
44 import android.widget.Switch;
45 import android.widget.TextView;
46 import android.widget.Toast;
47 
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.HashMap;
51 import java.util.List;
52 import java.util.Map;
53 
54 /**
55  * This fragment provides UI and functionality to set restrictions on the AppRestrictionSchema
56  * sample.
57  */
58 public class AppRestrictionEnforcerFragment extends Fragment implements
59         CompoundButton.OnCheckedChangeListener, AdapterView.OnItemSelectedListener,
60         View.OnClickListener, ItemAddFragment.OnItemAddedListener {
61 
62     /**
63      * Key for {@link SharedPreferences}
64      */
65     private static final String PREFS_KEY = "AppRestrictionEnforcerFragment";
66 
67     /**
68      * Key for the boolean restriction in AppRestrictionSchema.
69      */
70     private static final String RESTRICTION_KEY_SAY_HELLO = "can_say_hello";
71 
72     /**
73      * Key for the string restriction in AppRestrictionSchema.
74      */
75     private static final String RESTRICTION_KEY_MESSAGE = "message";
76 
77     /**
78      * Key for the integer restriction in AppRestrictionSchema.
79      */
80     private static final String RESTRICTION_KEY_NUMBER = "number";
81 
82     /**
83      * Key for the choice restriction in AppRestrictionSchema.
84      */
85     private static final String RESTRICTION_KEY_RANK = "rank";
86 
87     /**
88      * Key for the multi-select restriction in AppRestrictionSchema.
89      */
90     private static final String RESTRICTION_KEY_APPROVALS = "approvals";
91 
92     /**
93      * Key for the bundle restriction in AppRestrictionSchema.
94      */
95     private static final String RESTRICTION_KEY_PROFILE = "profile";
96     private static final String RESTRICTION_KEY_PROFILE_NAME = "name";
97     private static final String RESTRICTION_KEY_PROFILE_AGE = "age";
98 
99     /**
100      * Key for the bundle array restriction in AppRestrictionSchema.
101      */
102     private static final String RESTRICTION_KEY_ITEMS = "items";
103     private static final String RESTRICTION_KEY_ITEM_KEY = "key";
104     private static final String RESTRICTION_KEY_ITEM_VALUE = "value";
105 
106     private static final String DELIMETER = ",";
107     private static final String SEPARATOR = ":";
108 
109     private static final boolean BUNDLE_SUPPORTED = Build.VERSION.SDK_INT >= 23;
110 
111     /**
112      * Current status of the restrictions.
113      */
114     private Bundle mCurrentRestrictions = new Bundle();
115 
116     // UI Components
117     private Switch mSwitchSayHello;
118     private EditText mEditMessage;
119     private EditText mEditNumber;
120     private Spinner mSpinnerRank;
121     private LinearLayout mLayoutApprovals;
122     private EditText mEditProfileName;
123     private EditText mEditProfileAge;
124     private LinearLayout mLayoutItems;
125 
126     @Override
onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)127     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
128                              @Nullable Bundle savedInstanceState) {
129         return inflater.inflate(R.layout.fragment_app_restriction_enforcer, container, false);
130     }
131 
132     @Override
onViewCreated(View view, @Nullable Bundle savedInstanceState)133     public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
134         // Retain references for the UI elements
135         mSwitchSayHello = (Switch) view.findViewById(R.id.say_hello);
136         mEditMessage = (EditText) view.findViewById(R.id.message);
137         mEditNumber = (EditText) view.findViewById(R.id.number);
138         mSpinnerRank = (Spinner) view.findViewById(R.id.rank);
139         mLayoutApprovals = (LinearLayout) view.findViewById(R.id.approvals);
140         mEditProfileName = (EditText) view.findViewById(R.id.profile_name);
141         mEditProfileAge = (EditText) view.findViewById(R.id.profile_age);
142         mLayoutItems = (LinearLayout) view.findViewById(R.id.items);
143         view.findViewById(R.id.item_add).setOnClickListener(this);
144         View bundleLayout = view.findViewById(R.id.bundle_layout);
145         View bundleArrayLayout = view.findViewById(R.id.bundle_array_layout);
146         if (BUNDLE_SUPPORTED) {
147             bundleLayout.setVisibility(View.VISIBLE);
148             bundleArrayLayout.setVisibility(View.VISIBLE);
149         } else {
150             bundleLayout.setVisibility(View.GONE);
151             bundleArrayLayout.setVisibility(View.GONE);
152         }
153     }
154 
155     @Override
onResume()156     public void onResume() {
157         super.onResume();
158         loadRestrictions(getActivity());
159     }
160 
161     @Override
onCheckedChanged(CompoundButton compoundButton, boolean checked)162     public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
163         switch (compoundButton.getId()) {
164             case R.id.say_hello: {
165                 saveCanSayHello(getActivity(), checked);
166                 break;
167             }
168             case R.id.approval: {
169                 if (checked) {
170                     addApproval(getActivity(), (String) compoundButton.getTag());
171                 } else {
172                     removeApproval(getActivity(), (String) compoundButton.getTag());
173                 }
174                 break;
175             }
176         }
177     }
178 
179     private TextWatcher mWatcherMessage = new EasyTextWatcher() {
180         @Override
181         public void afterTextChanged(Editable s) {
182             saveMessage(getActivity(), s.toString());
183         }
184     };
185 
186     private TextWatcher mWatcherNumber = new EasyTextWatcher() {
187         @Override
188         public void afterTextChanged(Editable s) {
189             try {
190                 String string = s.toString();
191                 if (!TextUtils.isEmpty(string)) {
192                     saveNumber(getActivity(), Integer.parseInt(string));
193                 }
194             } catch (NumberFormatException e) {
195                 Toast.makeText(getActivity(), "Not an integer!", Toast.LENGTH_SHORT).show();
196             }
197         }
198     };
199 
200     private TextWatcher mWatcherProfile = new EasyTextWatcher() {
201         @Override
202         public void afterTextChanged(Editable s) {
203             try {
204                 String name = mEditProfileName.getText().toString();
205                 String ageString = mEditProfileAge.getText().toString();
206                 if (!TextUtils.isEmpty(ageString)) {
207                     saveProfile(getActivity(), name, Integer.parseInt(ageString));
208                 }
209             } catch (NumberFormatException e) {
210                 Toast.makeText(getActivity(), "Not an integer!", Toast.LENGTH_SHORT).show();
211             }
212         }
213     };
214 
215     @Override
onItemSelected(AdapterView<?> parent, View view, int position, long id)216     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
217         switch (parent.getId()) {
218             case R.id.rank: {
219                 saveRank(getActivity(), (String) parent.getAdapter().getItem(position));
220                 break;
221             }
222         }
223     }
224 
225     @Override
onNothingSelected(AdapterView<?> parent)226     public void onNothingSelected(AdapterView<?> parent) {
227         // Nothing to do
228     }
229 
230     @Override
onClick(View v)231     public void onClick(View v) {
232         switch (v.getId()) {
233             case R.id.item_add:
234                 new ItemAddFragment().show(getChildFragmentManager(), "dialog");
235                 break;
236             case R.id.item_remove:
237                 String key = (String) v.getTag();
238                 removeItem(key);
239                 mLayoutItems.removeView((View) v.getParent());
240                 break;
241         }
242     }
243 
244     @Override
onItemAdded(String key, String value)245     public void onItemAdded(String key, String value) {
246         key = TextUtils.replace(key,
247                 new String[]{DELIMETER, SEPARATOR}, new String[]{"", ""}).toString();
248         value = TextUtils.replace(value,
249                 new String[]{DELIMETER, SEPARATOR}, new String[]{"", ""}).toString();
250         Parcelable[] parcelables = mCurrentRestrictions.getParcelableArray(RESTRICTION_KEY_ITEMS);
251         Map<String, String> items = new HashMap<>();
252         if (parcelables != null) {
253             for (Parcelable parcelable : parcelables) {
254                 Bundle bundle = (Bundle) parcelable;
255                 items.put(bundle.getString(RESTRICTION_KEY_ITEM_KEY),
256                         bundle.getString(RESTRICTION_KEY_ITEM_VALUE));
257             }
258         }
259         items.put(key, value);
260         insertItemRow(LayoutInflater.from(getActivity()), key, value);
261         saveItems(getActivity(), items);
262     }
263 
264     /**
265      * Loads the restrictions for the AppRestrictionSchema sample.
266      *
267      * @param activity The activity
268      */
loadRestrictions(Activity activity)269     private void loadRestrictions(Activity activity) {
270         RestrictionsManager manager =
271                 (RestrictionsManager) activity.getSystemService(Context.RESTRICTIONS_SERVICE);
272         List<RestrictionEntry> restrictions =
273                 manager.getManifestRestrictions(Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA);
274         SharedPreferences prefs = activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE);
275         for (RestrictionEntry restriction : restrictions) {
276             String key = restriction.getKey();
277             if (RESTRICTION_KEY_SAY_HELLO.equals(key)) {
278                 updateCanSayHello(prefs.getBoolean(RESTRICTION_KEY_SAY_HELLO,
279                         restriction.getSelectedState()));
280             } else if (RESTRICTION_KEY_MESSAGE.equals(key)) {
281                 updateMessage(prefs.getString(RESTRICTION_KEY_MESSAGE,
282                         restriction.getSelectedString()));
283             } else if (RESTRICTION_KEY_NUMBER.equals(key)) {
284                 updateNumber(prefs.getInt(RESTRICTION_KEY_NUMBER,
285                         restriction.getIntValue()));
286             } else if (RESTRICTION_KEY_RANK.equals(key)) {
287                 updateRank(activity, restriction.getChoiceValues(),
288                         prefs.getString(RESTRICTION_KEY_RANK, restriction.getSelectedString()));
289             } else if (RESTRICTION_KEY_APPROVALS.equals(key)) {
290                 updateApprovals(activity, restriction.getChoiceValues(),
291                         TextUtils.split(prefs.getString(RESTRICTION_KEY_APPROVALS,
292                                         TextUtils.join(DELIMETER,
293                                                 restriction.getAllSelectedStrings())),
294                                 DELIMETER));
295             } else if (BUNDLE_SUPPORTED && RESTRICTION_KEY_PROFILE.equals(key)) {
296                 String name = null;
297                 int age = 0;
298                 for (RestrictionEntry entry : restriction.getRestrictions()) {
299                     String profileKey = entry.getKey();
300                     if (RESTRICTION_KEY_PROFILE_NAME.equals(profileKey)) {
301                         name = entry.getSelectedString();
302                     } else if (RESTRICTION_KEY_PROFILE_AGE.equals(profileKey)) {
303                         age = entry.getIntValue();
304                     }
305                 }
306                 name = prefs.getString(RESTRICTION_KEY_PROFILE_NAME, name);
307                 age = prefs.getInt(RESTRICTION_KEY_PROFILE_AGE, age);
308                 updateProfile(name, age);
309             } else if (BUNDLE_SUPPORTED && RESTRICTION_KEY_ITEMS.equals(key)) {
310                 String itemsString = prefs.getString(RESTRICTION_KEY_ITEMS, "");
311                 HashMap<String, String> items = new HashMap<>();
312                 for (String itemString : TextUtils.split(itemsString, DELIMETER)) {
313                     String[] strings = itemString.split(SEPARATOR, 2);
314                     items.put(strings[0], strings[1]);
315                 }
316                 updateItems(activity, items);
317             }
318         }
319     }
320 
updateCanSayHello(boolean canSayHello)321     private void updateCanSayHello(boolean canSayHello) {
322         mCurrentRestrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, canSayHello);
323         mSwitchSayHello.setOnCheckedChangeListener(null);
324         mSwitchSayHello.setChecked(canSayHello);
325         mSwitchSayHello.setOnCheckedChangeListener(this);
326     }
327 
updateMessage(String message)328     private void updateMessage(String message) {
329         mCurrentRestrictions.putString(RESTRICTION_KEY_MESSAGE, message);
330         mEditMessage.removeTextChangedListener(mWatcherMessage);
331         mEditMessage.setText(message);
332         mEditMessage.addTextChangedListener(mWatcherMessage);
333     }
334 
updateNumber(int number)335     private void updateNumber(int number) {
336         mCurrentRestrictions.putInt(RESTRICTION_KEY_NUMBER, number);
337         mEditNumber.removeTextChangedListener(mWatcherNumber);
338         mEditNumber.setText(String.valueOf(number));
339         mEditNumber.addTextChangedListener(mWatcherNumber);
340     }
341 
updateRank(Context context, String[] ranks, String selectedRank)342     private void updateRank(Context context, String[] ranks, String selectedRank) {
343         mCurrentRestrictions.putString(RESTRICTION_KEY_RANK, selectedRank);
344         mSpinnerRank.setAdapter(new ArrayAdapter<>(context,
345                 android.R.layout.simple_spinner_dropdown_item, ranks));
346         mSpinnerRank.setSelection(search(ranks, selectedRank));
347         mSpinnerRank.setOnItemSelectedListener(this);
348     }
349 
updateApprovals(Context context, String[] approvals, String[] selectedApprovals)350     private void updateApprovals(Context context, String[] approvals,
351                                  String[] selectedApprovals) {
352         mCurrentRestrictions.putStringArray(RESTRICTION_KEY_APPROVALS, selectedApprovals);
353         mLayoutApprovals.removeAllViews();
354         for (String approval : approvals) {
355             Switch sw = new Switch(context);
356             sw.setText(approval);
357             sw.setTag(approval);
358             sw.setChecked(Arrays.asList(selectedApprovals).contains(approval));
359             sw.setOnCheckedChangeListener(this);
360             sw.setId(R.id.approval);
361             mLayoutApprovals.addView(sw);
362         }
363     }
364 
updateProfile(String name, int age)365     private void updateProfile(String name, int age) {
366         if (!BUNDLE_SUPPORTED) {
367             return;
368         }
369         Bundle profile = new Bundle();
370         profile.putString(RESTRICTION_KEY_PROFILE_NAME, name);
371         profile.putInt(RESTRICTION_KEY_PROFILE_AGE, age);
372         mCurrentRestrictions.putBundle(RESTRICTION_KEY_PROFILE, profile);
373         mEditProfileName.removeTextChangedListener(mWatcherProfile);
374         mEditProfileName.setText(name);
375         mEditProfileName.addTextChangedListener(mWatcherProfile);
376         mEditProfileAge.removeTextChangedListener(mWatcherProfile);
377         mEditProfileAge.setText(String.valueOf(age));
378         mEditProfileAge.addTextChangedListener((mWatcherProfile));
379     }
380 
updateItems(Context context, Map<String, String> items)381     private void updateItems(Context context, Map<String, String> items) {
382         if (!BUNDLE_SUPPORTED) {
383             return;
384         }
385         mCurrentRestrictions.putParcelableArray(RESTRICTION_KEY_ITEMS, convertToBundles(items));
386         LayoutInflater inflater = LayoutInflater.from(context);
387         mLayoutItems.removeAllViews();
388         for (String key : items.keySet()) {
389             insertItemRow(inflater, key, items.get(key));
390         }
391     }
392 
insertItemRow(LayoutInflater inflater, String key, String value)393     private void insertItemRow(LayoutInflater inflater, String key, String value) {
394         View view = inflater.inflate(R.layout.item, mLayoutItems, false);
395         TextView textView = (TextView) view.findViewById(R.id.item_text);
396         textView.setText(getString(R.string.item, key, value));
397         Button remove = (Button) view.findViewById(R.id.item_remove);
398         remove.setTag(key);
399         remove.setOnClickListener(this);
400         mLayoutItems.addView(view);
401     }
402 
403     @NonNull
convertToBundles(Map<String, String> items)404     private Bundle[] convertToBundles(Map<String, String> items) {
405         Bundle[] bundles = new Bundle[items.size()];
406         int i = 0;
407         for (String key : items.keySet()) {
408             Bundle bundle = new Bundle();
409             bundle.putString(RESTRICTION_KEY_ITEM_KEY, key);
410             bundle.putString(RESTRICTION_KEY_ITEM_VALUE, items.get(key));
411             bundles[i++] = bundle;
412         }
413         return bundles;
414     }
415 
removeItem(String key)416     private void removeItem(String key) {
417         Parcelable[] parcelables = mCurrentRestrictions.getParcelableArray(RESTRICTION_KEY_ITEMS);
418         if (parcelables != null) {
419             Map<String, String> items = new HashMap<>();
420             for (Parcelable parcelable : parcelables) {
421                 Bundle bundle = (Bundle) parcelable;
422                 if (!key.equals(bundle.getString(RESTRICTION_KEY_ITEM_KEY))) {
423                     items.put(bundle.getString(RESTRICTION_KEY_ITEM_KEY),
424                             bundle.getString(RESTRICTION_KEY_ITEM_VALUE));
425                 }
426             }
427             saveItems(getActivity(), items);
428         }
429     }
430 
431     /**
432      * Saves the value for the "cay_say_hello" restriction of AppRestrictionSchema.
433      *
434      * @param activity The activity
435      * @param allow    The value to be set for the restriction.
436      */
saveCanSayHello(Activity activity, boolean allow)437     private void saveCanSayHello(Activity activity, boolean allow) {
438         mCurrentRestrictions.putBoolean(RESTRICTION_KEY_SAY_HELLO, allow);
439         saveRestrictions(activity);
440         // Note that the owner app needs to remember the restrictions on its own.
441         editPreferences(activity).putBoolean(RESTRICTION_KEY_SAY_HELLO, allow).apply();
442     }
443 
444     /**
445      * Saves the value for the "message" restriction of AppRestrictionSchema.
446      *
447      * @param activity The activity
448      * @param message  The value to be set for the restriction.
449      */
saveMessage(Activity activity, String message)450     private void saveMessage(Activity activity, String message) {
451         mCurrentRestrictions.putString(RESTRICTION_KEY_MESSAGE, message);
452         saveRestrictions(activity);
453         editPreferences(activity).putString(RESTRICTION_KEY_MESSAGE, message).apply();
454     }
455 
456     /**
457      * Saves the value for the "number" restriction of AppRestrictionSchema.
458      *
459      * @param activity The activity
460      * @param number   The value to be set for the restriction.
461      */
saveNumber(Activity activity, int number)462     private void saveNumber(Activity activity, int number) {
463         mCurrentRestrictions.putInt(RESTRICTION_KEY_NUMBER, number);
464         saveRestrictions(activity);
465         editPreferences(activity).putInt(RESTRICTION_KEY_NUMBER, number).apply();
466     }
467 
468     /**
469      * Saves the value for the "rank" restriction of AppRestrictionSchema.
470      *
471      * @param activity The activity
472      * @param rank     The value to be set for the restriction.
473      */
saveRank(Activity activity, String rank)474     private void saveRank(Activity activity, String rank) {
475         mCurrentRestrictions.putString(RESTRICTION_KEY_RANK, rank);
476         saveRestrictions(activity);
477         editPreferences(activity).putString(RESTRICTION_KEY_RANK, rank).apply();
478     }
479 
addApproval(Activity activity, String approval)480     private void addApproval(Activity activity, String approval) {
481         List<String> approvals = new ArrayList<>(Arrays.asList(
482                 mCurrentRestrictions.getStringArray(RESTRICTION_KEY_APPROVALS)));
483         if (approvals.contains(approval)) {
484             return;
485         }
486         approvals.add(approval);
487         saveApprovals(activity, approvals.toArray(new String[approvals.size()]));
488     }
489 
removeApproval(Activity activity, String approval)490     private void removeApproval(Activity activity, String approval) {
491         List<String> approvals = new ArrayList<>(Arrays.asList(
492                 mCurrentRestrictions.getStringArray(RESTRICTION_KEY_APPROVALS)));
493         if (!approval.contains(approval)) {
494             return;
495         }
496         approvals.remove(approval);
497         saveApprovals(activity, approvals.toArray(new String[approvals.size()]));
498     }
499 
500     /**
501      * Saves the value for the "approvals" restriction of AppRestrictionSchema.
502      *
503      * @param activity  The activity
504      * @param approvals The value to be set for the restriction.
505      */
saveApprovals(Activity activity, String[] approvals)506     private void saveApprovals(Activity activity, String[] approvals) {
507         mCurrentRestrictions.putStringArray(RESTRICTION_KEY_APPROVALS, approvals);
508         saveRestrictions(activity);
509         editPreferences(activity).putString(RESTRICTION_KEY_APPROVALS,
510                 TextUtils.join(DELIMETER, approvals)).apply();
511     }
512 
513     /**
514      * Saves the value for the "profile" restriction of AppRestrictionSchema.
515      *
516      * @param activity The activity
517      * @param name     The value to be set for the "name" field.
518      * @param age      The value to be set for the "age" field.
519      */
saveProfile(Activity activity, String name, int age)520     private void saveProfile(Activity activity, String name, int age) {
521         if (!BUNDLE_SUPPORTED) {
522             return;
523         }
524         Bundle profile = new Bundle();
525         profile.putString(RESTRICTION_KEY_PROFILE_NAME, name);
526         profile.putInt(RESTRICTION_KEY_PROFILE_AGE, age);
527         mCurrentRestrictions.putBundle(RESTRICTION_KEY_PROFILE, profile);
528         saveRestrictions(activity);
529         editPreferences(activity).putString(RESTRICTION_KEY_PROFILE_NAME, name).apply();
530     }
531 
532     /**
533      * Saves the value for the "items" restriction of AppRestrictionSchema.
534      *
535      * @param activity The activity.
536      * @param items    The values.
537      */
saveItems(Activity activity, Map<String, String> items)538     private void saveItems(Activity activity, Map<String, String> items) {
539         if (!BUNDLE_SUPPORTED) {
540             return;
541         }
542         mCurrentRestrictions.putParcelableArray(RESTRICTION_KEY_ITEMS, convertToBundles(items));
543         saveRestrictions(activity);
544         StringBuilder builder = new StringBuilder();
545         boolean first = true;
546         for (String key : items.keySet()) {
547             if (first) {
548                 first = false;
549             } else {
550                 builder.append(DELIMETER);
551             }
552             builder.append(key);
553             builder.append(SEPARATOR);
554             builder.append(items.get(key));
555         }
556         editPreferences(activity).putString(RESTRICTION_KEY_ITEMS, builder.toString()).apply();
557     }
558 
559     /**
560      * Saves all the restrictions.
561      *
562      * @param activity The activity.
563      */
saveRestrictions(Activity activity)564     private void saveRestrictions(Activity activity) {
565         DevicePolicyManager devicePolicyManager
566                 = (DevicePolicyManager) activity.getSystemService(Context.DEVICE_POLICY_SERVICE);
567         devicePolicyManager.setApplicationRestrictions(
568                 EnforcerDeviceAdminReceiver.getComponentName(activity),
569                 Constants.PACKAGE_NAME_APP_RESTRICTION_SCHEMA, mCurrentRestrictions);
570     }
571 
editPreferences(Activity activity)572     private SharedPreferences.Editor editPreferences(Activity activity) {
573         return activity.getSharedPreferences(PREFS_KEY, Context.MODE_PRIVATE).edit();
574     }
575 
576     /**
577      * Sequential search
578      *
579      * @param array The string array
580      * @param s     The string to search for
581      * @return Index if found. -1 if not found.
582      */
search(String[] array, String s)583     private int search(String[] array, String s) {
584         for (int i = 0; i < array.length; ++i) {
585             if (s.equals(array[i])) {
586                 return i;
587             }
588         }
589         return -1;
590     }
591 
592 }
593