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