Files
app_Settings/src/com/android/settings/RestrictedListPreference.java
Eran Messeri f61ccf3fa3 Require work profile to be unlocked for changing notification settings in a different way
Rather than check for the state of the work profile in
LockScreenNotificationPreferenceController#handlePreferenceTreeClick, do so in
the RestrictedListPreference#performClick.
The drawback of checking the state in handlePreferenceTreeClick is that the
preferences are displayed first and then the requirement to unlock/enable the
work profile is displayed on top of it.

This is rather poor UX, so switch to doing the check in performClick and
returning early if the work profile needs to be unlocked/enabled.
This is similar to Patchset 1 from ag/3805482.
The main difference is that the user is returned to the settings screen
both after enabling the work profile and unlocking it.

Test: Manually with TestDPC
Test: atest SettingsRoboTests:RestrictedListPreferenceTest
Bug: 77408805
Merged-In: Id168911b082fffac193cd7c7a658ab92d6ce2c15
Change-Id: I0a3a4ec4dda78e28ee88a11d383eda49e9cf50a6
2018-05-01 21:55:56 +01:00

302 lines
11 KiB
Java

/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.RemoteException;
import android.os.UserManager;
import android.support.annotation.VisibleForTesting;
import android.support.v14.preference.ListPreferenceDialogFragment;
import android.support.v7.preference.PreferenceViewHolder;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import com.android.settings.Utils;
import com.android.settingslib.RestrictedLockUtils;
import com.android.settingslib.RestrictedPreferenceHelper;
import java.util.ArrayList;
import java.util.List;
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
public class RestrictedListPreference extends CustomListPreference {
private final RestrictedPreferenceHelper mHelper;
private final List<RestrictedItem> mRestrictedItems = new ArrayList<>();
private boolean mRequiresActiveUnlockedProfile = false;
private int mProfileUserId;
public RestrictedListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setWidgetLayoutResource(R.layout.restricted_icon);
mHelper = new RestrictedPreferenceHelper(context, this, attrs);
}
public RestrictedListPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mHelper = new RestrictedPreferenceHelper(context, this, attrs);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
mHelper.onBindViewHolder(holder);
final View restrictedIcon = holder.findViewById(R.id.restricted_icon);
if (restrictedIcon != null) {
restrictedIcon.setVisibility(isDisabledByAdmin() ? View.VISIBLE : View.GONE);
}
}
@Override
public void performClick() {
if (mRequiresActiveUnlockedProfile) {
// Check if the profile is started, first.
if (Utils.startQuietModeDialogIfNecessary(getContext(), UserManager.get(getContext()),
mProfileUserId)) {
return;
}
// Next, check if the profile is unlocked.
KeyguardManager manager =
(KeyguardManager) getContext().getSystemService(Context.KEYGUARD_SERVICE);
if (manager.isDeviceLocked(mProfileUserId)) {
Intent intent = manager.createConfirmDeviceCredentialIntent(
null, null, mProfileUserId);
getContext().startActivity(intent);
return;
}
}
if (!mHelper.performClick()) {
super.performClick();
}
}
@Override
public void setEnabled(boolean enabled) {
if (enabled && isDisabledByAdmin()) {
mHelper.setDisabledByAdmin(null);
return;
}
super.setEnabled(enabled);
}
public void setDisabledByAdmin(EnforcedAdmin admin) {
if (mHelper.setDisabledByAdmin(admin)) {
notifyChanged();
}
}
public boolean isDisabledByAdmin() {
return mHelper.isDisabledByAdmin();
}
public void setRequiresActiveUnlockedProfile(boolean reqState) {
mRequiresActiveUnlockedProfile = reqState;
}
public void setProfileUserId(int profileUserId) {
mProfileUserId = profileUserId;
}
public boolean isRestrictedForEntry(CharSequence entry) {
if (entry == null) {
return false;
}
for (RestrictedItem item : mRestrictedItems) {
if (entry.equals(item.entry)) {
return true;
}
}
return false;
}
public void addRestrictedItem(RestrictedItem item) {
mRestrictedItems.add(item);
}
public void clearRestrictedItems() {
mRestrictedItems.clear();
}
private RestrictedItem getRestrictedItemForEntryValue(CharSequence entryValue) {
if (entryValue == null) {
return null;
}
for (RestrictedItem item : mRestrictedItems) {
if (entryValue.equals(item.entryValue)) {
return item;
}
}
return null;
}
protected ListAdapter createListAdapter() {
return new RestrictedArrayAdapter(getContext(), getEntries(),
getSelectedValuePos());
}
public int getSelectedValuePos() {
final String selectedValue = getValue();
final int selectedIndex =
(selectedValue == null) ? -1 : findIndexOfValue(selectedValue);
return selectedIndex;
}
@Override
protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
DialogInterface.OnClickListener listener) {
builder.setAdapter(createListAdapter(), listener);
}
public class RestrictedArrayAdapter extends ArrayAdapter<CharSequence> {
private final int mSelectedIndex;
public RestrictedArrayAdapter(Context context, CharSequence[] objects, int selectedIndex) {
super(context, R.layout.restricted_dialog_singlechoice, R.id.text1, objects);
mSelectedIndex = selectedIndex;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View root = super.getView(position, convertView, parent);
CharSequence entry = getItem(position);
CheckedTextView text = (CheckedTextView) root.findViewById(R.id.text1);
ImageView padlock = (ImageView) root.findViewById(R.id.restricted_lock_icon);
if (isRestrictedForEntry(entry)) {
text.setEnabled(false);
text.setChecked(false);
padlock.setVisibility(View.VISIBLE);
} else {
if (mSelectedIndex != -1) {
text.setChecked(position == mSelectedIndex);
}
if (!text.isEnabled()) {
text.setEnabled(true);
}
padlock.setVisibility(View.GONE);
}
return root;
}
@Override
public boolean hasStableIds() {
return true;
}
@Override
public long getItemId(int position) {
return position;
}
}
public static class RestrictedListPreferenceDialogFragment extends
CustomListPreference.CustomListPreferenceDialogFragment {
private int mLastCheckedPosition = AdapterView.INVALID_POSITION;
public static ListPreferenceDialogFragment newInstance(String key) {
final ListPreferenceDialogFragment fragment
= new RestrictedListPreferenceDialogFragment();
final Bundle b = new Bundle(1);
b.putString(ARG_KEY, key);
fragment.setArguments(b);
return fragment;
}
private RestrictedListPreference getCustomizablePreference() {
return (RestrictedListPreference) getPreference();
}
@Override
protected DialogInterface.OnClickListener getOnItemClickListener() {
return new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final RestrictedListPreference preference = getCustomizablePreference();
if (which < 0 || which >= preference.getEntryValues().length) {
return;
}
String entryValue = preference.getEntryValues()[which].toString();
RestrictedItem item = preference.getRestrictedItemForEntryValue(entryValue);
if (item != null) {
ListView listView = ((AlertDialog) dialog).getListView();
listView.setItemChecked(getLastCheckedPosition(), true);
RestrictedLockUtils.sendShowAdminSupportDetailsIntent(getContext(),
item.enforcedAdmin);
} else {
setClickedDialogEntryIndex(which);
}
if (getCustomizablePreference().isAutoClosePreference()) {
/*
* Clicking on an item simulates the positive button
* click, and dismisses the dialog.
*/
RestrictedListPreferenceDialogFragment.this.onClick(dialog,
DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
}
}
};
}
private int getLastCheckedPosition() {
if (mLastCheckedPosition == AdapterView.INVALID_POSITION) {
mLastCheckedPosition = ((RestrictedListPreference) getCustomizablePreference())
.getSelectedValuePos();
}
return mLastCheckedPosition;
}
private void setCheckedPosition(int checkedPosition) {
mLastCheckedPosition = checkedPosition;
}
@Override
protected void setClickedDialogEntryIndex(int which) {
super.setClickedDialogEntryIndex(which);
mLastCheckedPosition = which;
}
}
public static class RestrictedItem {
public final CharSequence entry;
public final CharSequence entryValue;
public final EnforcedAdmin enforcedAdmin;
public RestrictedItem(CharSequence entry, CharSequence entryValue,
EnforcedAdmin enforcedAdmin) {
this.entry = entry;
this.entryValue = entryValue;
this.enforcedAdmin = enforcedAdmin;
}
}
}