165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/* 265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Copyright (C) 2014 The Android Open Source Project 365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Licensed under the Apache License, Version 2.0 (the "License"); 565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * you may not use this file except in compliance with the License. 665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * You may obtain a copy of the License at 765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * http://www.apache.org/licenses/LICENSE-2.0 965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * 1065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Unless required by applicable law or agreed to in writing, software 1165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * distributed under the License is distributed on an "AS IS" BASIS, 1265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * See the License for the specific language governing permissions and 1465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * limitations under the License. 1565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 1665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lanepackage com.android.tv.settings.users; 1865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 1965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Activity; 2065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.app.Fragment; 2165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.BroadcastReceiver; 2265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Context; 2365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.Intent; 2465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.content.RestrictionEntry; 2565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.Bundle; 2665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.UserHandle; 2765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.os.UserManager; 2865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.text.TextUtils; 2965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport android.util.Log; 3065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 316e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantlerimport com.android.tv.settings.R; 326e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantlerimport com.android.tv.settings.dialog.DialogFragment; 336e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantlerimport com.android.tv.settings.dialog.DialogFragment.Action; 346e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler 3565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.ArrayList; 3665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.Arrays; 3765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.HashSet; 3865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneimport java.util.List; 3965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane/** 4165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Handles all aspects of DialogFragment Actions for setting individual app restrictions. 4265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 4365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Laneclass AppRestrictionsManager implements Action.Listener { 4465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane interface Listener { 4665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void onRestrictionActionsLoaded(String packageName, ArrayList<Action> actions); 4765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 4865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 4965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final boolean DEBUG = false; 5065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String TAG = "RestrictedProfile"; 5165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 5265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_PACKAGE_NAME = "AppRestrictionsManager.package_name"; 5365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_RESTRICTIONS = "AppRestrictionsManager.restrictions"; 5465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_USER_HANDLE = "user_handle"; 5565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_ENABLED = "enabled"; 5665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_RESTRICTION_KEY = "restriction_key"; 5765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String EXTRA_CHOICE_VALUE = "choice_value"; 5865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ACTION_CUSTOM_CONFIGURATION = "action_custom_configuration"; 5965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ACTION_TRUE = "action_true"; 6065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ACTION_FALSE = "action_false"; 6165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ACTION_CHANGE_RESTRICTION = "action_change_restriction"; 6265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ACTION_CHOICE = "action_choice"; 6365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String ACTION_MULTI_CHOICE = "action_multi_choice"; 6465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final int MUTUALLY_EXCLUSIVE_CHOICE_CHECK_SET_ID = 1; 6565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 6665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Fragment mFragment; 6765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final UserManager mUserManager; 6865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final UserHandle mUserHandle; 6965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final String mPackageName; 7065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final Listener mListener; 7165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 7265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private static final String CUSTOM_RESTRICTIONS_INTENT = Intent.EXTRA_RESTRICTIONS_INTENT; 7365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 7465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 7565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onReceive(Context context, Intent intent) { 7665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle results = getResultExtras(true); 7765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRestrictions = results.getParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST); 786e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler mRestrictionsIntent = results.getParcelable(CUSTOM_RESTRICTIONS_INTENT); 7965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mRestrictions != null && mRestrictionsIntent == null) { 8165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane saveRestrictions(); 8265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (mRestrictionsIntent != null) { 8365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getRestrictionActions(); 8465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 8665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane }; 8765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 8865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private ArrayList<RestrictionEntry> mRestrictions; 8965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private Intent mRestrictionsIntent; 9065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private DialogFragment mCurrentDialogFragment; 9165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 9265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 9365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param fragment THe fragment for which DialogFragment actions are being managed. 9465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param userHandle the user whose app restrictions are being set. 9565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param userManager the user manager for setting app restrictions. 9665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * @param packageName settings' package name (for special case restrictions). 976e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler * @param listener a listener for when restriction actions are ready to be displayed. 9865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 9965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane AppRestrictionsManager(Fragment fragment, UserHandle userHandle, UserManager userManager, 10065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String packageName, Listener listener) { 10165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFragment = fragment; 10265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mUserHandle = userHandle; 10365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mUserManager = userManager; 10465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mPackageName = packageName; 10565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mListener = listener; 10665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 10765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 10865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void loadRestrictionActions() { 10965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mPackageName.equals(mFragment.getActivity().getPackageName())) { 11065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // Settings, fake it by using user restrictions 11165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRestrictions = RestrictionUtils.getRestrictions(mFragment.getActivity(), mUserHandle); 11265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mRestrictionsIntent = null; 11365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getRestrictionActions(); 11465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 11565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane requestRestrictionsForApp(); 11665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 11865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 11965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane @Override 12065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane public void onActionClicked(Action action) { 12165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String restrictionEntryKey = action.getIntent().getStringExtra(EXTRA_RESTRICTION_KEY); 12265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane RestrictionEntry entry = restrictionEntryKey != null ? findRestriction(restrictionEntryKey) 12365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane : null; 12465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 12565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (ACTION_CUSTOM_CONFIGURATION.equals(action.getKey())) { 12665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFragment.startActivityForResult(action.getIntent(), 1); 12765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (ACTION_CHANGE_RESTRICTION.equals(action.getKey())) { 1286e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler ArrayList<Action> actions = new ArrayList<>(); 12965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane switch (entry.getType()) { 13065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_BOOLEAN: 13165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder() 13265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .key(ACTION_TRUE) 13365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(Boolean.toString(true)) 13465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .checked(entry.getSelectedState()) 13565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .checkSetId(MUTUALLY_EXCLUSIVE_CHOICE_CHECK_SET_ID) 13665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(action.getIntent()) 13765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 13865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder() 13965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .key(ACTION_FALSE) 14065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(Boolean.toString(false)) 14165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .checked(!entry.getSelectedState()) 14265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .checkSetId(MUTUALLY_EXCLUSIVE_CHOICE_CHECK_SET_ID) 14365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(action.getIntent()) 14465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 14565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 14665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_CHOICE: 14765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_CHOICE_LEVEL: 14865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane { 14965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String value = entry.getSelectedString(); 15065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (value == null) { 15165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane value = entry.getDescription(); 15265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 15365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] choiceEntries = entry.getChoiceEntries(); 15465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] choiceValues = entry.getChoiceValues(); 15565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean useValue = (choiceEntries == null 15665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane || choiceEntries.length != choiceValues.length); 15765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0; i < choiceValues.length; i++) { 15865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String choiceValue = choiceValues[i]; 15965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = useValue ? choiceValue : choiceEntries[i]; 16065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = new Intent(action.getIntent()); 16165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_CHOICE_VALUE, choiceValue); 16265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder() 16365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .key(ACTION_CHOICE) 16465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(title) 16565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .checked(choiceValue.equals(value)) 16665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .checkSetId(MUTUALLY_EXCLUSIVE_CHOICE_CHECK_SET_ID) 16765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(intent) 16865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 16965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 17165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 17265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_MULTI_SELECT: 17365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane { 17465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane List<String> selectedChoiceValues = Arrays.asList( 17565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.getAllSelectedStrings()); 17665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] choiceEntries = entry.getChoiceEntries(); 17765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] choiceValues = entry.getChoiceValues(); 17865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane boolean useValues = (choiceEntries == null 17965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane || choiceEntries.length != choiceValues.length); 18065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0; i < choiceValues.length; i++) { 18165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String choiceValue = choiceValues[i]; 18265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String title = useValues ? choiceValue : choiceEntries[i]; 18365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = new Intent(action.getIntent()); 18465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(EXTRA_CHOICE_VALUE, choiceValue); 18565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder() 18665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .key(ACTION_MULTI_CHOICE) 18765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(title) 18865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .checked(selectedChoiceValues.contains(choiceValue)) 18965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(intent) 19065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 19165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 19465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_NULL: 19565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane default: 19665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 19765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 19865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (!actions.isEmpty()) { 19965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mCurrentDialogFragment = new DialogFragment.Builder() 20065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(entry.getTitle()) 20165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(entry.getDescription()) 2023150b12e5df05eec2c3ebb85360661f1d034c188Andrew Wilson .iconResourceId(RestrictedProfileDialogFragment.getIconResource()) 20365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .iconBackgroundColor( 20465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFragment.getActivity().getResources() 20565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .getColor(R.color.icon_background)) 20665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .actions(actions).build(); 20765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mCurrentDialogFragment.setListener(this); 20865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane DialogFragment.add(mFragment.getFragmentManager(), mCurrentDialogFragment); 20965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 21065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 21165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (ACTION_TRUE.equals(action.getKey())) { 21265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.setSelectedState(true); 21365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane saveRestrictions(); 21465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (ACTION_FALSE.equals(action.getKey())) { 21565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.setSelectedState(false); 21665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane saveRestrictions(); 21765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (ACTION_CHOICE.equals(action.getKey())) { 21865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.setSelectedString(getChoiceValue(action)); 21965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane saveRestrictions(); 22065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (ACTION_MULTI_CHOICE.equals(action.getKey())) { 22165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane action.setChecked(!action.isChecked()); 22365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mCurrentDialogFragment != null) { 22465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mCurrentDialogFragment.setActions(mCurrentDialogFragment.getActions()); 22565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 2266e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler HashSet<String> selectedChoiceValues = new HashSet<>(); 22765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane selectedChoiceValues.addAll(Arrays.asList(entry.getAllSelectedStrings())); 22865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 22965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (action.isChecked()) { 23065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane selectedChoiceValues.add(getChoiceValue(action)); 23165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 23265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane selectedChoiceValues.remove(getChoiceValue(action)); 23365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 23465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.setAllSelectedStrings( 23565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane selectedChoiceValues.toArray(new String[selectedChoiceValues.size()])); 23665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane saveRestrictions(); 23765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 23865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 23965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 24065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane void onActivityResult(int requestCode, int resultCode, Intent data) { 24165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (resultCode == Activity.RESULT_OK) { 24265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ArrayList<RestrictionEntry> list = 24365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane data.getParcelableArrayListExtra(Intent.EXTRA_RESTRICTIONS_LIST); 24465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle bundle = data.getBundleExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE); 24565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (list != null) { 24665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If there's a valid result, persist it to the user manager. 24765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mUserManager.setApplicationRestrictions(mPackageName, 24865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane RestrictionUtils.restrictionsToBundle(list), mUserHandle); 24965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else if (bundle != null) { 25065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane // If there's a valid result, persist it to the user manager. 25165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mUserManager.setApplicationRestrictions(mPackageName, bundle, mUserHandle); 25265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 253420343e45f4c3db45ef7390cb572a6388ba45c37Andrew Wilson loadRestrictionActions(); 25465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 25665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 25765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private RestrictionEntry findRestriction(String key) { 25865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (RestrictionEntry entry : mRestrictions) { 25965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (entry.getKey().equals(key)) { 26065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return entry; 26165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Log.wtf(TAG, "Couldn't find the restriction to set!"); 26465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return null; 26565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 26665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 26765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String getChoiceValue(Action action) { 26865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return action.getIntent().getStringExtra(EXTRA_CHOICE_VALUE); 26965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 27065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 27165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane /** 27265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane * Send a broadcast to the app to query its restrictions 27365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane */ 27465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void requestRestrictionsForApp() { 27565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle oldEntries = mUserManager.getApplicationRestrictions(mPackageName, mUserHandle); 27665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent intent = new Intent(Intent.ACTION_GET_RESTRICTION_ENTRIES); 27765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.setPackage(mPackageName); 27865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.putExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE, oldEntries); 27965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES); 28065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mFragment.getActivity().sendOrderedBroadcast(intent, null, mBroadcastReceiver, null, 28165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Activity.RESULT_OK, null, null); 28265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 28365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 28465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void getRestrictionActions() { 2856e995161147d9110d77ae1fe38b697e52891d3f2Tony Mantler ArrayList<Action> actions = new ArrayList<>(); 28665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 28765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mRestrictionsIntent != null) { 28865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder() 28965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .key(ACTION_CUSTOM_CONFIGURATION) 29065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(mFragment.getActivity().getString( 29165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.restricted_profile_customize_restrictions)) 29265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(mRestrictionsIntent) 29365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .hasNext(true) 29465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 29565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 29665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 29765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mRestrictions != null) { 29865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (RestrictionEntry entry : mRestrictions) { 29965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Intent data = new Intent().putExtra(EXTRA_RESTRICTION_KEY, entry.getKey()); 30065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane switch (entry.getType()) { 30165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_BOOLEAN: 30265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder() 30365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .key(ACTION_CHANGE_RESTRICTION) 30465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(entry.getTitle()) 30565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mFragment.getActivity().getString( 30665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.restriction_description, entry.getDescription(), 30765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Boolean.toString(entry.getSelectedState()))) 30865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .hasNext(mRestrictionsIntent == null) 30965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .infoOnly(mRestrictionsIntent != null) 31065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(data) 31165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .multilineDescription(true) 31265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 31365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 31465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_CHOICE: 31565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_CHOICE_LEVEL: 31665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String value = entry.getSelectedString(); 31765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (value == null) { 31865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane value = entry.getDescription(); 31965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 32065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder() 32165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .key(ACTION_CHANGE_RESTRICTION) 32265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(entry.getTitle()) 32365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mFragment.getActivity().getString( 32465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.restriction_description, 32565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.getDescription(), findInArray( 32665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.getChoiceEntries(), entry.getChoiceValues(), 32765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane value))) 32865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .hasNext(mRestrictionsIntent == null) 32965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .infoOnly(mRestrictionsIntent != null) 33065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(data) 33165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .multilineDescription(true) 33265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 33365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 33465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_MULTI_SELECT: 33565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane actions.add(new Action.Builder() 33665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .key(ACTION_CHANGE_RESTRICTION) 33765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .title(entry.getTitle()) 33865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .description(mFragment.getActivity().getString( 33965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane R.string.restriction_description, 34065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.getDescription(), TextUtils.join( 34165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane ", ", findSelectedStrings(entry.getChoiceEntries(), 34265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.getChoiceValues(), 34365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane entry.getAllSelectedStrings())))) 34465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .hasNext(mRestrictionsIntent == null) 34565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .infoOnly(mRestrictionsIntent != null) 34665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .intent(data) 34765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .multilineDescription(true) 34865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane .build()); 34965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane break; 35065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane case RestrictionEntry.TYPE_NULL: 35165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane default: 35265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 35665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mListener.onRestrictionActionsLoaded(mPackageName, actions); 35765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 35865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 35965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String findInArray(String[] choiceEntries, String[] choiceValues, 36065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String selectedString) { 36165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (choiceEntries == null || choiceValues.length != choiceEntries.length) { 36265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return selectedString; 36365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0; i < choiceValues.length; i++) { 36565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (choiceValues[i].equals(selectedString)) { 36665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return choiceEntries[i]; 36765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 36965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return selectedString; 37065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 37265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private String[] findSelectedStrings(String[] choiceEntries, String[] choiceValues, 37365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] selectedStrings) { 37465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (choiceEntries == null || choiceValues.length != choiceEntries.length) { 37565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return selectedStrings; 37665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 37765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane String[] selectedStringsMapped = new String[selectedStrings.length]; 37865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int i = 0; i < selectedStrings.length; i++) { 37965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane selectedStringsMapped[i] = selectedStrings[i]; 38065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane for (int j = 0; j < choiceValues.length; j++) { 38165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (choiceValues[j].equals(selectedStrings[i])) { 38265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane selectedStringsMapped[i] = choiceEntries[j]; 38365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane return selectedStringsMapped; 38765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 38865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane 38965a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane private void saveRestrictions() { 39065a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane getRestrictionActions(); 39165a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane if (mPackageName.equals(mFragment.getActivity().getPackageName())) { 39265a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane RestrictionUtils.setRestrictions(mFragment.getActivity(), mRestrictions, mUserHandle); 39365a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } else { 39465a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane Bundle bundle = RestrictionUtils.restrictionsToBundle(mRestrictions); 39565a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane mUserManager.setApplicationRestrictions(mPackageName, bundle, mUserHandle); 39665a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39765a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane } 39865a5a7d84ad9b5324ae53eda526e39e513473af7Christopher Lane} 399