Merge remote-tracking branch 'goog/stage-aosp-master' into HEAD
This commit is contained in:
@@ -146,7 +146,8 @@ public class ApnEditor extends SettingsPreferenceFragment
|
||||
Telephony.Carriers.ROAMING_PROTOCOL, // 20
|
||||
Telephony.Carriers.MVNO_TYPE, // 21
|
||||
Telephony.Carriers.MVNO_MATCH_DATA, // 22
|
||||
Telephony.Carriers.EDITED // 23
|
||||
Telephony.Carriers.EDITED, // 23
|
||||
Telephony.Carriers.USER_EDITABLE //24
|
||||
};
|
||||
|
||||
private static final int ID_INDEX = 0;
|
||||
@@ -172,6 +173,7 @@ public class ApnEditor extends SettingsPreferenceFragment
|
||||
private static final int MVNO_TYPE_INDEX = 21;
|
||||
private static final int MVNO_MATCH_DATA_INDEX = 22;
|
||||
private static final int EDITED_INDEX = 23;
|
||||
private static final int USER_EDITABLE_INDEX = 24;
|
||||
|
||||
|
||||
@Override
|
||||
@@ -282,7 +284,8 @@ public class ApnEditor extends SettingsPreferenceFragment
|
||||
Log.d(TAG, "onCreate: EDITED " + mCursor.getInt(EDITED_INDEX));
|
||||
// if it's not a USER_EDITED apn, check if it's read-only
|
||||
if (mCursor.getInt(EDITED_INDEX) != Telephony.Carriers.USER_EDITED &&
|
||||
apnTypesMatch(mReadOnlyApnTypes, mCursor.getString(TYPE_INDEX))) {
|
||||
(mCursor.getInt(USER_EDITABLE_INDEX) == 0 ||
|
||||
apnTypesMatch(mReadOnlyApnTypes, mCursor.getString(TYPE_INDEX)))) {
|
||||
Log.d(TAG, "onCreate: apnTypesMatch; read-only APN");
|
||||
mReadOnlyApn = true;
|
||||
disableAllFields();
|
||||
|
||||
@@ -193,7 +193,7 @@ public class ApnSettings extends RestrictedSettingsFragment implements
|
||||
mUnavailable = isUiRestricted();
|
||||
setHasOptionsMenu(!mUnavailable);
|
||||
if (mUnavailable) {
|
||||
addPreferencesFromResource(R.xml.empty_settings);
|
||||
addPreferencesFromResource(R.xml.placeholder_prefs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.CustomDialogPreference;
|
||||
|
||||
public class BugreportPreference extends CustomDialogPreference {
|
||||
|
||||
|
||||
@@ -47,14 +47,16 @@ import android.widget.Toast;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.org.bouncycastle.asn1.ASN1InputStream;
|
||||
import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.security.ConfigureKeyGuardDialog;
|
||||
import com.android.settings.vpn2.VpnUtils;
|
||||
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
import sun.security.x509.AlgorithmId;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import sun.security.util.ObjectIdentifier;
|
||||
import sun.security.x509.AlgorithmId;
|
||||
|
||||
/**
|
||||
* CredentialStorage handles KeyStore reset, unlock, and install.
|
||||
*
|
||||
@@ -72,14 +74,14 @@ import java.io.IOException;
|
||||
* KeyGuard: ON
|
||||
* Action: confirm key guard
|
||||
* Notes: user had key guard but no keystore and upgraded from pre-ICS
|
||||
* OR user had key guard and pre-ICS keystore password which was then reset
|
||||
* OR user had key guard and pre-ICS keystore password which was then reset
|
||||
*
|
||||
* KeyStore: LOCKED
|
||||
* KeyGuard: OFF/ON
|
||||
* Action: old unlock dialog
|
||||
* Notes: assume old password, need to use it to unlock.
|
||||
* if unlock, ensure key guard before install.
|
||||
* if reset, treat as UNINITALIZED/OFF
|
||||
* if unlock, ensure key guard before install.
|
||||
* if reset, treat as UNINITALIZED/OFF
|
||||
*
|
||||
* KeyStore: UNLOCKED
|
||||
* KeyGuard: OFF
|
||||
@@ -101,7 +103,7 @@ public final class CredentialStorage extends Activity {
|
||||
|
||||
// This is the minimum acceptable password quality. If the current password quality is
|
||||
// lower than this, keystore should not be activated.
|
||||
static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
|
||||
public static final int MIN_PASSWORD_QUALITY = DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
|
||||
|
||||
private static final int CONFIRM_KEY_GUARD_REQUEST = 1;
|
||||
private static final int CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST = 2;
|
||||
@@ -169,7 +171,8 @@ public final class CredentialStorage extends Activity {
|
||||
}
|
||||
case UNLOCKED: {
|
||||
if (!checkKeyGuardQuality()) {
|
||||
new ConfigureKeyGuardDialog();
|
||||
final ConfigureKeyGuardDialog dialog = new ConfigureKeyGuardDialog();
|
||||
dialog.show(getFragmentManager(), ConfigureKeyGuardDialog.TAG);
|
||||
return;
|
||||
}
|
||||
installIfAvailable();
|
||||
@@ -188,7 +191,8 @@ public final class CredentialStorage extends Activity {
|
||||
private void ensureKeyGuard() {
|
||||
if (!checkKeyGuardQuality()) {
|
||||
// key guard not setup, doing so will initialize keystore
|
||||
new ConfigureKeyGuardDialog();
|
||||
final ConfigureKeyGuardDialog dialog = new ConfigureKeyGuardDialog();
|
||||
dialog.show(getFragmentManager(), ConfigureKeyGuardDialog.TAG);
|
||||
// will return to onResume after Activity
|
||||
return;
|
||||
}
|
||||
@@ -306,8 +310,7 @@ public final class CredentialStorage extends Activity {
|
||||
* Prompt for reset confirmation, resetting on confirmation, finishing otherwise.
|
||||
*/
|
||||
private class ResetDialog
|
||||
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener
|
||||
{
|
||||
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
|
||||
private boolean mResetConfirmed;
|
||||
|
||||
private ResetDialog() {
|
||||
@@ -321,11 +324,13 @@ public final class CredentialStorage extends Activity {
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
@Override public void onClick(DialogInterface dialog, int button) {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int button) {
|
||||
mResetConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
|
||||
}
|
||||
|
||||
@Override public void onDismiss(DialogInterface dialog) {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
if (mResetConfirmed) {
|
||||
mResetConfirmed = false;
|
||||
if (confirmKeyGuard(CONFIRM_CLEAR_SYSTEM_CREDENTIAL_REQUEST)) {
|
||||
@@ -342,7 +347,8 @@ public final class CredentialStorage extends Activity {
|
||||
*/
|
||||
private class ResetKeyStoreAndKeyChain extends AsyncTask<Void, Void, Boolean> {
|
||||
|
||||
@Override protected Boolean doInBackground(Void... unused) {
|
||||
@Override
|
||||
protected Boolean doInBackground(Void... unused) {
|
||||
|
||||
// Clear all the users credentials could have been installed in for this user.
|
||||
new LockPatternUtils(CredentialStorage.this).resetKeyStore(UserHandle.myUserId());
|
||||
@@ -362,14 +368,15 @@ public final class CredentialStorage extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onPostExecute(Boolean success) {
|
||||
@Override
|
||||
protected void onPostExecute(Boolean success) {
|
||||
if (success) {
|
||||
Toast.makeText(CredentialStorage.this,
|
||||
R.string.credentials_erased, Toast.LENGTH_SHORT).show();
|
||||
R.string.credentials_erased, Toast.LENGTH_SHORT).show();
|
||||
clearLegacyVpnIfEstablished();
|
||||
} else {
|
||||
Toast.makeText(CredentialStorage.this,
|
||||
R.string.credentials_not_erased, Toast.LENGTH_SHORT).show();
|
||||
R.string.credentials_not_erased, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
finish();
|
||||
}
|
||||
@@ -383,42 +390,6 @@ public final class CredentialStorage extends Activity {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prompt for key guard configuration confirmation.
|
||||
*/
|
||||
private class ConfigureKeyGuardDialog
|
||||
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener
|
||||
{
|
||||
private boolean mConfigureConfirmed;
|
||||
|
||||
private ConfigureKeyGuardDialog() {
|
||||
AlertDialog dialog = new AlertDialog.Builder(CredentialStorage.this)
|
||||
.setTitle(android.R.string.dialog_alert_title)
|
||||
.setMessage(R.string.credentials_configure_lock_screen_hint)
|
||||
.setPositiveButton(android.R.string.ok, this)
|
||||
.setNegativeButton(android.R.string.cancel, this)
|
||||
.create();
|
||||
dialog.setOnDismissListener(this);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
@Override public void onClick(DialogInterface dialog, int button) {
|
||||
mConfigureConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
|
||||
}
|
||||
|
||||
@Override public void onDismiss(DialogInterface dialog) {
|
||||
if (mConfigureConfirmed) {
|
||||
mConfigureConfirmed = false;
|
||||
Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
|
||||
intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY,
|
||||
MIN_PASSWORD_QUALITY);
|
||||
startActivity(intent);
|
||||
return;
|
||||
}
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that the caller is either certinstaller or Settings running in a profile of this user.
|
||||
*/
|
||||
@@ -504,8 +475,7 @@ public final class CredentialStorage extends Activity {
|
||||
* On unsuccessful unlock, retry by calling handleUnlockOrInstall.
|
||||
*/
|
||||
private class UnlockDialog implements TextWatcher,
|
||||
DialogInterface.OnClickListener, DialogInterface.OnDismissListener
|
||||
{
|
||||
DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
|
||||
private boolean mUnlockConfirmed;
|
||||
|
||||
private final Button mButton;
|
||||
@@ -544,21 +514,26 @@ public final class CredentialStorage extends Activity {
|
||||
mButton.setEnabled(false);
|
||||
}
|
||||
|
||||
@Override public void afterTextChanged(Editable editable) {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
mButton.setEnabled(mOldPassword == null || mOldPassword.getText().length() > 0);
|
||||
}
|
||||
|
||||
@Override public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override public void onTextChanged(CharSequence s,int start, int before, int count) {
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override public void onClick(DialogInterface dialog, int button) {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int button) {
|
||||
mUnlockConfirmed = (button == DialogInterface.BUTTON_POSITIVE);
|
||||
}
|
||||
|
||||
@Override public void onDismiss(DialogInterface dialog) {
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
if (mUnlockConfirmed) {
|
||||
mUnlockConfirmed = false;
|
||||
mError.setVisibility(View.VISIBLE);
|
||||
@@ -567,16 +542,16 @@ public final class CredentialStorage extends Activity {
|
||||
if (error == KeyStore.NO_ERROR) {
|
||||
mRetriesRemaining = -1;
|
||||
Toast.makeText(CredentialStorage.this,
|
||||
R.string.credentials_enabled,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
R.string.credentials_enabled,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
// aha, now we are unlocked, switch to key guard.
|
||||
// we'll end up back in onResume to install
|
||||
ensureKeyGuard();
|
||||
} else if (error == KeyStore.UNINITIALIZED) {
|
||||
mRetriesRemaining = -1;
|
||||
Toast.makeText(CredentialStorage.this,
|
||||
R.string.credentials_erased,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
R.string.credentials_erased,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
// we are reset, we can now set new password with key guard
|
||||
handleUnlockOrInstall();
|
||||
} else if (error >= KeyStore.WRONG_PASSWORD) {
|
||||
|
||||
@@ -888,7 +888,7 @@ public class CryptKeeper extends Activity implements TextView.OnEditorActionList
|
||||
mPasswordEntry.setEnabled(false);
|
||||
setBackFunctionality(false);
|
||||
|
||||
if (password.length() >= LockPatternUtils.MIN_LOCK_PATTERN_SIZE) {
|
||||
if (password.length() >= LockPatternUtils.MIN_LOCK_PASSWORD_SIZE) {
|
||||
new DecryptTask().execute(password);
|
||||
} else {
|
||||
// Allow user to make as many of these as they want.
|
||||
|
||||
@@ -37,6 +37,8 @@ import android.widget.Button;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.ConfirmLockPattern;
|
||||
|
||||
public class CryptKeeperSettings extends InstrumentedPreferenceFragment {
|
||||
private static final String TAG = "CryptKeeper";
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.v14.preference.PreferenceDialogFragment;
|
||||
import android.support.v7.preference.DialogPreference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
public class CustomDialogPreference extends DialogPreference {
|
||||
|
||||
private CustomPreferenceDialogFragment mFragment;
|
||||
|
||||
public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public CustomDialogPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public CustomDialogPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public CustomDialogPreference(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public boolean isDialogOpen() {
|
||||
return getDialog() != null && getDialog().isShowing();
|
||||
}
|
||||
|
||||
public Dialog getDialog() {
|
||||
return mFragment != null ? mFragment.getDialog() : null;
|
||||
}
|
||||
|
||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
|
||||
DialogInterface.OnClickListener listener) {
|
||||
}
|
||||
|
||||
protected void onDialogClosed(boolean positiveResult) {
|
||||
}
|
||||
|
||||
protected void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
|
||||
protected void onBindDialogView(View view) {
|
||||
}
|
||||
|
||||
private void setFragment(CustomPreferenceDialogFragment fragment) {
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
public static class CustomPreferenceDialogFragment extends PreferenceDialogFragment {
|
||||
|
||||
public static CustomPreferenceDialogFragment newInstance(String key) {
|
||||
final CustomPreferenceDialogFragment fragment = new CustomPreferenceDialogFragment();
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putString(ARG_KEY, key);
|
||||
fragment.setArguments(b);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
private CustomDialogPreference getCustomizablePreference() {
|
||||
return (CustomDialogPreference) getPreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||
super.onPrepareDialogBuilder(builder);
|
||||
getCustomizablePreference().setFragment(this);
|
||||
getCustomizablePreference().onPrepareDialogBuilder(builder, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDialogClosed(boolean positiveResult) {
|
||||
getCustomizablePreference().onDialogClosed(positiveResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(View view) {
|
||||
super.onBindDialogView(view);
|
||||
getCustomizablePreference().onBindDialogView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
super.onClick(dialog, which);
|
||||
getCustomizablePreference().onClick(dialog, which);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
import android.support.v14.preference.EditTextPreferenceDialogFragment;
|
||||
import android.support.v7.preference.EditTextPreference;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
public class CustomEditTextPreference extends EditTextPreference {
|
||||
|
||||
private CustomPreferenceDialogFragment mFragment;
|
||||
|
||||
public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
}
|
||||
|
||||
public CustomEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
public CustomEditTextPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public CustomEditTextPreference(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public EditText getEditText() {
|
||||
return mFragment != null ? (EditText) mFragment.getDialog().findViewById(android.R.id.edit)
|
||||
: null;
|
||||
}
|
||||
|
||||
public boolean isDialogOpen() {
|
||||
return getDialog() != null && getDialog().isShowing();
|
||||
}
|
||||
|
||||
public Dialog getDialog() {
|
||||
return mFragment != null ? mFragment.getDialog() : null;
|
||||
}
|
||||
|
||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder,
|
||||
DialogInterface.OnClickListener listener) {
|
||||
}
|
||||
|
||||
protected void onDialogClosed(boolean positiveResult) {
|
||||
}
|
||||
|
||||
protected void onClick(DialogInterface dialog, int which) {
|
||||
}
|
||||
|
||||
protected void onBindDialogView(View view) {
|
||||
}
|
||||
|
||||
private void setFragment(CustomPreferenceDialogFragment fragment) {
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
public static class CustomPreferenceDialogFragment extends EditTextPreferenceDialogFragment {
|
||||
|
||||
public static CustomPreferenceDialogFragment newInstance(String key) {
|
||||
final CustomPreferenceDialogFragment fragment = new CustomPreferenceDialogFragment();
|
||||
final Bundle b = new Bundle(1);
|
||||
b.putString(ARG_KEY, key);
|
||||
fragment.setArguments(b);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
private CustomEditTextPreference getCustomizablePreference() {
|
||||
return (CustomEditTextPreference) getPreference();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindDialogView(View view) {
|
||||
super.onBindDialogView(view);
|
||||
getCustomizablePreference().onBindDialogView(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||
super.onPrepareDialogBuilder(builder);
|
||||
getCustomizablePreference().setFragment(this);
|
||||
getCustomizablePreference().onPrepareDialogBuilder(builder, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDialogClosed(boolean positiveResult) {
|
||||
super.onDialogClosed(positiveResult);
|
||||
getCustomizablePreference().onDialogClosed(positiveResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
super.onClick(dialog, which);
|
||||
getCustomizablePreference().onClick(dialog, which);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,6 @@ import android.provider.SearchIndexableResource;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.dashboard.SummaryLoader;
|
||||
import com.android.settings.deviceinfo.AdditionalSystemUpdatePreferenceController;
|
||||
@@ -42,6 +41,7 @@ import com.android.settings.deviceinfo.SafetyInfoPreferenceController;
|
||||
import com.android.settings.deviceinfo.SecurityPatchPreferenceController;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -17,18 +17,18 @@
|
||||
package com.android.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
import com.android.internal.hardware.AmbientDisplayConfiguration;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.display.AmbientDisplayPreferenceController;
|
||||
import com.android.settings.display.AutoBrightnessPreferenceController;
|
||||
import com.android.settings.display.AutoRotatePreferenceController;
|
||||
import com.android.settings.display.BrightnessLevelPreferenceController;
|
||||
import com.android.settings.display.CameraGesturePreferenceController;
|
||||
import com.android.settings.display.DozePreferenceController;
|
||||
import com.android.settings.display.ColorModePreferenceController;
|
||||
import com.android.settings.display.FontSizePreferenceController;
|
||||
import com.android.settings.display.LiftToWakePreferenceController;
|
||||
import com.android.settings.display.NightDisplayPreferenceController;
|
||||
@@ -39,10 +39,9 @@ import com.android.settings.display.ThemePreferenceController;
|
||||
import com.android.settings.display.TimeoutPreferenceController;
|
||||
import com.android.settings.display.VrDisplayPreferenceController;
|
||||
import com.android.settings.display.WallpaperPreferenceController;
|
||||
import com.android.settings.gestures.DoubleTapScreenPreferenceController;
|
||||
import com.android.settings.gestures.PickupGesturePreferenceController;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -50,12 +49,11 @@ import java.util.List;
|
||||
public class DisplaySettings extends DashboardFragment {
|
||||
private static final String TAG = "DisplaySettings";
|
||||
|
||||
public static final String KEY_AUTO_BRIGHTNESS = "auto_brightness";
|
||||
public static final String KEY_DISPLAY_SIZE = "screen_zoom";
|
||||
|
||||
private static final String KEY_AUTO_BRIGHTNESS = "auto_brightness";
|
||||
private static final String KEY_SCREEN_TIMEOUT = "screen_timeout";
|
||||
private static final String KEY_PICK_UP = "gesture_pick_up_display_summary";
|
||||
private static final String KEY_DOUBLE_TAP_SCREEN = "gesture_double_tap_screen_display_summary";
|
||||
private static final String KEY_AMBIENT_DISPLAY = "ambient_display";
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
@@ -92,25 +90,24 @@ public class DisplaySettings extends DashboardFragment {
|
||||
Context context, Lifecycle lifecycle) {
|
||||
final List<PreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new AutoBrightnessPreferenceController(context, KEY_AUTO_BRIGHTNESS));
|
||||
controllers.add(new AutoRotatePreferenceController(context));
|
||||
controllers.add(new AutoRotatePreferenceController(context, lifecycle));
|
||||
controllers.add(new CameraGesturePreferenceController(context));
|
||||
controllers.add(new DozePreferenceController(context));
|
||||
controllers.add(new FontSizePreferenceController(context));
|
||||
controllers.add(new LiftToWakePreferenceController(context));
|
||||
controllers.add(new NightDisplayPreferenceController(context));
|
||||
controllers.add(new NightModePreferenceController(context));
|
||||
controllers.add(new ScreenSaverPreferenceController(context));
|
||||
AmbientDisplayConfiguration ambientDisplayConfig = new AmbientDisplayConfiguration(context);
|
||||
controllers.add(new PickupGesturePreferenceController(
|
||||
context, lifecycle, ambientDisplayConfig, UserHandle.myUserId(), KEY_PICK_UP));
|
||||
controllers.add(new DoubleTapScreenPreferenceController(
|
||||
context, lifecycle, ambientDisplayConfig, UserHandle.myUserId(),
|
||||
KEY_DOUBLE_TAP_SCREEN));
|
||||
controllers.add(new AmbientDisplayPreferenceController(
|
||||
context,
|
||||
new AmbientDisplayConfiguration(context),
|
||||
KEY_AMBIENT_DISPLAY));
|
||||
controllers.add(new TapToWakePreferenceController(context));
|
||||
controllers.add(new TimeoutPreferenceController(context, KEY_SCREEN_TIMEOUT));
|
||||
controllers.add(new VrDisplayPreferenceController(context));
|
||||
controllers.add(new WallpaperPreferenceController(context));
|
||||
controllers.add(new ThemePreferenceController(context));
|
||||
controllers.add(new BrightnessLevelPreferenceController(context, lifecycle));
|
||||
controllers.add(new ColorModePreferenceController(context));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@@ -131,6 +128,8 @@ public class DisplaySettings extends DashboardFragment {
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
List<String> keys = super.getNonIndexableKeys(context);
|
||||
keys.add(KEY_DISPLAY_SIZE);
|
||||
keys.add(WallpaperPreferenceController.KEY_WALLPAPER);
|
||||
keys.add(KEY_AMBIENT_DISPLAY);
|
||||
return keys;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,364 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2012 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.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.util.Log;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MenuItem.OnMenuItemClickListener;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Switch;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
import com.android.settingslib.dream.DreamBackend;
|
||||
import com.android.settingslib.dream.DreamBackend.DreamInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DreamSettings extends SettingsPreferenceFragment implements
|
||||
SwitchBar.OnSwitchChangeListener {
|
||||
private static final String TAG = DreamSettings.class.getSimpleName();
|
||||
static final boolean DEBUG = false;
|
||||
private static final int DIALOG_WHEN_TO_DREAM = 1;
|
||||
private static final String PACKAGE_SCHEME = "package";
|
||||
|
||||
private final PackageReceiver mPackageReceiver = new PackageReceiver();
|
||||
|
||||
private Context mContext;
|
||||
private DreamBackend mBackend;
|
||||
private SwitchBar mSwitchBar;
|
||||
private MenuItem[] mMenuItemsWhenEnabled;
|
||||
private boolean mRefreshing;
|
||||
|
||||
@Override
|
||||
public int getHelpResource() {
|
||||
return R.string.help_url_dreams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
logd("onAttach(%s)", activity.getClass().getSimpleName());
|
||||
super.onAttach(activity);
|
||||
mContext = activity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.DREAM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
logd("onCreate(%s)", icicle);
|
||||
super.onCreate(icicle);
|
||||
|
||||
mBackend = new DreamBackend(getActivity());
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSwitchChanged(Switch switchView, boolean isChecked) {
|
||||
if (!mRefreshing) {
|
||||
mBackend.setEnabled(isChecked);
|
||||
refreshFromBackend();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
logd("onStart()");
|
||||
super.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
logd("onDestroyView()");
|
||||
super.onDestroyView();
|
||||
|
||||
mSwitchBar.removeOnSwitchChangeListener(this);
|
||||
mSwitchBar.hide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
logd("onActivityCreated(%s)", savedInstanceState);
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
|
||||
TextView emptyView = (TextView) getView().findViewById(android.R.id.empty);
|
||||
emptyView.setText(R.string.screensaver_settings_disabled_prompt);
|
||||
setEmptyView(emptyView);
|
||||
|
||||
final SettingsActivity sa = (SettingsActivity) getActivity();
|
||||
mSwitchBar = sa.getSwitchBar();
|
||||
mSwitchBar.addOnSwitchChangeListener(this);
|
||||
mSwitchBar.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
logd("onCreateOptionsMenu()");
|
||||
|
||||
boolean isEnabled = mBackend.isEnabled();
|
||||
|
||||
// create "start" action
|
||||
MenuItem start = createMenuItem(menu, R.string.screensaver_settings_dream_start,
|
||||
MenuItem.SHOW_AS_ACTION_NEVER,
|
||||
isEnabled, new Runnable(){
|
||||
@Override
|
||||
public void run() {
|
||||
mBackend.startDreaming();
|
||||
}});
|
||||
|
||||
// create "when to dream" overflow menu item
|
||||
MenuItem whenToDream = createMenuItem(menu,
|
||||
R.string.screensaver_settings_when_to_dream,
|
||||
MenuItem.SHOW_AS_ACTION_NEVER,
|
||||
isEnabled,
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showDialog(DIALOG_WHEN_TO_DREAM);
|
||||
}});
|
||||
|
||||
// create "help" overflow menu item (make sure it appears last)
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
|
||||
mMenuItemsWhenEnabled = new MenuItem[] { start, whenToDream };
|
||||
}
|
||||
|
||||
private MenuItem createMenuItem(Menu menu,
|
||||
int titleRes, int actionEnum, boolean isEnabled, final Runnable onClick) {
|
||||
MenuItem item = menu.add(titleRes);
|
||||
item.setShowAsAction(actionEnum);
|
||||
item.setEnabled(isEnabled);
|
||||
item.setOnMenuItemClickListener(new OnMenuItemClickListener() {
|
||||
@Override
|
||||
public boolean onMenuItemClick(MenuItem item) {
|
||||
onClick.run();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
logd("onCreateDialog(%s)", dialogId);
|
||||
if (dialogId == DIALOG_WHEN_TO_DREAM)
|
||||
return createWhenToDreamDialog();
|
||||
return super.onCreateDialog(dialogId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
if (dialogId == DIALOG_WHEN_TO_DREAM) {
|
||||
return MetricsEvent.DIALOG_DREAM_START_DELAY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Dialog createWhenToDreamDialog() {
|
||||
final CharSequence[] items = {
|
||||
mContext.getString(R.string.screensaver_settings_summary_dock),
|
||||
mContext.getString(R.string.screensaver_settings_summary_sleep),
|
||||
mContext.getString(R.string.screensaver_settings_summary_either_short)
|
||||
};
|
||||
|
||||
int initialSelection = mBackend.isActivatedOnDock() && mBackend.isActivatedOnSleep() ? 2
|
||||
: mBackend.isActivatedOnDock() ? 0
|
||||
: mBackend.isActivatedOnSleep() ? 1
|
||||
: -1;
|
||||
|
||||
return new AlertDialog.Builder(mContext)
|
||||
.setTitle(R.string.screensaver_settings_when_to_dream)
|
||||
.setSingleChoiceItems(items, initialSelection, new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int item) {
|
||||
mBackend.setActivatedOnDock(item == 0 || item == 2);
|
||||
mBackend.setActivatedOnSleep(item == 1 || item == 2);
|
||||
dialog.dismiss();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
logd("onPause()");
|
||||
super.onPause();
|
||||
|
||||
mContext.unregisterReceiver(mPackageReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
logd("onResume()");
|
||||
super.onResume();
|
||||
refreshFromBackend();
|
||||
|
||||
// listen for package changes
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_PACKAGE_ADDED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
|
||||
filter.addAction(Intent.ACTION_PACKAGE_REPLACED);
|
||||
filter.addDataScheme(PACKAGE_SCHEME);
|
||||
mContext.registerReceiver(mPackageReceiver , filter);
|
||||
}
|
||||
|
||||
public static int getSummaryResource(Context context) {
|
||||
DreamBackend backend = new DreamBackend(context);
|
||||
boolean isEnabled = backend.isEnabled();
|
||||
boolean activatedOnSleep = backend.isActivatedOnSleep();
|
||||
boolean activatedOnDock = backend.isActivatedOnDock();
|
||||
boolean activatedOnEither = activatedOnSleep && activatedOnDock;
|
||||
return !isEnabled ? R.string.screensaver_settings_summary_off
|
||||
: activatedOnEither ? R.string.screensaver_settings_summary_either_long
|
||||
: activatedOnSleep ? R.string.screensaver_settings_summary_sleep
|
||||
: activatedOnDock ? R.string.screensaver_settings_summary_dock
|
||||
: 0;
|
||||
}
|
||||
|
||||
public static CharSequence getSummaryTextWithDreamName(Context context) {
|
||||
DreamBackend backend = new DreamBackend(context);
|
||||
boolean isEnabled = backend.isEnabled();
|
||||
if (!isEnabled) {
|
||||
return context.getString(R.string.screensaver_settings_summary_off);
|
||||
} else {
|
||||
return backend.getActiveDreamName();
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshFromBackend() {
|
||||
logd("refreshFromBackend()");
|
||||
mRefreshing = true;
|
||||
boolean dreamsEnabled = mBackend.isEnabled();
|
||||
if (mSwitchBar.isChecked() != dreamsEnabled) {
|
||||
mSwitchBar.setChecked(dreamsEnabled);
|
||||
}
|
||||
|
||||
if (getPreferenceScreen() == null) {
|
||||
setPreferenceScreen(getPreferenceManager().createPreferenceScreen(getContext()));
|
||||
}
|
||||
getPreferenceScreen().removeAll();
|
||||
if (dreamsEnabled) {
|
||||
List<DreamBackend.DreamInfo> dreamInfos = mBackend.getDreamInfos();
|
||||
final int N = dreamInfos.size();
|
||||
for (int i = 0; i < N; i++) {
|
||||
getPreferenceScreen().addPreference(
|
||||
new DreamInfoPreference(getPrefContext(), dreamInfos.get(i)));
|
||||
}
|
||||
}
|
||||
if (mMenuItemsWhenEnabled != null) {
|
||||
for (MenuItem menuItem : mMenuItemsWhenEnabled) {
|
||||
menuItem.setEnabled(dreamsEnabled);
|
||||
}
|
||||
}
|
||||
mRefreshing = false;
|
||||
}
|
||||
|
||||
private static void logd(String msg, Object... args) {
|
||||
if (DEBUG) Log.d(TAG, args == null || args.length == 0 ? msg : String.format(msg, args));
|
||||
}
|
||||
|
||||
private class DreamInfoPreference extends Preference {
|
||||
|
||||
private final DreamInfo mInfo;
|
||||
|
||||
public DreamInfoPreference(Context context, DreamInfo info) {
|
||||
super(context);
|
||||
mInfo = info;
|
||||
setLayoutResource(R.layout.dream_info_row);
|
||||
setTitle(mInfo.caption);
|
||||
setIcon(mInfo.icon);
|
||||
}
|
||||
|
||||
public void onBindViewHolder(final PreferenceViewHolder holder) {
|
||||
super.onBindViewHolder(holder);
|
||||
|
||||
// bind radio button
|
||||
RadioButton radioButton = (RadioButton) holder.findViewById(android.R.id.button1);
|
||||
radioButton.setChecked(mInfo.isActive);
|
||||
radioButton.setOnTouchListener(new OnTouchListener() {
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event) {
|
||||
holder.itemView.onTouchEvent(event);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// bind settings button + divider
|
||||
boolean showSettings = mInfo.settingsComponentName != null;
|
||||
View settingsDivider = holder.findViewById(R.id.divider);
|
||||
settingsDivider.setVisibility(showSettings ? View.VISIBLE : View.INVISIBLE);
|
||||
|
||||
ImageView settingsButton = (ImageView) holder.findViewById(android.R.id.button2);
|
||||
settingsButton.setVisibility(showSettings ? View.VISIBLE : View.INVISIBLE);
|
||||
settingsButton.setAlpha(mInfo.isActive ? 1f : Utils.DISABLED_ALPHA);
|
||||
settingsButton.setEnabled(mInfo.isActive);
|
||||
settingsButton.setFocusable(mInfo.isActive);
|
||||
settingsButton.setOnClickListener(new OnClickListener(){
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mBackend.launchSettings(mInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void performClick() {
|
||||
if (mInfo.isActive)
|
||||
return;
|
||||
for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
|
||||
DreamInfoPreference preference =
|
||||
(DreamInfoPreference) getPreferenceScreen().getPreference(i);
|
||||
preference.mInfo.isActive = false;
|
||||
preference.notifyChanged();
|
||||
}
|
||||
mInfo.isActive = true;
|
||||
mBackend.setActiveDream(mInfo.componentName);
|
||||
notifyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private class PackageReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
logd("PackageReceiver.onReceive");
|
||||
refreshFromBackend();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.android.settingslib.CustomEditTextPreference;
|
||||
|
||||
/**
|
||||
* TODO: Add a soft dialpad for PIN entry.
|
||||
*/
|
||||
@@ -31,9 +33,9 @@ class EditPinPreference extends CustomEditTextPreference {
|
||||
interface OnPinEnteredListener {
|
||||
void onPinEntered(EditPinPreference preference, boolean positiveResult);
|
||||
}
|
||||
|
||||
|
||||
private OnPinEnteredListener mPinListener;
|
||||
|
||||
|
||||
public EditPinPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
@@ -41,7 +43,7 @@ class EditPinPreference extends CustomEditTextPreference {
|
||||
public EditPinPreference(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
|
||||
public void setOnPinEnteredListener(OnPinEnteredListener listener) {
|
||||
mPinListener = listener;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.app.Activity;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
@@ -34,7 +33,6 @@ import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settings.search.SearchIndexableRaw;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
|
||||
@@ -106,7 +104,6 @@ public class EncryptionAndCredential extends SettingsPreferenceFragment implemen
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Credential storage
|
||||
mKeyStore = KeyStore.getInstance(); // needs to be initialized for onResume()
|
||||
|
||||
@@ -168,7 +165,7 @@ public class EncryptionAndCredential extends SettingsPreferenceFragment implemen
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_security;
|
||||
return R.string.help_url_encryption;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,83 +179,57 @@ public class EncryptionAndCredential extends SettingsPreferenceFragment implemen
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(
|
||||
Context context, boolean enabled) {
|
||||
final List<SearchIndexableResource> index = new ArrayList<SearchIndexableResource>();
|
||||
final List<SearchIndexableResource> index = new ArrayList<>();
|
||||
|
||||
final DevicePolicyManager dpm = (DevicePolicyManager)
|
||||
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
final UserManager um = UserManager.get(context);
|
||||
|
||||
if (um.isAdminUser()) {
|
||||
switch (dpm.getStorageEncryptionStatus()) {
|
||||
case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
|
||||
// The device is currently encrypted.
|
||||
index.add(getSearchResource(context, R.xml.security_settings_encrypted));
|
||||
break;
|
||||
case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE:
|
||||
// This device supports encryption but isn't encrypted.
|
||||
index.add(getSearchResource(context, R.xml.security_settings_unencrypted));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Add everything. We will suppress some of them in getNonIndexableKeys()
|
||||
index.add(getSearchResource(context, R.xml.encryption_and_credential));
|
||||
index.add(getSearchResource(context, R.xml.security_settings_encrypted));
|
||||
index.add(getSearchResource(context, R.xml.security_settings_unencrypted));
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isPageSearchEnabled(Context context) {
|
||||
final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
return um.isAdminUser();
|
||||
}
|
||||
|
||||
private SearchIndexableResource getSearchResource(Context context, int xmlResId) {
|
||||
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||
sir.xmlResId = xmlResId;
|
||||
return sir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
|
||||
final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>();
|
||||
final Resources res = context.getResources();
|
||||
|
||||
final String screenTitle = res.getString(
|
||||
R.string.encryption_and_credential_settings_title);
|
||||
|
||||
SearchIndexableRaw data = new SearchIndexableRaw(context);
|
||||
data.title = screenTitle;
|
||||
data.screenTitle = screenTitle;
|
||||
result.add(data);
|
||||
|
||||
final UserManager um = UserManager.get(context);
|
||||
if (!um.isAdminUser()) {
|
||||
int resId = um.isLinkedUser() ?
|
||||
R.string.profile_info_settings_title : R.string.user_info_settings_title;
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
data.title = res.getString(resId);
|
||||
data.screenTitle = screenTitle;
|
||||
result.add(data);
|
||||
}
|
||||
|
||||
// Credential storage
|
||||
if (!um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) {
|
||||
KeyStore keyStore = KeyStore.getInstance();
|
||||
|
||||
final int storageSummaryRes = keyStore.isHardwareBacked() ?
|
||||
R.string.credential_storage_type_hardware :
|
||||
R.string.credential_storage_type_software;
|
||||
|
||||
data = new SearchIndexableRaw(context);
|
||||
data.title = res.getString(storageSummaryRes);
|
||||
data.screenTitle = screenTitle;
|
||||
result.add(data);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
final List<String> keys = new ArrayList<String>();
|
||||
|
||||
final UserManager um = UserManager.get(context);
|
||||
final List<String> keys = super.getNonIndexableKeys(context);
|
||||
if (!isPageSearchEnabled(context)) {
|
||||
return keys;
|
||||
}
|
||||
final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
|
||||
if (um.hasUserRestriction(UserManager.DISALLOW_CONFIG_CREDENTIALS)) {
|
||||
keys.add(KEY_CREDENTIALS_MANAGER);
|
||||
keys.add(KEY_RESET_CREDENTIALS);
|
||||
keys.add(KEY_CREDENTIALS_INSTALL);
|
||||
keys.add(KEY_CREDENTIAL_STORAGE_TYPE);
|
||||
keys.add(KEY_USER_CREDENTIALS);
|
||||
}
|
||||
|
||||
final DevicePolicyManager dpm = (DevicePolicyManager)
|
||||
context.getSystemService(Context.DEVICE_POLICY_SERVICE);
|
||||
switch (dpm.getStorageEncryptionStatus()) {
|
||||
case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE:
|
||||
// The device is currently encrypted. Disable security_settings_unencrypted
|
||||
keys.addAll(getNonIndexableKeysFromXml(
|
||||
context, R.xml.security_settings_unencrypted));
|
||||
break;
|
||||
default:
|
||||
// This device supports encryption but isn't encrypted.
|
||||
keys.addAll(getNonIndexableKeysFromXml(
|
||||
context, R.xml.security_settings_encrypted));
|
||||
break;
|
||||
}
|
||||
|
||||
return keys;
|
||||
|
||||
@@ -17,23 +17,27 @@
|
||||
package com.android.settings;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.setupwizardlib.GlifLayout;
|
||||
|
||||
import java.util.List;
|
||||
@@ -53,6 +57,12 @@ public class EncryptionInterstitial extends SettingsActivity {
|
||||
return modIntent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
|
||||
resid = SetupWizardUtils.getTheme(getIntent());
|
||||
super.onApplyThemeResource(theme, resid, first);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValidFragment(String fragmentName) {
|
||||
return EncryptionInterstitialFragment.class.getName().equals(fragmentName);
|
||||
@@ -74,10 +84,8 @@ public class EncryptionInterstitial extends SettingsActivity {
|
||||
layout.setFitsSystemWindows(false);
|
||||
}
|
||||
|
||||
public static class EncryptionInterstitialFragment extends SettingsPreferenceFragment
|
||||
implements View.OnClickListener, DialogInterface.OnClickListener {
|
||||
|
||||
private static final int ACCESSIBILITY_WARNING_DIALOG = 1;
|
||||
public static class EncryptionInterstitialFragment extends InstrumentedFragment
|
||||
implements View.OnClickListener {
|
||||
|
||||
private View mRequirePasswordToDecrypt;
|
||||
private View mDontRequirePasswordToDecrypt;
|
||||
@@ -164,7 +172,10 @@ public class EncryptionInterstitial extends SettingsActivity {
|
||||
final boolean accEn = AccessibilityManager.getInstance(getActivity()).isEnabled();
|
||||
if (accEn && !mPasswordRequired) {
|
||||
setRequirePasswordState(false); // clear the UI state
|
||||
showDialog(ACCESSIBILITY_WARNING_DIALOG);
|
||||
AccessibilityWarningDialogFragment.newInstance(mRequestedPasswordQuality)
|
||||
.show(
|
||||
getChildFragmentManager(),
|
||||
AccessibilityWarningDialogFragment.TAG);
|
||||
} else {
|
||||
setRequirePasswordState(true);
|
||||
startLockIntent();
|
||||
@@ -175,72 +186,93 @@ public class EncryptionInterstitial extends SettingsActivity {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(int dialogId) {
|
||||
switch(dialogId) {
|
||||
case ACCESSIBILITY_WARNING_DIALOG: {
|
||||
final int titleId;
|
||||
final int messageId;
|
||||
switch (mRequestedPasswordQuality) {
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
|
||||
titleId = R.string.encrypt_talkback_dialog_require_pattern;
|
||||
messageId = R.string.encrypt_talkback_dialog_message_pattern;
|
||||
break;
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
|
||||
titleId = R.string.encrypt_talkback_dialog_require_pin;
|
||||
messageId = R.string.encrypt_talkback_dialog_message_pin;
|
||||
break;
|
||||
default:
|
||||
titleId = R.string.encrypt_talkback_dialog_require_password;
|
||||
messageId = R.string.encrypt_talkback_dialog_message_password;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
List<AccessibilityServiceInfo> list =
|
||||
AccessibilityManager.getInstance(getActivity())
|
||||
.getEnabledAccessibilityServiceList(
|
||||
AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
|
||||
final CharSequence exampleAccessibility;
|
||||
if (list.isEmpty()) {
|
||||
// This should never happen. But we shouldn't crash
|
||||
exampleAccessibility = "";
|
||||
} else {
|
||||
exampleAccessibility = list.get(0).getResolveInfo()
|
||||
.loadLabel(getPackageManager());
|
||||
}
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setTitle(titleId)
|
||||
.setMessage(getString(messageId, exampleAccessibility))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(android.R.string.ok, this)
|
||||
.setNegativeButton(android.R.string.cancel, this)
|
||||
.create();
|
||||
}
|
||||
default: throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDialogMetricsCategory(int dialogId) {
|
||||
if (dialogId == ACCESSIBILITY_WARNING_DIALOG) {
|
||||
return MetricsEvent.DIALOG_ENCRYPTION_INTERSTITIAL_ACCESSIBILITY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void setRequirePasswordState(boolean required) {
|
||||
mPasswordRequired = required;
|
||||
}
|
||||
|
||||
public void finish() {
|
||||
Activity activity = getActivity();
|
||||
if (activity == null) return;
|
||||
if (getFragmentManager().getBackStackEntryCount() > 0) {
|
||||
getFragmentManager().popBackStack();
|
||||
} else {
|
||||
activity.finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class AccessibilityWarningDialogFragment extends InstrumentedDialogFragment
|
||||
implements DialogInterface.OnClickListener {
|
||||
|
||||
public static final String TAG = "AccessibilityWarningDialog";
|
||||
|
||||
public static AccessibilityWarningDialogFragment newInstance(int passwordQuality) {
|
||||
AccessibilityWarningDialogFragment fragment = new AccessibilityWarningDialogFragment();
|
||||
Bundle args = new Bundle(1);
|
||||
args.putInt(EXTRA_PASSWORD_QUALITY, passwordQuality);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final int titleId;
|
||||
final int messageId;
|
||||
switch (getArguments().getInt(EXTRA_PASSWORD_QUALITY)) {
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
|
||||
titleId = R.string.encrypt_talkback_dialog_require_pattern;
|
||||
messageId = R.string.encrypt_talkback_dialog_message_pattern;
|
||||
break;
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
|
||||
case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
|
||||
titleId = R.string.encrypt_talkback_dialog_require_pin;
|
||||
messageId = R.string.encrypt_talkback_dialog_message_pin;
|
||||
break;
|
||||
default:
|
||||
titleId = R.string.encrypt_talkback_dialog_require_password;
|
||||
messageId = R.string.encrypt_talkback_dialog_message_password;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
final Activity activity = getActivity();
|
||||
List<AccessibilityServiceInfo> list =
|
||||
AccessibilityManager.getInstance(activity)
|
||||
.getEnabledAccessibilityServiceList(
|
||||
AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
|
||||
final CharSequence exampleAccessibility;
|
||||
if (list.isEmpty()) {
|
||||
// This should never happen. But we shouldn't crash
|
||||
exampleAccessibility = "";
|
||||
} else {
|
||||
exampleAccessibility = list.get(0).getResolveInfo()
|
||||
.loadLabel(activity.getPackageManager());
|
||||
}
|
||||
return new AlertDialog.Builder(activity)
|
||||
.setTitle(titleId)
|
||||
.setMessage(getString(messageId, exampleAccessibility))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(android.R.string.ok, this)
|
||||
.setNegativeButton(android.R.string.cancel, this)
|
||||
.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.DIALOG_ENCRYPTION_INTERSTITIAL_ACCESSIBILITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
setRequirePasswordState(true);
|
||||
startLockIntent();
|
||||
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||
setRequirePasswordState(false);
|
||||
EncryptionInterstitialFragment fragment =
|
||||
(EncryptionInterstitialFragment) getParentFragment();
|
||||
if (fragment != null) {
|
||||
if (which == DialogInterface.BUTTON_POSITIVE) {
|
||||
fragment.setRequirePasswordState(true);
|
||||
fragment.startLockIntent();
|
||||
} else if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||
fragment.setRequirePasswordState(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,11 @@ public class HelpTrampoline extends Activity {
|
||||
|
||||
final Intent intent = HelpUtils.getHelpIntent(this, value, null);
|
||||
if (intent != null) {
|
||||
startActivity(intent);
|
||||
/*
|
||||
* TODO: b/38230998.
|
||||
* Move to startActivity once the HelpUtils.getHelpIntent is refactored
|
||||
*/
|
||||
startActivityForResult(intent, 0);
|
||||
}
|
||||
|
||||
} catch (Resources.NotFoundException | ActivityNotFoundException e) {
|
||||
|
||||
@@ -289,6 +289,11 @@ public class IccLockSettings extends SettingsPreferenceFragment
|
||||
getContext().unregisterReceiver(mSimStateReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_icc_lock;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle out) {
|
||||
// Need to store this state for slider open/close
|
||||
|
||||
@@ -16,11 +16,14 @@
|
||||
|
||||
package com.android.settings;
|
||||
|
||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AuthenticatorDescription;
|
||||
import android.app.Activity;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
@@ -32,7 +35,10 @@ import android.os.Environment;
|
||||
import android.os.SystemProperties;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.telephony.euicc.EuiccManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -47,13 +53,12 @@ import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.widget.CarrierDemoPasswordDialogFragment;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.ConfirmLockPattern;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
/**
|
||||
* Confirm and execute a reset of the device to a clean "just out of the box"
|
||||
* state. Multiple confirmations are required: first, a general "are you sure
|
||||
@@ -64,18 +69,18 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
*
|
||||
* This is the initial screen.
|
||||
*/
|
||||
public class MasterClear extends OptionsMenuFragment
|
||||
implements CarrierDemoPasswordDialogFragment.Callback {
|
||||
public class MasterClear extends OptionsMenuFragment {
|
||||
private static final String TAG = "MasterClear";
|
||||
|
||||
private static final int KEYGUARD_REQUEST = 55;
|
||||
|
||||
static final String ERASE_EXTERNAL_EXTRA = "erase_sd";
|
||||
static final String ERASE_ESIMS_EXTRA = "erase_esim";
|
||||
|
||||
private View mContentView;
|
||||
private Button mInitiateButton;
|
||||
private View mExternalStorageContainer;
|
||||
private CheckBox mExternalStorage;
|
||||
@VisibleForTesting CheckBox mExternalStorage;
|
||||
private ScrollView mScrollView;
|
||||
|
||||
private final OnGlobalLayoutListener mOnGlobalLayoutListener = new OnGlobalLayoutListener() {
|
||||
@@ -115,9 +120,12 @@ public class MasterClear extends OptionsMenuFragment
|
||||
}
|
||||
}
|
||||
|
||||
private void showFinalConfirmation() {
|
||||
@VisibleForTesting
|
||||
void showFinalConfirmation() {
|
||||
Bundle args = new Bundle();
|
||||
args.putBoolean(ERASE_EXTERNAL_EXTRA, mExternalStorage.isChecked());
|
||||
// TODO: Offer the user a choice to wipe eSIMs when it is technically feasible to do so.
|
||||
args.putBoolean(ERASE_ESIMS_EXTRA, true);
|
||||
((SettingsActivity) getActivity()).startPreferencePanel(
|
||||
this, MasterClearConfirm.class.getName(),
|
||||
args, R.string.master_clear_confirm_title, null, null, 0);
|
||||
@@ -127,15 +135,21 @@ public class MasterClear extends OptionsMenuFragment
|
||||
* If the user clicks to begin the reset sequence, we next require a
|
||||
* keyguard confirmation if the user has currently enabled one. If there
|
||||
* is no keyguard available, we simply go to the final confirmation prompt.
|
||||
*
|
||||
* If the user is in demo mode, route to the demo mode app for confirmation.
|
||||
*/
|
||||
private final Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
|
||||
@VisibleForTesting
|
||||
protected final Button.OnClickListener mInitiateListener = new Button.OnClickListener() {
|
||||
|
||||
public void onClick(View v) {
|
||||
if ( Utils.isCarrierDemoUser(v.getContext())) {
|
||||
// Require the carrier password before displaying the final confirmation.
|
||||
final FragmentManager fm = getChildFragmentManager();
|
||||
if (fm != null && !fm.isDestroyed()) {
|
||||
new CarrierDemoPasswordDialogFragment().show(fm, null /* tag */);
|
||||
public void onClick(View view) {
|
||||
final Context context = view.getContext();
|
||||
if (Utils.isDemoUser(context)) {
|
||||
final ComponentName componentName = Utils.getDeviceOwnerComponent(context);
|
||||
if (componentName != null) {
|
||||
final Intent requestFactoryReset = new Intent()
|
||||
.setPackage(componentName.getPackageName())
|
||||
.setAction(Intent.ACTION_FACTORY_RESET);
|
||||
context.startActivity(requestFactoryReset);
|
||||
}
|
||||
} else if (!runKeyguardConfirmation(KEYGUARD_REQUEST)) {
|
||||
showFinalConfirmation();
|
||||
@@ -143,11 +157,6 @@ public class MasterClear extends OptionsMenuFragment
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onPasswordVerified() {
|
||||
showFinalConfirmation();
|
||||
}
|
||||
|
||||
/**
|
||||
* In its initial state, the activity presents a button for the user to
|
||||
* click in order to initiate a confirmation sequence. This method is
|
||||
@@ -198,6 +207,14 @@ public class MasterClear extends OptionsMenuFragment
|
||||
});
|
||||
}
|
||||
|
||||
if (showWipeEuicc()) {
|
||||
final View esimAlsoErased = mContentView.findViewById(R.id.also_erases_esim);
|
||||
esimAlsoErased.setVisibility(View.VISIBLE);
|
||||
|
||||
final View noCancelMobilePlan = mContentView.findViewById(R.id.no_cancel_mobile_plan);
|
||||
noCancelMobilePlan.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
final UserManager um = (UserManager) getActivity().getSystemService(Context.USER_SERVICE);
|
||||
loadAccountList(um);
|
||||
StringBuffer contentDescription = new StringBuffer();
|
||||
@@ -220,6 +237,28 @@ public class MasterClear extends OptionsMenuFragment
|
||||
mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(mOnGlobalLayoutListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to show strings indicating that the eUICC will be wiped.
|
||||
*
|
||||
* <p>We show the strings on any device which supports eUICC as long as the eUICC was ever
|
||||
* provisioned (that is, at least one profile was ever downloaded onto it).
|
||||
*/
|
||||
@VisibleForTesting
|
||||
boolean showWipeEuicc() {
|
||||
Context context = getContext();
|
||||
if (!isEuiccEnabled(context)) {
|
||||
return false;
|
||||
}
|
||||
ContentResolver cr = context.getContentResolver();
|
||||
return Settings.Global.getInt(cr, Settings.Global.EUICC_PROVISIONED, 0) != 0;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
protected boolean isEuiccEnabled(Context context) {
|
||||
EuiccManager euiccManager = (EuiccManager) context.getSystemService(Context.EUICC_SERVICE);
|
||||
return euiccManager.isEnabled();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean hasReachedBottom(final ScrollView scrollView) {
|
||||
if (scrollView.getChildCount() < 1) {
|
||||
@@ -349,7 +388,7 @@ public class MasterClear extends OptionsMenuFragment
|
||||
final UserManager um = UserManager.get(context);
|
||||
final boolean disallow = !um.isAdminUser() || RestrictedLockUtils.hasBaseUserRestriction(
|
||||
context, UserManager.DISALLOW_FACTORY_RESET, UserHandle.myUserId());
|
||||
if (disallow && !Utils.isCarrierDemoUser(context)) {
|
||||
if (disallow && !Utils.isDemoUser(context)) {
|
||||
return inflater.inflate(R.layout.master_clear_disallowed_screen, null);
|
||||
} else if (admin != null) {
|
||||
View view = inflater.inflate(R.layout.admin_support_details_empty_view, null);
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
import android.service.oemlock.OemLockManager;
|
||||
import android.service.persistentdata.PersistentDataBlockManager;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -51,6 +51,7 @@ public class MasterClearConfirm extends OptionsMenuFragment {
|
||||
|
||||
private View mContentView;
|
||||
private boolean mEraseSdCard;
|
||||
private boolean mEraseEsims;
|
||||
|
||||
/**
|
||||
* The user has gone through the multiple confirmation, so now we go ahead
|
||||
@@ -66,12 +67,14 @@ public class MasterClearConfirm extends OptionsMenuFragment {
|
||||
|
||||
final PersistentDataBlockManager pdbManager = (PersistentDataBlockManager)
|
||||
getActivity().getSystemService(Context.PERSISTENT_DATA_BLOCK_SERVICE);
|
||||
final OemLockManager oemLockManager = (OemLockManager)
|
||||
getActivity().getSystemService(Context.OEM_LOCK_SERVICE);
|
||||
|
||||
if (pdbManager != null && !pdbManager.getOemUnlockEnabled() &&
|
||||
if (pdbManager != null && !oemLockManager.isOemUnlockAllowed() &&
|
||||
Utils.isDeviceProvisioned(getActivity())) {
|
||||
// if OEM unlock is enabled, this will be wiped during FR process. If disabled, it
|
||||
// will be wiped here, unless the device is still being provisioned, in which case
|
||||
// the persistent data block will be preserved.
|
||||
// if OEM unlock is allowed, the persistent data block will be wiped during FR
|
||||
// process. If disabled, it will be wiped here, unless the device is still being
|
||||
// provisioned, in which case the persistent data block will be preserved.
|
||||
new AsyncTask<Void, Void, Void>() {
|
||||
int mOldOrientation;
|
||||
ProgressDialog mProgressDialog;
|
||||
@@ -125,6 +128,7 @@ public class MasterClearConfirm extends OptionsMenuFragment {
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
|
||||
intent.putExtra(Intent.EXTRA_REASON, "MasterClearConfirm");
|
||||
intent.putExtra(Intent.EXTRA_WIPE_EXTERNAL_STORAGE, mEraseSdCard);
|
||||
intent.putExtra(Intent.EXTRA_WIPE_ESIMS, mEraseEsims);
|
||||
getActivity().sendBroadcast(intent);
|
||||
// Intent handling is asynchronous -- assume it will happen soon.
|
||||
}
|
||||
@@ -175,6 +179,8 @@ public class MasterClearConfirm extends OptionsMenuFragment {
|
||||
Bundle args = getArguments();
|
||||
mEraseSdCard = args != null
|
||||
&& args.getBoolean(MasterClear.ERASE_EXTERNAL_EXTRA);
|
||||
mEraseEsims = args != null
|
||||
&& args.getBoolean(MasterClear.ERASE_ESIMS_EXTRA);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,8 @@ import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.app.QueuedWork;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
@@ -31,6 +33,7 @@ import android.os.AsyncResult;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.telephony.CarrierConfigManager;
|
||||
import android.telephony.CellInfo;
|
||||
import android.telephony.CellInfoCdma;
|
||||
import android.telephony.CellInfoGsm;
|
||||
@@ -129,6 +132,9 @@ public class RadioInfo extends Activity {
|
||||
private static final int IMS_WFC_PROVISIONED_CONFIG_ID =
|
||||
ImsConfig.ConfigConstants.VOICE_OVER_WIFI_SETTING_ENABLED;
|
||||
|
||||
private static final int EAB_PROVISIONED_CONFIG_ID =
|
||||
ImsConfig.ConfigConstants.EAB_SETTING_ENABLED;
|
||||
|
||||
//Values in must match mCellInfoRefreshRates
|
||||
private static final String[] mCellInfoRefreshRateLabels = {
|
||||
"Disabled",
|
||||
@@ -195,9 +201,12 @@ public class RadioInfo extends Activity {
|
||||
private Button updateSmscButton;
|
||||
private Button refreshSmscButton;
|
||||
private Button oemInfoButton;
|
||||
private Button carrierProvisioningButton;
|
||||
private Button triggercarrierProvisioningButton;
|
||||
private Switch imsVolteProvisionedSwitch;
|
||||
private Switch imsVtProvisionedSwitch;
|
||||
private Switch imsWfcProvisionedSwitch;
|
||||
private Switch eabProvisionedSwitch;
|
||||
private Spinner preferredNetworkType;
|
||||
private Spinner cellInfoRefreshRateSpinner;
|
||||
|
||||
@@ -403,6 +412,7 @@ public class RadioInfo extends Activity {
|
||||
imsVolteProvisionedSwitch = (Switch) findViewById(R.id.volte_provisioned_switch);
|
||||
imsVtProvisionedSwitch = (Switch) findViewById(R.id.vt_provisioned_switch);
|
||||
imsWfcProvisionedSwitch = (Switch) findViewById(R.id.wfc_provisioned_switch);
|
||||
eabProvisionedSwitch = (Switch) findViewById(R.id.eab_provisioned_switch);
|
||||
|
||||
radioPowerOnSwitch = (Switch) findViewById(R.id.radio_power);
|
||||
|
||||
@@ -414,6 +424,11 @@ public class RadioInfo extends Activity {
|
||||
refreshSmscButton.setOnClickListener(mRefreshSmscButtonHandler);
|
||||
dnsCheckToggleButton = (Button) findViewById(R.id.dns_check_toggle);
|
||||
dnsCheckToggleButton.setOnClickListener(mDnsCheckButtonHandler);
|
||||
carrierProvisioningButton = (Button) findViewById(R.id.carrier_provisioning);
|
||||
carrierProvisioningButton.setOnClickListener(mCarrierProvisioningButtonHandler);
|
||||
triggercarrierProvisioningButton = (Button) findViewById(R.id.trigger_carrier_provisioning);
|
||||
triggercarrierProvisioningButton.setOnClickListener(
|
||||
mTriggerCarrierProvisioningButtonHandler);
|
||||
|
||||
oemInfoButton = (Button) findViewById(R.id.oem_info);
|
||||
oemInfoButton.setOnClickListener(mOemInfoButtonHandler);
|
||||
@@ -470,6 +485,7 @@ public class RadioInfo extends Activity {
|
||||
imsVolteProvisionedSwitch.setOnCheckedChangeListener(mImsVolteCheckedChangeListener);
|
||||
imsVtProvisionedSwitch.setOnCheckedChangeListener(mImsVtCheckedChangeListener);
|
||||
imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
|
||||
eabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
|
||||
|
||||
mTelephonyManager.listen(mPhoneStateListener,
|
||||
PhoneStateListener.LISTEN_CALL_STATE
|
||||
@@ -1162,6 +1178,11 @@ public class RadioInfo extends Activity {
|
||||
setImsConfigProvisionedState(IMS_WFC_PROVISIONED_CONFIG_ID, state);
|
||||
}
|
||||
|
||||
void setEabProvisionedState(boolean state) {
|
||||
Log.d(TAG, "setEabProvisioned() state: " + ((state)? "on":"off"));
|
||||
setImsConfigProvisionedState(EAB_PROVISIONED_CONFIG_ID, state);
|
||||
}
|
||||
|
||||
void setImsConfigProvisionedState(int configItem, boolean state) {
|
||||
if (phone != null && mImsManager != null) {
|
||||
QueuedWork.queue(new Runnable() {
|
||||
@@ -1231,6 +1252,48 @@ public class RadioInfo extends Activity {
|
||||
}
|
||||
};
|
||||
|
||||
private boolean isEabProvisioned() {
|
||||
return isFeatureProvisioned(EAB_PROVISIONED_CONFIG_ID, false);
|
||||
}
|
||||
|
||||
OnCheckedChangeListener mEabCheckedChangeListener = new OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
setEabProvisionedState(isChecked);
|
||||
}
|
||||
};
|
||||
|
||||
private boolean isFeatureProvisioned(int featureId, boolean defaultValue) {
|
||||
boolean provisioned = defaultValue;
|
||||
if (mImsManager != null) {
|
||||
try {
|
||||
ImsConfig imsConfig = mImsManager.getConfigInterface();
|
||||
if (imsConfig != null) {
|
||||
provisioned =
|
||||
(imsConfig.getProvisionedValue(featureId)
|
||||
== ImsConfig.FeatureValueConstants.ON);
|
||||
}
|
||||
} catch (ImsException ex) {
|
||||
Log.e(TAG, "isFeatureProvisioned() exception:", ex);
|
||||
}
|
||||
}
|
||||
|
||||
log("isFeatureProvisioned() featureId=" + featureId + " provisioned=" + provisioned);
|
||||
return provisioned;
|
||||
}
|
||||
|
||||
private static boolean isEabEnabledByPlatform(Context context) {
|
||||
if (context != null) {
|
||||
CarrierConfigManager configManager = (CarrierConfigManager)
|
||||
context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
|
||||
if (configManager != null && configManager.getConfig().getBoolean(
|
||||
CarrierConfigManager.KEY_USE_RCS_PRESENCE_BOOL)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void updateImsProvisionedState() {
|
||||
log("updateImsProvisionedState isImsVolteProvisioned()=" + isImsVolteProvisioned());
|
||||
//delightful hack to prevent on-checked-changed calls from
|
||||
@@ -1252,6 +1315,11 @@ public class RadioInfo extends Activity {
|
||||
imsWfcProvisionedSwitch.setOnCheckedChangeListener(mImsWfcCheckedChangeListener);
|
||||
imsWfcProvisionedSwitch.setEnabled(
|
||||
mImsManager.isWfcEnabledByPlatform(phone.getContext()));
|
||||
|
||||
eabProvisionedSwitch.setOnCheckedChangeListener(null);
|
||||
eabProvisionedSwitch.setChecked(isEabProvisioned());
|
||||
eabProvisionedSwitch.setOnCheckedChangeListener(mEabCheckedChangeListener);
|
||||
eabProvisionedSwitch.setEnabled(isEabEnabledByPlatform(phone.getContext()));
|
||||
}
|
||||
|
||||
OnClickListener mDnsCheckButtonHandler = new OnClickListener() {
|
||||
@@ -1295,6 +1363,26 @@ public class RadioInfo extends Activity {
|
||||
}
|
||||
};
|
||||
|
||||
OnClickListener mCarrierProvisioningButtonHandler = new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
final Intent intent = new Intent("com.android.settings.CARRIER_PROVISIONING");
|
||||
final ComponentName serviceComponent = ComponentName.unflattenFromString(
|
||||
"com.android.omadm.service/.DMIntentReceiver");
|
||||
intent.setComponent(serviceComponent);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
};
|
||||
|
||||
OnClickListener mTriggerCarrierProvisioningButtonHandler = new OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
final Intent intent = new Intent("com.android.settings.TRIGGER_CARRIER_PROVISIONING");
|
||||
final ComponentName serviceComponent = ComponentName.unflattenFromString(
|
||||
"com.android.omadm.service/.DMIntentReceiver");
|
||||
intent.setComponent(serviceComponent);
|
||||
sendBroadcast(intent);
|
||||
}
|
||||
};
|
||||
|
||||
AdapterView.OnItemSelectedListener mPreferredNetworkHandler =
|
||||
new AdapterView.OnItemSelectedListener() {
|
||||
|
||||
|
||||
@@ -20,15 +20,20 @@ import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemProperties;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* {@link Activity} that displays regulatory information for the "Regulatory information"
|
||||
* preference item, and when "*#07#" is dialed on the Phone keypad. To enable this feature,
|
||||
@@ -41,7 +46,12 @@ import android.widget.TextView;
|
||||
*/
|
||||
public class RegulatoryInfoDisplayActivity extends Activity implements
|
||||
DialogInterface.OnDismissListener {
|
||||
|
||||
private final String REGULATORY_INFO_RESOURCE = "regulatory_info";
|
||||
private static final String DEFAULT_REGULATORY_INFO_FILEPATH =
|
||||
"/data/misc/elabel/regulatory_info.png";
|
||||
private static final String REGULATORY_INFO_FILEPATH_TEMPLATE =
|
||||
"/data/misc/elabel/regulatory_info_%s.png";
|
||||
|
||||
/**
|
||||
* Display the regulatory info graphic in a dialog window.
|
||||
@@ -60,7 +70,18 @@ public class RegulatoryInfoDisplayActivity extends Activity implements
|
||||
.setOnDismissListener(this);
|
||||
|
||||
boolean regulatoryInfoDrawableExists = false;
|
||||
int resId = getResourceId();
|
||||
|
||||
final String regulatoryInfoFile = getRegulatoryInfoImageFileName();
|
||||
final Bitmap regulatoryInfoBitmap = BitmapFactory.decodeFile(regulatoryInfoFile);
|
||||
|
||||
if (regulatoryInfoBitmap != null) {
|
||||
regulatoryInfoDrawableExists = true;
|
||||
}
|
||||
|
||||
int resId = 0;
|
||||
if (!regulatoryInfoDrawableExists) {
|
||||
resId = getResourceId();
|
||||
}
|
||||
if (resId != 0) {
|
||||
try {
|
||||
Drawable d = getDrawable(resId);
|
||||
@@ -77,8 +98,12 @@ public class RegulatoryInfoDisplayActivity extends Activity implements
|
||||
|
||||
if (regulatoryInfoDrawableExists) {
|
||||
View view = getLayoutInflater().inflate(R.layout.regulatory_info, null);
|
||||
ImageView image = (ImageView) view.findViewById(R.id.regulatoryInfo);
|
||||
image.setImageResource(resId);
|
||||
ImageView image = view.findViewById(R.id.regulatoryInfo);
|
||||
if (regulatoryInfoBitmap != null) {
|
||||
image.setImageBitmap(regulatoryInfoBitmap);
|
||||
} else {
|
||||
image.setImageResource(resId);
|
||||
}
|
||||
builder.setView(view);
|
||||
builder.show();
|
||||
} else if (regulatoryText.length() > 0) {
|
||||
@@ -99,7 +124,7 @@ public class RegulatoryInfoDisplayActivity extends Activity implements
|
||||
REGULATORY_INFO_RESOURCE, "drawable", getPackageName());
|
||||
|
||||
// When hardware sku property exists, use regulatory_info_<sku> resource if valid.
|
||||
String sku = SystemProperties.get("ro.boot.hardware.sku", "");
|
||||
final String sku = getSku();
|
||||
if (!TextUtils.isEmpty(sku)) {
|
||||
String regulatory_info_res = REGULATORY_INFO_RESOURCE + "_" + sku.toLowerCase();
|
||||
int id = getResources().getIdentifier(
|
||||
@@ -115,4 +140,20 @@ public class RegulatoryInfoDisplayActivity extends Activity implements
|
||||
public void onDismiss(DialogInterface dialog) {
|
||||
finish(); // close the activity
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static String getSku() {
|
||||
return SystemProperties.get("ro.boot.hardware.sku", "");
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static String getRegulatoryInfoImageFileName() {
|
||||
final String sku = getSku();
|
||||
if (TextUtils.isEmpty(sku)) {
|
||||
return DEFAULT_REGULATORY_INFO_FILEPATH;
|
||||
} else {
|
||||
return String.format(Locale.US, REGULATORY_INFO_FILEPATH_TEMPLATE,
|
||||
sku.toLowerCase());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,13 +34,14 @@ import android.widget.Spinner;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.telephony.PhoneConstants;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.ConfirmLockPattern;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
/**
|
||||
* Confirm and execute a reset of the device's network settings to a clean "just out of the box"
|
||||
* state. Multiple confirmations are required: first, a general "are you sure you want to do this?"
|
||||
|
||||
@@ -18,9 +18,11 @@ package com.android.settings;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothManager;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.NetworkPolicyManager;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
@@ -104,12 +106,27 @@ public class ResetNetworkConfirm extends OptionsMenuFragment {
|
||||
}
|
||||
|
||||
ImsManager.factoryReset(context);
|
||||
restoreDefaultApn(context);
|
||||
|
||||
Toast.makeText(context, R.string.reset_network_complete_toast, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Restore APN settings to default.
|
||||
*/
|
||||
private void restoreDefaultApn(Context context) {
|
||||
Uri uri = Uri.parse(ApnSettings.RESTORE_CARRIERS_URI);
|
||||
|
||||
if (SubscriptionManager.isUsableSubIdValue(mSubId)) {
|
||||
uri = Uri.withAppendedPath(uri, "subId/" + String.valueOf(mSubId));
|
||||
}
|
||||
|
||||
ContentResolver resolver = context.getContentResolver();
|
||||
resolver.delete(uri, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the UI for the final confirmation interaction
|
||||
*/
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.settings;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.admin.DevicePolicyManager;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -27,10 +26,10 @@ import android.os.Bundle;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.dashboard.RestrictedDashboardFragment;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
|
||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
@@ -46,7 +45,10 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
* If this settings screen should be pin protected whenever
|
||||
* {@link RestrictionsManager.hasRestrictionsProvider()} returns true, pass in
|
||||
* {@link RESTRICT_IF_OVERRIDABLE} to the constructor instead of a restrictions key.
|
||||
*
|
||||
* @deprecated Use {@link RestrictedDashboardFragment} instead
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class RestrictedSettingsFragment extends SettingsPreferenceFragment {
|
||||
|
||||
protected static final String RESTRICT_IF_OVERRIDABLE = "restrict_if_overridable";
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.widget.Switch;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.password.ChooseLockGeneric;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settings.search.SearchIndexableRaw;
|
||||
@@ -73,6 +74,11 @@ public class ScreenPinningSettings extends SettingsPreferenceFragment
|
||||
mSwitchBar.setChecked(isLockToAppEnabled(getActivity()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_screen_pinning;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.android.settings;
|
||||
|
||||
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
|
||||
|
||||
import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
|
||||
import android.app.Activity;
|
||||
@@ -65,6 +66,9 @@ import com.android.settings.fingerprint.FingerprintSettings;
|
||||
import com.android.settings.location.LocationPreferenceController;
|
||||
import com.android.settings.notification.LockScreenNotificationPreferenceController;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.password.ChooseLockGeneric.ChooseLockGenericFragment;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
import com.android.settings.password.ManagedLockPasswordProvider;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settings.search.SearchIndexableRaw;
|
||||
@@ -104,6 +108,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
static final String KEY_LOCKSCREEN_PREFERENCES = "lockscreen_preferences";
|
||||
private static final String KEY_ENCRYPTION_AND_CREDENTIALS = "encryption_and_credential";
|
||||
private static final String KEY_LOCATION_SCANNING = "location_scanning";
|
||||
private static final String KEY_LOCATION = "location";
|
||||
|
||||
private static final int SET_OR_CHANGE_LOCK_METHOD_REQUEST = 123;
|
||||
private static final int CHANGE_TRUST_AGENT_SETTINGS = 126;
|
||||
@@ -177,6 +182,12 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
return MetricsEvent.SECURITY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
mLocationcontroller = new LocationPreferenceController(context, getLifecycle());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -207,7 +218,6 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
mTrustAgentClickIntent = savedInstanceState.getParcelable(TRUST_AGENT_CLICK_INTENT);
|
||||
}
|
||||
|
||||
mLocationcontroller = new LocationPreferenceController(activity);
|
||||
mManageDeviceAdminPreferenceController
|
||||
= new ManageDeviceAdminPreferenceController(activity);
|
||||
mEnterprisePrivacyPreferenceController
|
||||
@@ -632,7 +642,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
return false;
|
||||
}
|
||||
}
|
||||
startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
|
||||
startFragment(this, ChooseLockGenericFragment.class.getName(),
|
||||
R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
|
||||
} else if (KEY_UNLOCK_SET_OR_CHANGE_PROFILE.equals(key)) {
|
||||
if (Utils.startQuietModeDialogIfNecessary(this.getActivity(), mUm,
|
||||
@@ -641,7 +651,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
}
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
|
||||
startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
|
||||
startFragment(this, ChooseLockGenericFragment.class.getName(),
|
||||
R.string.lock_settings_picker_title_profile,
|
||||
SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
|
||||
} else if (KEY_TRUST_AGENT.equals(key)) {
|
||||
@@ -741,7 +751,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
private void unifyUncompliantLocks() {
|
||||
mLockPatternUtils.setSeparateProfileChallengeEnabled(mProfileChallengeUserId, false,
|
||||
mCurrentProfilePassword);
|
||||
startFragment(this, "com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
|
||||
startFragment(this, ChooseLockGenericFragment.class.getName(),
|
||||
R.string.lock_settings_picker_title, SET_OR_CHANGE_LOCK_METHOD_REQUEST, null);
|
||||
}
|
||||
|
||||
@@ -749,7 +759,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
Bundle extras = new Bundle();
|
||||
extras.putInt(Intent.EXTRA_USER_ID, mProfileChallengeUserId);
|
||||
startFragment(this,
|
||||
"com.android.settings.ChooseLockGeneric$ChooseLockGenericFragment",
|
||||
ChooseLockGenericFragment.class.getName(),
|
||||
R.string.lock_settings_picker_title_profile,
|
||||
SET_OR_CHANGE_LOCK_METHOD_REQUEST_PROFILE, extras);
|
||||
}
|
||||
@@ -957,7 +967,7 @@ public class SecuritySettings extends SettingsPreferenceFragment
|
||||
// Duplicate in special app access
|
||||
keys.add(KEY_MANAGE_DEVICE_ADMIN);
|
||||
// Duplicates between parent-child
|
||||
keys.add((new LocationPreferenceController(context)).getPreferenceKey());
|
||||
keys.add(KEY_LOCATION);
|
||||
keys.add(KEY_ENCRYPTION_AND_CREDENTIALS);
|
||||
keys.add(KEY_SCREEN_PINNING);
|
||||
keys.add(KEY_LOCATION_SCANNING);
|
||||
|
||||
@@ -23,6 +23,8 @@ import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.SeekBar;
|
||||
|
||||
import com.android.settingslib.CustomDialogPreference;
|
||||
|
||||
/**
|
||||
* Based on frameworks/base/core/java/android/preference/SeekBarDialogPreference.java
|
||||
* except uses support lib preferences.
|
||||
|
||||
@@ -22,6 +22,8 @@ import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
|
||||
import com.android.settingslib.CustomEditTextPreference;
|
||||
|
||||
public class SelectableEditTextPreference extends CustomEditTextPreference {
|
||||
|
||||
private int mSelectionMode;
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.android.settings.applications.AppOpsSummary;
|
||||
import com.android.settings.enterprise.EnterprisePrivacySettings;
|
||||
import com.android.settings.fingerprint.FingerprintEnrollIntroduction;
|
||||
import com.android.settings.fingerprint.FingerprintSettings;
|
||||
import com.android.settings.password.ChooseLockGeneric;
|
||||
|
||||
/**
|
||||
* Top-level Settings activity
|
||||
@@ -31,6 +32,7 @@ public class Settings extends SettingsActivity {
|
||||
/*
|
||||
* Settings subclasses for launching independently.
|
||||
*/
|
||||
public static class AssistGestureSettingsActivity extends SettingsActivity { /* empty */}
|
||||
public static class BluetoothSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class SimSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class TetherSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
@@ -139,12 +141,17 @@ public class Settings extends SettingsActivity {
|
||||
public static class ManageAppExternalSourcesActivity extends SettingsActivity { /* empty */ }
|
||||
|
||||
public static class WifiCallingSuggestionActivity extends SettingsActivity { /* empty */ }
|
||||
public static class ZenModeAutomationSuggestionActivity extends SettingsActivity { /* empty */ }
|
||||
public static class FingerprintSuggestionActivity extends FingerprintSettings { /* empty */ }
|
||||
public static class FingerprintEnrollSuggestionActivity extends FingerprintEnrollIntroduction {
|
||||
/* empty */
|
||||
}
|
||||
public static class ScreenLockSuggestionActivity extends ChooseLockGeneric { /* empty */ }
|
||||
public static class DoubleTapPowerSuggestionActivity extends SettingsActivity { /* empty */ }
|
||||
public static class DoubleTwistSuggestionActivity extends SettingsActivity { /* empty */ }
|
||||
public static class AmbientDisplaySuggestionActivity extends SettingsActivity { /* empty */ }
|
||||
public static class AmbientDisplayPickupSuggestionActivity extends SettingsActivity {
|
||||
/* empty */ }
|
||||
public static class SwipeToNotificationSuggestionActivity extends SettingsActivity {
|
||||
/* empty */ }
|
||||
public static class WallpaperSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class ManagedProfileSettingsActivity extends SettingsActivity { /* empty */ }
|
||||
public static class DeletionHelperActivity extends SettingsActivity { /* empty */ }
|
||||
@@ -168,6 +175,7 @@ public class Settings extends SettingsActivity {
|
||||
}
|
||||
}
|
||||
public static class WebViewAppPickerActivity extends SettingsActivity { /* empty */ }
|
||||
public static class LegacySupportActivity extends SettingsActivity{ /* empty */ }
|
||||
|
||||
// Top level categories for new IA
|
||||
public static class NetworkDashboardActivity extends SettingsActivity {}
|
||||
@@ -176,6 +184,5 @@ public class Settings extends SettingsActivity {
|
||||
public static class StorageDashboardActivity extends SettingsActivity {}
|
||||
public static class UserAndAccountDashboardActivity extends SettingsActivity {}
|
||||
public static class SystemDashboardActivity extends SettingsActivity {}
|
||||
public static class SupportDashboardActivity extends SettingsActivity {}
|
||||
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.Toolbar;
|
||||
|
||||
import com.android.internal.util.ArrayUtils;
|
||||
import com.android.settings.Settings.WifiSettingsActivity;
|
||||
@@ -62,7 +63,8 @@ import com.android.settings.dashboard.DashboardSummary;
|
||||
import com.android.settings.development.DevelopmentSettings;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.DynamicIndexableContentMonitor;
|
||||
import com.android.settings.search2.SearchFeatureProvider;
|
||||
import com.android.settings.search.SearchActivity;
|
||||
import com.android.settings.search.SearchFeatureProvider;
|
||||
import com.android.settings.wfd.WifiDisplaySettings;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
import com.android.settingslib.drawer.DashboardCategory;
|
||||
@@ -75,7 +77,7 @@ import java.util.Set;
|
||||
public class SettingsActivity extends SettingsDrawerActivity
|
||||
implements PreferenceManager.OnPreferenceTreeClickListener,
|
||||
PreferenceFragment.OnPreferenceStartFragmentCallback,
|
||||
ButtonBarHandler, FragmentManager.OnBackStackChangedListener {
|
||||
ButtonBarHandler, FragmentManager.OnBackStackChangedListener, OnClickListener {
|
||||
|
||||
private static final String LOG_TAG = "Settings";
|
||||
|
||||
@@ -85,8 +87,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
private static final String SAVE_KEY_CATEGORIES = ":settings:categories";
|
||||
@VisibleForTesting
|
||||
static final String SAVE_KEY_SHOW_HOME_AS_UP = ":settings:show_home_as_up";
|
||||
@VisibleForTesting
|
||||
static final String SAVE_KEY_SHOW_SEARCH = ":settings:show_search";
|
||||
|
||||
/**
|
||||
* When starting this activity, the invoking Intent can contain this extra
|
||||
@@ -190,22 +190,18 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
|
||||
private DynamicIndexableContentMonitor mDynamicIndexableContentMonitor;
|
||||
|
||||
private ActionBar mActionBar;
|
||||
private SwitchBar mSwitchBar;
|
||||
|
||||
private Button mNextButton;
|
||||
|
||||
@VisibleForTesting
|
||||
boolean mDisplayHomeAsUpEnabled;
|
||||
@VisibleForTesting
|
||||
boolean mDisplaySearch;
|
||||
|
||||
private boolean mIsShowingDashboard;
|
||||
private boolean mIsShortcut;
|
||||
|
||||
private ViewGroup mContent;
|
||||
|
||||
private SearchFeatureProvider mSearchFeatureProvider;
|
||||
private MetricsFeatureProvider mMetricsFeatureProvider;
|
||||
|
||||
// Categories
|
||||
@@ -230,15 +226,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
if (!mDisplaySearch) {
|
||||
return false;
|
||||
}
|
||||
mSearchFeatureProvider.setUpSearchMenu(menu, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SharedPreferences getSharedPreferences(String name, int mode) {
|
||||
if (name.equals(getPackageName() + "_preferences")) {
|
||||
@@ -282,7 +269,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
final FeatureFactory factory = FeatureFactory.getFactory(this);
|
||||
|
||||
mDashboardFeatureProvider = factory.getDashboardFeatureProvider(this);
|
||||
mSearchFeatureProvider = factory.getSearchFeatureProvider();
|
||||
mMetricsFeatureProvider = factory.getMetricsFeatureProvider();
|
||||
|
||||
// Should happen before any call to getIntent()
|
||||
@@ -322,7 +308,7 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
setContentView(mIsShowingDashboard ?
|
||||
R.layout.settings_main_dashboard : R.layout.settings_main_prefs);
|
||||
|
||||
mContent = (ViewGroup) findViewById(R.id.main_content);
|
||||
mContent = findViewById(R.id.main_content);
|
||||
|
||||
getFragmentManager().addOnBackStackChangedListener(this);
|
||||
|
||||
@@ -345,12 +331,28 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
launchSettingFragment(initialFragmentName, isSubSettings, intent);
|
||||
}
|
||||
|
||||
mActionBar = getActionBar();
|
||||
if (mActionBar != null) {
|
||||
mActionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
|
||||
mActionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
|
||||
if (mIsShowingDashboard) {
|
||||
findViewById(R.id.search_bar).setVisibility(View.VISIBLE);
|
||||
findViewById(R.id.action_bar).setVisibility(View.GONE);
|
||||
Toolbar toolbar = findViewById(R.id.search_action_bar);
|
||||
toolbar.setOnClickListener(this);
|
||||
setActionBar(toolbar);
|
||||
|
||||
// Please forgive me for what I am about to do.
|
||||
//
|
||||
// Need to make the navigation icon non-clickable so that the entire card is clickable
|
||||
// and goes to the search UI. Also set the background to null so there's no ripple.
|
||||
View navView = toolbar.getNavigationView();
|
||||
navView.setClickable(false);
|
||||
navView.setBackground(null);
|
||||
}
|
||||
mSwitchBar = (SwitchBar) findViewById(R.id.switch_bar);
|
||||
|
||||
ActionBar actionBar = getActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(mDisplayHomeAsUpEnabled);
|
||||
actionBar.setHomeButtonEnabled(mDisplayHomeAsUpEnabled);
|
||||
}
|
||||
mSwitchBar = findViewById(R.id.switch_bar);
|
||||
if (mSwitchBar != null) {
|
||||
mSwitchBar.setMetricsTag(getMetricsTag());
|
||||
}
|
||||
@@ -417,7 +419,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
@VisibleForTesting
|
||||
void launchSettingFragment(String initialFragmentName, boolean isSubSettings, Intent intent) {
|
||||
if (!mIsShowingDashboard && initialFragmentName != null) {
|
||||
mDisplaySearch = false;
|
||||
// UP will be shown only if it is a sub settings
|
||||
if (mIsShortcut) {
|
||||
mDisplayHomeAsUpEnabled = isSubSettings;
|
||||
@@ -432,10 +433,8 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
switchToFragment(initialFragmentName, initialArguments, true, false,
|
||||
mInitialTitleResId, mInitialTitle, false);
|
||||
} else {
|
||||
// No UP affordance if we are displaying the main Dashboard
|
||||
mDisplayHomeAsUpEnabled = false;
|
||||
// Show Search affordance
|
||||
mDisplaySearch = true;
|
||||
// Show search icon as up affordance if we are displaying the main Dashboard
|
||||
mDisplayHomeAsUpEnabled = true;
|
||||
mInitialTitleResId = R.string.dashboard_title;
|
||||
|
||||
switchToFragment(DashboardSummary.class.getName(), null /* args */, false, false,
|
||||
@@ -443,13 +442,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
}
|
||||
}
|
||||
|
||||
public void setDisplaySearchMenu(boolean displaySearch) {
|
||||
if (displaySearch != mDisplaySearch) {
|
||||
mDisplaySearch = displaySearch;
|
||||
invalidateOptionsMenu();
|
||||
}
|
||||
}
|
||||
|
||||
private void setTitleFromIntent(Intent intent) {
|
||||
final int initialTitleResId = intent.getIntExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1);
|
||||
if (initialTitleResId > 0) {
|
||||
@@ -530,7 +522,6 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
}
|
||||
|
||||
outState.putBoolean(SAVE_KEY_SHOW_HOME_AS_UP, mDisplayHomeAsUpEnabled);
|
||||
outState.putBoolean(SAVE_KEY_SHOW_SEARCH, mDisplaySearch);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -538,19 +529,13 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
|
||||
mDisplayHomeAsUpEnabled = savedInstanceState.getBoolean(SAVE_KEY_SHOW_HOME_AS_UP);
|
||||
mDisplaySearch = savedInstanceState.getBoolean(SAVE_KEY_SHOW_SEARCH);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
mDevelopmentPreferencesListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
||||
@Override
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
updateTilesList();
|
||||
}
|
||||
};
|
||||
mDevelopmentPreferencesListener = (sharedPreferences, key) -> updateTilesList();
|
||||
mDevelopmentPreferences.registerOnSharedPreferenceChangeListener(
|
||||
mDevelopmentPreferencesListener);
|
||||
|
||||
@@ -939,4 +924,10 @@ public class SettingsActivity extends SettingsDrawerActivity
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Intent intent = new Intent(this, SearchActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,8 +49,10 @@ import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.core.instrumentation.Instrumentable;
|
||||
import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
|
||||
import com.android.settings.widget.FooterPreferenceMixin;
|
||||
import com.android.settingslib.CustomDialogPreference;
|
||||
import com.android.settingslib.CustomEditTextPreference;
|
||||
import com.android.settingslib.HelpUtils;
|
||||
import com.android.settingslib.widget.FooterPreferenceMixin;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -321,12 +323,15 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEmptyView() {
|
||||
@VisibleForTesting
|
||||
void updateEmptyView() {
|
||||
if (mEmptyView == null) return;
|
||||
if (getPreferenceScreen() != null) {
|
||||
final View listContainer = getActivity().findViewById(android.R.id.list_container);
|
||||
boolean show = (getPreferenceScreen().getPreferenceCount()
|
||||
- (mHeader != null ? 1 : 0)
|
||||
- (mFooterPreferenceMixin.hasFooter() ? 1 : 0)) <= 0;
|
||||
- (mFooterPreferenceMixin.hasFooter() ? 1 : 0)) <= 0
|
||||
|| (listContainer != null && listContainer.getVisibility() != View.VISIBLE);
|
||||
mEmptyView.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
} else {
|
||||
mEmptyView.setVisibility(View.VISIBLE);
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
/**
|
||||
* Setup Wizard's version of ChooseLockPassword screen. It inherits the logic and basic structure
|
||||
* from ChooseLockPassword class, and should remain similar to that behaviorally. This class should
|
||||
* only overload base methods for minor theme and behavior differences specific to Setup Wizard.
|
||||
* Other changes should be done to ChooseLockPassword class instead and let this class inherit
|
||||
* those changes.
|
||||
*/
|
||||
public class SetupChooseLockPassword extends ChooseLockPassword {
|
||||
|
||||
public static Intent createIntent(Context context, int quality,
|
||||
int minLength, final int maxLength, boolean requirePasswordToDecrypt,
|
||||
boolean confirmCredentials) {
|
||||
Intent intent = ChooseLockPassword.createIntent(context, quality, minLength,
|
||||
maxLength, requirePasswordToDecrypt, confirmCredentials);
|
||||
intent.setClass(context, SetupChooseLockPassword.class);
|
||||
intent.putExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent createIntent(Context context, int quality,
|
||||
int minLength, final int maxLength, boolean requirePasswordToDecrypt, String password) {
|
||||
Intent intent = ChooseLockPassword.createIntent(context, quality, minLength, maxLength,
|
||||
requirePasswordToDecrypt, password);
|
||||
intent.setClass(context, SetupChooseLockPassword.class);
|
||||
intent.putExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent createIntent(Context context, int quality,
|
||||
int minLength, final int maxLength, boolean requirePasswordToDecrypt, long challenge) {
|
||||
Intent intent = ChooseLockPassword.createIntent(context, quality, minLength, maxLength,
|
||||
requirePasswordToDecrypt, challenge);
|
||||
intent.setClass(context, SetupChooseLockPassword.class);
|
||||
intent.putExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false);
|
||||
return intent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isValidFragment(String fragmentName) {
|
||||
return SetupChooseLockPasswordFragment.class.getName().equals(fragmentName);
|
||||
}
|
||||
|
||||
@Override
|
||||
/* package */ Class<? extends Fragment> getFragmentClass() {
|
||||
return SetupChooseLockPasswordFragment.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstance) {
|
||||
super.onCreate(savedInstance);
|
||||
LinearLayout layout = (LinearLayout) findViewById(R.id.content_parent);
|
||||
layout.setFitsSystemWindows(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
|
||||
resid = SetupWizardUtils.getTheme(getIntent());
|
||||
super.onApplyThemeResource(theme, resid, first);
|
||||
}
|
||||
|
||||
public static class SetupChooseLockPasswordFragment extends ChooseLockPasswordFragment {
|
||||
|
||||
@Override
|
||||
protected Intent getRedactionInterstitialIntent(Context context) {
|
||||
// Setup wizard's redaction interstitial is deferred to optional step. Enable that
|
||||
// optional step if the lock screen was set up.
|
||||
SetupRedactionInterstitial.setEnabled(context, true);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package com.android.settings;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Bundle;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
@@ -54,12 +53,6 @@ public class SetupEncryptionInterstitial extends EncryptionInterstitial {
|
||||
return SetupEncryptionInterstitialFragment.class.getName().equals(fragmentName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
|
||||
resid = SetupWizardUtils.getTheme(getIntent());
|
||||
super.onApplyThemeResource(theme, resid, first);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstance) {
|
||||
super.onCreate(savedInstance);
|
||||
|
||||
@@ -60,12 +60,6 @@ public class SetupRedactionInterstitial extends RedactionInterstitial {
|
||||
return SetupRedactionInterstitialFragment.class.getName().equals(fragmentName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onApplyThemeResource(Resources.Theme theme, int resid, boolean first) {
|
||||
resid = SetupWizardUtils.getTheme(getIntent());
|
||||
super.onApplyThemeResource(theme, resid, first);
|
||||
}
|
||||
|
||||
public static class SetupRedactionInterstitialFragment extends RedactionInterstitialFragment {
|
||||
|
||||
// Setup wizard specific UI customizations can be done here
|
||||
|
||||
@@ -17,17 +17,34 @@
|
||||
package com.android.settings;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.SystemProperties;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.setupwizardlib.util.WizardManagerHelper;
|
||||
|
||||
public class SetupWizardUtils {
|
||||
|
||||
@VisibleForTesting
|
||||
static final String SYSTEM_PROP_SETUPWIZARD_THEME = "setupwizard.theme";
|
||||
|
||||
public static int getTheme(Intent intent) {
|
||||
if (WizardManagerHelper.isLightTheme(intent, true)) {
|
||||
return R.style.SetupWizardTheme_Light;
|
||||
} else {
|
||||
return R.style.SetupWizardTheme;
|
||||
String theme = intent.getStringExtra(WizardManagerHelper.EXTRA_THEME);
|
||||
if (theme == null) {
|
||||
theme = SystemProperties.get(SYSTEM_PROP_SETUPWIZARD_THEME);
|
||||
}
|
||||
if (theme != null) {
|
||||
switch (theme) {
|
||||
case WizardManagerHelper.THEME_GLIF_V2_LIGHT:
|
||||
return R.style.GlifV2Theme_Light;
|
||||
case WizardManagerHelper.THEME_GLIF_V2:
|
||||
return R.style.GlifV2Theme;
|
||||
case WizardManagerHelper.THEME_GLIF_LIGHT:
|
||||
return R.style.GlifTheme_Light;
|
||||
case WizardManagerHelper.THEME_GLIF:
|
||||
return R.style.GlifTheme;
|
||||
}
|
||||
}
|
||||
return R.style.GlifTheme_Light;
|
||||
}
|
||||
|
||||
public static int getTransparentTheme(Intent intent) {
|
||||
|
||||
@@ -400,7 +400,7 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
private void updateState(String[] available, String[] tethered,
|
||||
String[] errored) {
|
||||
updateUsbState(available, tethered, errored);
|
||||
updateBluetoothState(available, tethered, errored);
|
||||
updateBluetoothState();
|
||||
}
|
||||
|
||||
|
||||
@@ -431,41 +431,18 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
}
|
||||
|
||||
if (usbTethered) {
|
||||
mUsbTether.setSummary(R.string.usb_tethering_active_subtext);
|
||||
mUsbTether.setEnabled(!mDataSaverEnabled);
|
||||
mUsbTether.setChecked(true);
|
||||
} else if (usbAvailable) {
|
||||
if (usbError == ConnectivityManager.TETHER_ERROR_NO_ERROR) {
|
||||
mUsbTether.setSummary(R.string.usb_tethering_available_subtext);
|
||||
} else {
|
||||
mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
|
||||
}
|
||||
mUsbTether.setEnabled(!mDataSaverEnabled);
|
||||
mUsbTether.setChecked(false);
|
||||
} else if (usbErrored) {
|
||||
mUsbTether.setSummary(R.string.usb_tethering_errored_subtext);
|
||||
mUsbTether.setEnabled(false);
|
||||
mUsbTether.setChecked(false);
|
||||
} else if (mMassStorageActive) {
|
||||
mUsbTether.setSummary(R.string.usb_tethering_storage_active_subtext);
|
||||
mUsbTether.setEnabled(false);
|
||||
mUsbTether.setChecked(false);
|
||||
} else {
|
||||
mUsbTether.setSummary(R.string.usb_tethering_unavailable_subtext);
|
||||
mUsbTether.setEnabled(false);
|
||||
mUsbTether.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBluetoothState(String[] available, String[] tethered,
|
||||
String[] errored) {
|
||||
boolean bluetoothErrored = false;
|
||||
for (String s: errored) {
|
||||
for (String regex : mBluetoothRegexs) {
|
||||
if (s.matches(regex)) bluetoothErrored = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBluetoothState() {
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
if (adapter == null) {
|
||||
return;
|
||||
@@ -473,34 +450,17 @@ public class TetherSettings extends RestrictedSettingsFragment
|
||||
int btState = adapter.getState();
|
||||
if (btState == BluetoothAdapter.STATE_TURNING_OFF) {
|
||||
mBluetoothTether.setEnabled(false);
|
||||
mBluetoothTether.setSummary(R.string.bluetooth_turning_off);
|
||||
} else if (btState == BluetoothAdapter.STATE_TURNING_ON) {
|
||||
mBluetoothTether.setEnabled(false);
|
||||
mBluetoothTether.setSummary(R.string.bluetooth_turning_on);
|
||||
} else {
|
||||
BluetoothPan bluetoothPan = mBluetoothPan.get();
|
||||
if (btState == BluetoothAdapter.STATE_ON && bluetoothPan != null
|
||||
&& bluetoothPan.isTetheringOn()) {
|
||||
mBluetoothTether.setChecked(true);
|
||||
mBluetoothTether.setEnabled(!mDataSaverEnabled);
|
||||
int bluetoothTethered = bluetoothPan.getConnectedDevices().size();
|
||||
if (bluetoothTethered > 1) {
|
||||
String summary = getString(
|
||||
R.string.bluetooth_tethering_devices_connected_subtext,
|
||||
bluetoothTethered);
|
||||
mBluetoothTether.setSummary(summary);
|
||||
} else if (bluetoothTethered == 1) {
|
||||
mBluetoothTether.setSummary(
|
||||
R.string.bluetooth_tethering_device_connected_subtext);
|
||||
} else if (bluetoothErrored) {
|
||||
mBluetoothTether.setSummary(R.string.bluetooth_tethering_errored_subtext);
|
||||
} else {
|
||||
mBluetoothTether.setSummary(R.string.bluetooth_tethering_available_subtext);
|
||||
}
|
||||
} else {
|
||||
mBluetoothTether.setEnabled(!mDataSaverEnabled);
|
||||
mBluetoothTether.setChecked(false);
|
||||
mBluetoothTether.setSummary(R.string.bluetooth_tethering_off_subtext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,6 @@ import android.util.ArraySet;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.security.SecurityFeatureProvider;
|
||||
import com.android.settings.trustagent.TrustAgentManager;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
@@ -78,6 +77,11 @@ public class TrustAgentSettings extends SettingsPreferenceFragment implements
|
||||
return MetricsEvent.TRUST_AGENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_trust_agent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
|
||||
@@ -943,6 +943,8 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: move this out of Utils to a mixin or a controller or a helper class.
|
||||
@Deprecated
|
||||
public static void handleLoadingContainer(View loading, View doneLoading, boolean done,
|
||||
boolean animate) {
|
||||
setViewShown(loading, !done, animate);
|
||||
@@ -1036,7 +1038,24 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
return getCredentialOwnerUserId(context);
|
||||
}
|
||||
int userId = bundle.getInt(Intent.EXTRA_USER_ID, UserHandle.myUserId());
|
||||
return enforceSameOwner(context, userId);
|
||||
if (userId == LockPatternUtils.USER_FRP) {
|
||||
return enforceSystemUser(context, userId);
|
||||
} else {
|
||||
return enforceSameOwner(context, userId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the given user id if the current user is the system user.
|
||||
*
|
||||
* @throws SecurityException if the current user is not the system user.
|
||||
*/
|
||||
public static int enforceSystemUser(Context context, int userId) {
|
||||
if (UserHandle.myUserId() == UserHandle.USER_SYSTEM) {
|
||||
return userId;
|
||||
}
|
||||
throw new SecurityException("Given user id " + userId + " must only be used from "
|
||||
+ "USER_SYSTEM, but current user is " + UserHandle.myUserId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1233,6 +1252,11 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasFingerprintHardware(Context context) {
|
||||
FingerprintManager fingerprintManager = getFingerprintManagerOrNull(context);
|
||||
return fingerprintManager != null && fingerprintManager.isHardwareDetected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Launches an intent which may optionally have a user id defined.
|
||||
* @param fragment Fragment to use to launch the activity.
|
||||
@@ -1252,19 +1276,19 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isCarrierDemoUser(Context context) {
|
||||
final String carrierDemoModeSetting =
|
||||
context.getString(com.android.internal.R.string.config_carrierDemoModeSetting);
|
||||
return UserManager.isDeviceInDemoMode(context)
|
||||
&& getUserManager(context).isDemoUser()
|
||||
&& !TextUtils.isEmpty(carrierDemoModeSetting)
|
||||
&& (Settings.Secure.getInt(context.getContentResolver(),
|
||||
carrierDemoModeSetting, 0) == 1);
|
||||
public static boolean isDemoUser(Context context) {
|
||||
return UserManager.isDeviceInDemoMode(context) && getUserManager(context).isDemoUser();
|
||||
}
|
||||
|
||||
public static ComponentName getDeviceOwnerComponent(Context context) {
|
||||
final DevicePolicyManager dpm = (DevicePolicyManager) context.getSystemService(
|
||||
Context.DEVICE_POLICY_SERVICE);
|
||||
return dpm.getDeviceOwnerComponentOnAnyUser();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if a given user is a profile of another user.
|
||||
* @param user The user whose profiles will be checked.
|
||||
* @param user The user whose profiles wibe checked.
|
||||
* @param profile The (potential) profile.
|
||||
* @return if the profile is actually a profile
|
||||
*/
|
||||
@@ -1311,8 +1335,6 @@ public final class Utils extends com.android.settingslib.Utils {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static boolean isVolumeValid(VolumeInfo volume) {
|
||||
return (volume != null) && (volume.getType() == VolumeInfo.TYPE_PRIVATE)
|
||||
&& volume.isMountedReadable();
|
||||
|
||||
@@ -152,7 +152,9 @@ public class WifiCallingSettings extends SettingsPreferenceFragment
|
||||
|
||||
mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
|
||||
setEmptyView(mEmptyView);
|
||||
mEmptyView.setText(R.string.wifi_calling_off_explanation);
|
||||
String emptyViewText = activity.getString(R.string.wifi_calling_off_explanation)
|
||||
+ activity.getString(R.string.wifi_calling_off_explanation_2);
|
||||
mEmptyView.setText(emptyViewText);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -55,7 +55,7 @@ public class AccessibilityServiceWarning {
|
||||
final View.OnTouchListener filterTouchListener = (View v, MotionEvent event) -> {
|
||||
// Filter obscured touches by consuming them.
|
||||
if (((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_OBSCURED) != 0)
|
||||
|| ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
|
||||
|| ((event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) != 0)) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
Toast.makeText(v.getContext(), R.string.touch_filtered_warning,
|
||||
Toast.LENGTH_SHORT).show();
|
||||
|
||||
@@ -211,6 +211,18 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
|
||||
private DevicePolicyManager mDpm;
|
||||
|
||||
/**
|
||||
* Check if the color transforms are color accelerated. Some transforms are experimental only
|
||||
* on non-accelerated platforms due to the performance implications.
|
||||
*
|
||||
* @param context The current context
|
||||
* @return
|
||||
*/
|
||||
public static boolean isColorTransformAccelerated(Context context) {
|
||||
return context.getResources()
|
||||
.getBoolean(com.android.internal.R.bool.config_setColorTransformAccelerated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.ACCESSIBILITY;
|
||||
@@ -618,11 +630,6 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
updateAccessibilityShortcut(mAccessibilityShortcutPreferenceScreen);
|
||||
}
|
||||
|
||||
private boolean isColorTransformAccelerated(Context context) {
|
||||
return context.getResources()
|
||||
.getBoolean(com.android.internal.R.bool.config_setColorTransformAccelerated);
|
||||
}
|
||||
|
||||
private void updateMagnificationSummary(Preference pref) {
|
||||
final boolean tripleTapEnabled = Settings.Secure.getInt(getContentResolver(),
|
||||
Settings.Secure.ACCESSIBILITY_DISPLAY_MAGNIFICATION_ENABLED, 0) == 1;
|
||||
@@ -767,10 +774,9 @@ public class AccessibilitySettings extends SettingsPreferenceFragment implements
|
||||
|
||||
@Override
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
List<String> keys = new ArrayList<>();
|
||||
List<String> keys = super.getNonIndexableKeys(context);
|
||||
// Duplicates in Display
|
||||
keys.add(FONT_SIZE_PREFERENCE_SCREEN);
|
||||
// TODO (b/37741509) Remove this non-indexble key when bug is resolved.
|
||||
keys.add(DisplaySettings.KEY_DISPLAY_SIZE);
|
||||
|
||||
return keys;
|
||||
|
||||
@@ -51,6 +51,11 @@ public class AccessibilityShortcutPreferenceFragment extends ToggleFeaturePrefer
|
||||
return MetricsEvent.ACCESSIBILITY_TOGGLE_GLOBAL_GESTURE;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_accessibility_shortcut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
@@ -31,7 +31,7 @@ import android.widget.AbsListView;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.BaseAdapter;
|
||||
|
||||
import com.android.settings.CustomDialogPreference;
|
||||
import com.android.settingslib.CustomDialogPreference;
|
||||
|
||||
/**
|
||||
* Abstract dialog preference that displays a set of values and optional titles.
|
||||
|
||||
@@ -31,11 +31,9 @@ import android.view.accessibility.AccessibilityManager;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -67,6 +65,11 @@ public final class MagnificationPreferenceFragment extends SettingsPreferenceFra
|
||||
mMagnificationNavbarPreference = findPreference(MAGNIFICATION_NAVBAR_PREFERENCE_SCREEN_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_magnification;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static android.content.DialogInterface.BUTTON_POSITIVE;
|
||||
|
||||
import static com.android.settings.Utils.setOverlayAllowed;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.settings.accessibility;
|
||||
|
||||
import static com.android.settings.Utils.setOverlayAllowed;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
@@ -38,19 +36,20 @@ import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.widget.LockPatternUtils;
|
||||
import com.android.settings.ConfirmDeviceCredentialActivity;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.password.ConfirmDeviceCredentialActivity;
|
||||
import com.android.settings.widget.ToggleSwitch;
|
||||
import com.android.settings.widget.ToggleSwitch.OnBeforeCheckedChangeListener;
|
||||
import com.android.settingslib.accessibility.AccessibilityUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.android.settings.Utils.setOverlayAllowed;
|
||||
|
||||
public class ToggleAccessibilityServicePreferenceFragment
|
||||
extends ToggleFeaturePreferenceFragment implements DialogInterface.OnClickListener {
|
||||
|
||||
@@ -85,14 +84,6 @@ public class ToggleAccessibilityServicePreferenceFragment
|
||||
// Do not call super. We don't want to see the "Help & feedback" option on this page so as
|
||||
// not to confuse users who think they might be able to send feedback about a specific
|
||||
// accessibility service from this page.
|
||||
|
||||
// We still want to show the "Settings" menu.
|
||||
if (mSettingsTitle != null && mSettingsIntent != null) {
|
||||
MenuItem menuItem = menu.add(mSettingsTitle);
|
||||
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
menuItem.setIntent(mSettingsIntent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,7 +26,7 @@ import android.widget.Switch;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SeekBarPreference;
|
||||
import com.android.settings.widget.SeekBarPreference;
|
||||
import com.android.settings.widget.SwitchBar;
|
||||
|
||||
|
||||
@@ -104,6 +104,11 @@ public class ToggleAutoclickPreferenceFragment extends ToggleFeaturePreferenceFr
|
||||
return MetricsEvent.ACCESSIBILITY_TOGGLE_AUTOCLICK;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_autoclick;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
@@ -41,6 +41,11 @@ public class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceF
|
||||
return MetricsEvent.ACCESSIBILITY_TOGGLE_DALTONIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_color_correction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -49,6 +54,10 @@ public class ToggleDaltonizerPreferenceFragment extends ToggleFeaturePreferenceF
|
||||
|
||||
mType = (ListPreference) findPreference("type");
|
||||
|
||||
if (!AccessibilitySettings.isColorTransformAccelerated(getActivity())) {
|
||||
mFooterPreferenceMixin.createFooterPreference().setTitle(
|
||||
R.string.accessibility_display_daltonizer_preference_subtitle);
|
||||
}
|
||||
initPreferences();
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ public abstract class ToggleFeaturePreferenceFragment
|
||||
protected ToggleSwitch mToggleSwitch;
|
||||
|
||||
protected String mPreferenceKey;
|
||||
protected Preference mSummaryPreference;
|
||||
|
||||
protected CharSequence mSettingsTitle;
|
||||
protected Intent mSettingsIntent;
|
||||
@@ -53,36 +52,6 @@ public abstract class ToggleFeaturePreferenceFragment
|
||||
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(
|
||||
getActivity());
|
||||
setPreferenceScreen(preferenceScreen);
|
||||
mSummaryPreference = new Preference(getPrefContext()) {
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
view.setDividerAllowedAbove(false);
|
||||
view.setDividerAllowedBelow(false);
|
||||
final TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
|
||||
summaryView.setText(getSummary());
|
||||
sendAccessibilityEvent(summaryView);
|
||||
}
|
||||
|
||||
private void sendAccessibilityEvent(View view) {
|
||||
// Since the view is still not attached we create, populate,
|
||||
// and send the event directly since we do not know when it
|
||||
// will be attached and posting commands is not as clean.
|
||||
AccessibilityManager accessibilityManager =
|
||||
AccessibilityManager.getInstance(getActivity());
|
||||
if (accessibilityManager.isEnabled()) {
|
||||
AccessibilityEvent event = AccessibilityEvent.obtain();
|
||||
event.setEventType(AccessibilityEvent.TYPE_VIEW_FOCUSED);
|
||||
view.onInitializeAccessibilityEvent(event);
|
||||
view.dispatchPopulateAccessibilityEvent(event);
|
||||
accessibilityManager.sendAccessibilityEvent(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
mSummaryPreference.setSelectable(false);
|
||||
mSummaryPreference.setPersistent(false);
|
||||
mSummaryPreference.setLayoutResource(R.layout.text_description_preference);
|
||||
preferenceScreen.addPreference(mSummaryPreference);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,6 +63,16 @@ public abstract class ToggleFeaturePreferenceFragment
|
||||
mToggleSwitch = mSwitchBar.getSwitch();
|
||||
|
||||
onProcessArguments(getArguments());
|
||||
|
||||
// Show the "Settings" menu as if it were a preference screen
|
||||
if (mSettingsTitle != null && mSettingsIntent != null) {
|
||||
PreferenceScreen preferenceScreen = getPreferenceScreen();
|
||||
Preference settingsPref = new Preference(preferenceScreen.getContext());
|
||||
settingsPref.setTitle(mSettingsTitle);
|
||||
settingsPref.setIconSpaceReserved(true);
|
||||
settingsPref.setIntent(mSettingsIntent);
|
||||
preferenceScreen.addPreference(settingsPref);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -111,16 +90,6 @@ public abstract class ToggleFeaturePreferenceFragment
|
||||
|
||||
protected abstract void onPreferenceToggled(String preferenceKey, boolean enabled);
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
if (mSettingsTitle != null && mSettingsIntent != null) {
|
||||
MenuItem menuItem = menu.add(mSettingsTitle);
|
||||
menuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
|
||||
menuItem.setIntent(mSettingsIntent);
|
||||
}
|
||||
}
|
||||
|
||||
protected void onInstallSwitchBarToggleSwitch() {
|
||||
// Implement this to set a checked listener.
|
||||
}
|
||||
@@ -145,11 +114,6 @@ public abstract class ToggleFeaturePreferenceFragment
|
||||
}
|
||||
|
||||
protected void onProcessArguments(Bundle arguments) {
|
||||
if (arguments == null) {
|
||||
getPreferenceScreen().removePreference(mSummaryPreference);
|
||||
return;
|
||||
}
|
||||
|
||||
// Key.
|
||||
mPreferenceKey = arguments.getString(AccessibilitySettings.EXTRA_PREFERENCE_KEY);
|
||||
|
||||
@@ -168,9 +132,7 @@ public abstract class ToggleFeaturePreferenceFragment
|
||||
if (arguments.containsKey(AccessibilitySettings.EXTRA_SUMMARY)) {
|
||||
final CharSequence summary = arguments.getCharSequence(
|
||||
AccessibilitySettings.EXTRA_SUMMARY);
|
||||
mSummaryPreference.setSummary(summary);
|
||||
} else {
|
||||
getPreferenceScreen().removePreference(mSummaryPreference);
|
||||
mFooterPreferenceMixin.createFooterPreference().setTitle(summary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,6 +72,11 @@ public class ToggleFontSizePreferenceFragment extends PreviewSeekBarPreferenceFr
|
||||
Settings.System.putFloat(resolver, Settings.System.FONT_SCALE, mValues[mCurrentIndex]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getHelpResource() {
|
||||
return R.string.help_url_font_size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.ACCESSIBILITY_FONT_SIZE;
|
||||
|
||||
@@ -146,7 +146,6 @@ public class ToggleScreenMagnificationPreferenceFragment extends
|
||||
final PreferenceScreen preferenceScreen = getPreferenceManager().getPreferenceScreen();
|
||||
preferenceScreen.setOrderingAsAdded(false);
|
||||
mVideoPreference.setOrder(0);
|
||||
mSummaryPreference.setOrder(1);
|
||||
mConfigWarningPreference.setOrder(2);
|
||||
preferenceScreen.addPreference(mVideoPreference);
|
||||
preferenceScreen.addPreference(mConfigWarningPreference);
|
||||
|
||||
@@ -22,9 +22,8 @@ import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
@@ -45,13 +44,12 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
|
||||
public static final String KEY_ACCOUNT_TYPE = "account_type";
|
||||
public static final String KEY_ACCOUNT_LABEL = "account_label";
|
||||
public static final String KEY_ACCOUNT_TITLE_RES = "account_title_res";
|
||||
public static final String KEY_ACCOUNT_HEADER = "account_header";
|
||||
public static final String KEY_USER_HANDLE = "user_handle";
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
@VisibleForTesting
|
||||
Account mAccount;
|
||||
private String mAccountLabel;
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
|
||||
@VisibleForTesting
|
||||
String mAccountType;
|
||||
private AccountSyncPreferenceController mAccountSynController;
|
||||
private RemoveAccountPreferenceController mRemoveAccountController;
|
||||
@@ -98,6 +96,11 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_account_detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.account_type_settings;
|
||||
@@ -110,6 +113,8 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
|
||||
controllers.add(mAccountSynController);
|
||||
mRemoveAccountController = new RemoveAccountPreferenceController(context, this);
|
||||
controllers.add(mRemoveAccountController);
|
||||
controllers.add(new AccountHeaderPreferenceController(
|
||||
context, getLifecycle(), getActivity(), this /* host */, getArguments()));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@@ -127,8 +132,6 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
|
||||
|
||||
@VisibleForTesting
|
||||
void updateUi() {
|
||||
final Preference headerPreference = findPreference(KEY_ACCOUNT_HEADER);
|
||||
headerPreference.setTitle(mAccount.name);
|
||||
final Context context = getContext();
|
||||
UserHandle userHandle = null;
|
||||
Bundle args = getArguments();
|
||||
@@ -136,14 +139,12 @@ public class AccountDetailDashboardFragment extends DashboardFragment {
|
||||
userHandle = args.getParcelable(KEY_USER_HANDLE);
|
||||
}
|
||||
final AuthenticatorHelper helper = new AuthenticatorHelper(context, userHandle, null);
|
||||
headerPreference.setIcon(helper.getDrawableForType(context, mAccountType));
|
||||
final AccountTypePreferenceLoader accountTypePreferenceLoader =
|
||||
new AccountTypePreferenceLoader(this, helper, userHandle);
|
||||
PreferenceScreen prefs =
|
||||
accountTypePreferenceLoader.addPreferencesForType(mAccountType, getPreferenceScreen());
|
||||
new AccountTypePreferenceLoader(this, helper, userHandle);
|
||||
PreferenceScreen prefs = accountTypePreferenceLoader.addPreferencesForType(
|
||||
mAccountType, getPreferenceScreen());
|
||||
if (prefs != null) {
|
||||
accountTypePreferenceLoader.updatePreferenceIntents(prefs, mAccountType, mAccount);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.accounts;
|
||||
|
||||
import static com.android.settings.accounts.AccountDetailDashboardFragment.KEY_ACCOUNT;
|
||||
import static com.android.settings.accounts.AccountDetailDashboardFragment.KEY_USER_HANDLE;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.support.v14.preference.PreferenceFragment;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.LayoutPreference;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.accounts.AuthenticatorHelper;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
public class AccountHeaderPreferenceController extends PreferenceController
|
||||
implements LifecycleObserver, OnResume {
|
||||
|
||||
private static final String KEY_ACCOUNT_HEADER = "account_header";
|
||||
|
||||
private final Activity mActivity;
|
||||
private final PreferenceFragment mHost;
|
||||
private final Account mAccount;
|
||||
private final UserHandle mUserHandle;
|
||||
|
||||
private LayoutPreference mHeaderPreference;
|
||||
|
||||
public AccountHeaderPreferenceController(Context context, Lifecycle lifecycle,
|
||||
Activity activity, PreferenceFragment host, Bundle args) {
|
||||
super(context);
|
||||
mActivity = activity;
|
||||
mHost = host;
|
||||
if (args != null && args.containsKey(KEY_ACCOUNT)) {
|
||||
mAccount = args.getParcelable(KEY_ACCOUNT);
|
||||
} else {
|
||||
mAccount = null;
|
||||
}
|
||||
|
||||
if (args != null && args.containsKey(KEY_USER_HANDLE)) {
|
||||
mUserHandle = args.getParcelable(KEY_USER_HANDLE);
|
||||
} else {
|
||||
mUserHandle = null;
|
||||
}
|
||||
if (lifecycle != null) {
|
||||
lifecycle.addObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return mAccount != null && mUserHandle != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_ACCOUNT_HEADER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mHeaderPreference = (LayoutPreference) screen.findPreference(KEY_ACCOUNT_HEADER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
final AuthenticatorHelper helper = new AuthenticatorHelper(mContext, mUserHandle, null);
|
||||
|
||||
EntityHeaderController
|
||||
.newInstance(mActivity, mHost, mHeaderPreference.findViewById(R.id.entity_header))
|
||||
.setLabel(mAccount.name)
|
||||
.setIcon(helper.getDrawableForType(mContext, mAccount.type))
|
||||
.done(mActivity, true /* rebindButtons */);
|
||||
}
|
||||
}
|
||||
@@ -47,14 +47,14 @@ import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.instrumentation.MetricsFeatureProvider;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.search.SearchIndexableRaw;
|
||||
import com.android.settings.search2.SearchFeatureProviderImpl;
|
||||
import com.android.settings.search.SearchFeatureProviderImpl;
|
||||
import com.android.settingslib.RestrictedPreference;
|
||||
import com.android.settingslib.accounts.AuthenticatorHelper;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -19,23 +19,31 @@ package com.android.settings.accounts;
|
||||
import static android.content.Intent.EXTRA_USER;
|
||||
|
||||
import android.accounts.Account;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.SyncAdapterType;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settingslib.accounts.AuthenticatorHelper;
|
||||
|
||||
public class AccountSyncPreferenceController extends PreferenceController {
|
||||
public class AccountSyncPreferenceController extends PreferenceController
|
||||
implements AuthenticatorHelper.OnAccountsUpdateListener {
|
||||
|
||||
private static final String TAG = "AccountSyncController";
|
||||
private static final String KEY_ACCOUNT_SYNC = "account_sync";
|
||||
|
||||
private Account mAccount;
|
||||
private UserHandle mUserHandle;
|
||||
private AuthenticatorHelper mAuthenticatorHelper;
|
||||
private Preference mPreference;
|
||||
|
||||
public AccountSyncPreferenceController(Context context) {
|
||||
super(context);
|
||||
@@ -65,8 +73,61 @@ public class AccountSyncPreferenceController extends PreferenceController {
|
||||
return KEY_ACCOUNT_SYNC;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
super.displayPreference(screen);
|
||||
mPreference = screen.findPreference(getPreferenceKey());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
updateSummary(preference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAccountsUpdate(UserHandle userHandle) {
|
||||
updateSummary(mPreference);
|
||||
}
|
||||
|
||||
public void init(Account account, UserHandle userHandle) {
|
||||
mAccount = account;
|
||||
mUserHandle = userHandle;
|
||||
mAuthenticatorHelper = new AuthenticatorHelper(mContext, mUserHandle, this);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void updateSummary(Preference preference) {
|
||||
final int userId = mUserHandle.getIdentifier();
|
||||
final SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypesAsUser(userId);
|
||||
int total = 0;
|
||||
int enabled = 0;
|
||||
if (syncAdapters != null) {
|
||||
for (int i = 0, n = syncAdapters.length; i < n; i++) {
|
||||
final SyncAdapterType sa = syncAdapters[i];
|
||||
if (!sa.accountType.equals(mAccount.type) || !sa.isUserVisible()) {
|
||||
continue;
|
||||
}
|
||||
final int syncState =
|
||||
ContentResolver.getIsSyncableAsUser(mAccount, sa.authority, userId);
|
||||
if (syncState > 0) {
|
||||
total++;
|
||||
final boolean syncEnabled = ContentResolver.getSyncAutomaticallyAsUser(
|
||||
mAccount, sa.authority, userId);
|
||||
final boolean oneTimeSyncMode =
|
||||
!ContentResolver.getMasterSyncAutomaticallyAsUser(userId);
|
||||
if (oneTimeSyncMode || syncEnabled) {
|
||||
enabled++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (enabled == 0) {
|
||||
preference.setSummary(R.string.account_sync_summary_all_off);
|
||||
} else if (enabled == total) {
|
||||
preference.setSummary(R.string.account_sync_summary_all_on);
|
||||
} else {
|
||||
preference.setSummary(
|
||||
mContext.getString(R.string.account_sync_summary_some_on, enabled, total));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,6 @@ public class AccountTypePreference extends Preference implements OnPreferenceCli
|
||||
mFragment = fragment;
|
||||
mFragmentArguments = fragmentArguments;
|
||||
mMetricsCategory = metricsCategory;
|
||||
setWidgetLayoutResource(R.layout.account_type_preference);
|
||||
|
||||
setKey(buildKey(account));
|
||||
setTitle(mTitle);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
package com.android.settings.accounts;
|
||||
|
||||
import static android.content.Intent.EXTRA_USER;
|
||||
|
||||
import android.accounts.AccountManager;
|
||||
import android.accounts.AccountManagerCallback;
|
||||
import android.accounts.AccountManagerFuture;
|
||||
@@ -32,14 +34,12 @@ import android.os.UserManager;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.android.settings.ChooseLockSettingsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static android.content.Intent.EXTRA_USER;
|
||||
/**
|
||||
* Entry point Activity for account setup. Works as follows
|
||||
*
|
||||
|
||||
@@ -20,11 +20,11 @@ import android.provider.Settings.Global;
|
||||
import android.support.v7.preference.Preference;
|
||||
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
import com.android.settings.users.UserCapabilities;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
public class AddUserWhenLockedPreferenceController extends PreferenceController
|
||||
implements Preference.OnPreferenceChangeListener, LifecycleObserver, OnPause, OnResume {
|
||||
|
||||
@@ -44,10 +44,10 @@ import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.enterprise.EnterprisePrivacyFeatureProvider;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.FooterPreference;
|
||||
import com.android.settings.widget.FooterPreferenceMixin;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
|
||||
import com.android.settingslib.widget.FooterPreference;
|
||||
import com.android.settingslib.widget.FooterPreferenceMixin;
|
||||
|
||||
import com.google.android.collect.Maps;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.List;
|
||||
public class EmergencyInfoPreferenceController extends PreferenceController {
|
||||
|
||||
private static final String KEY_EMERGENCY_INFO = "emergency_info";
|
||||
private static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENGY_INFO";
|
||||
private static final String ACTION_EDIT_EMERGENCY_INFO = "android.settings.EDIT_EMERGENCY_INFO";
|
||||
private static final String PACKAGE_NAME_EMERGENCY = "com.android.emergency";
|
||||
|
||||
public EmergencyInfoPreferenceController(Context context) {
|
||||
|
||||
@@ -57,6 +57,11 @@ public class UserAndAccountDashboardFragment extends DashboardFragment {
|
||||
return R.xml.user_and_accounts_settings;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_user_and_account_dashboard;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PreferenceController> getPreferenceControllers(Context context) {
|
||||
final List<PreferenceController> controllers = new ArrayList<>();
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.applications;
|
||||
|
||||
import android.view.accessibility.AccessibilityManager;
|
||||
|
||||
/**
|
||||
* This class replicates a subset of the {@link android.view.accessibility.AccessibilityManager}.
|
||||
* The interface exists so that we can use a thin wrapper around the AccessibilityManager in
|
||||
* production code and a mock in tests.
|
||||
*/
|
||||
public class AccessibilityManagerWrapperImpl {
|
||||
|
||||
/**
|
||||
* Determines if the accessibility button within the system navigation area is supported.
|
||||
*
|
||||
* @return {@code true} if the accessibility button is supported on this device,
|
||||
* {@code false} otherwise
|
||||
* @hide
|
||||
*/
|
||||
public static boolean isAccessibilityButtonSupported() {
|
||||
return AccessibilityManager.isAccessibilityButtonSupported();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.applications;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.content.ComponentName;
|
||||
|
||||
/**
|
||||
* This interface replicates a subset of the
|
||||
* {@link android.accessibilityservice.AccessibilityServiceInfo}. The interface
|
||||
* exists so that we can use a thin wrapper around it in production code and a mock in tests.
|
||||
* We cannot directly mock or shadow it, because some of the methods we rely on are newer than
|
||||
* the API version supported by Robolectric.
|
||||
*/
|
||||
public interface AccessibilityServiceInfoWrapper {
|
||||
|
||||
/**
|
||||
* Returns the real {@code AccessibilityServiceInfo} object.
|
||||
*/
|
||||
AccessibilityServiceInfo getAccessibilityServiceInfo();
|
||||
|
||||
ComponentName getComponentName();
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.applications;
|
||||
|
||||
import android.accessibilityservice.AccessibilityServiceInfo;
|
||||
import android.content.ComponentName;
|
||||
|
||||
public class AccessibilityServiceInfoWrapperImpl implements AccessibilityServiceInfoWrapper {
|
||||
|
||||
private final AccessibilityServiceInfo mServiceInfo;
|
||||
|
||||
public AccessibilityServiceInfoWrapperImpl(AccessibilityServiceInfo serviceInfo) {
|
||||
mServiceInfo = serviceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessibilityServiceInfo getAccessibilityServiceInfo() {
|
||||
return mServiceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComponentName getComponentName() {
|
||||
return mServiceInfo.getComponentName();
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,8 @@ package com.android.settings.applications;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.defaultapps.DefaultBrowserPreferenceController;
|
||||
@@ -57,6 +57,15 @@ public class AdvancedAppSettings extends DashboardFragment {
|
||||
|
||||
@Override
|
||||
protected List<PreferenceController> getPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.APPLICATIONS_ADVANCED;
|
||||
}
|
||||
|
||||
private static List<PreferenceController> buildPreferenceControllers(Context context) {
|
||||
final List<PreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new DefaultBrowserPreferenceController(context));
|
||||
controllers.add(new DefaultWorkBrowserPreferenceController(context));
|
||||
@@ -68,11 +77,6 @@ public class AdvancedAppSettings extends DashboardFragment {
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.APPLICATIONS_ADVANCED;
|
||||
}
|
||||
|
||||
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider() {
|
||||
@Override
|
||||
@@ -94,6 +98,11 @@ public class AdvancedAppSettings extends DashboardFragment {
|
||||
.getPreferenceKey());
|
||||
return keys;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PreferenceController> getPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context);
|
||||
}
|
||||
};
|
||||
|
||||
static class SummaryProvider implements SummaryLoader.SummaryProvider {
|
||||
@@ -118,10 +127,10 @@ public class AdvancedAppSettings extends DashboardFragment {
|
||||
return;
|
||||
}
|
||||
CharSequence summary = concatSummaryText(
|
||||
mDefaultSmsPreferenceController.getDefaultAppLabel(),
|
||||
mDefaultBrowserPreferenceController.getDefaultAppLabel());
|
||||
mDefaultSmsPreferenceController.getDefaultAppLabel(),
|
||||
mDefaultBrowserPreferenceController.getDefaultAppLabel());
|
||||
summary = concatSummaryText(summary,
|
||||
mDefaultPhonePreferenceController.getDefaultAppLabel());
|
||||
mDefaultPhonePreferenceController.getDefaultAppLabel());
|
||||
if (!TextUtils.isEmpty(summary)) {
|
||||
mSummaryLoader.setSummary(this, summary);
|
||||
}
|
||||
@@ -139,11 +148,11 @@ public class AdvancedAppSettings extends DashboardFragment {
|
||||
}
|
||||
|
||||
public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY =
|
||||
new SummaryLoader.SummaryProviderFactory() {
|
||||
@Override
|
||||
public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
|
||||
SummaryLoader summaryLoader) {
|
||||
return new AdvancedAppSettings.SummaryProvider(activity, summaryLoader);
|
||||
}
|
||||
};
|
||||
new SummaryLoader.SummaryProviderFactory() {
|
||||
@Override
|
||||
public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
|
||||
SummaryLoader summaryLoader) {
|
||||
return new AdvancedAppSettings.SummaryProvider(activity, summaryLoader);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
package com.android.settings.applications;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
@@ -47,7 +50,12 @@ public class AppAndNotificationDashboardFragment extends DashboardFragment {
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
mProgressiveDisclosureMixin.setTileLimit(3);
|
||||
mProgressiveDisclosureMixin.setTileLimit(4);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_url_apps_and_notifications;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,14 +65,24 @@ public class AppAndNotificationDashboardFragment extends DashboardFragment {
|
||||
|
||||
@Override
|
||||
protected List<PreferenceController> getPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context);
|
||||
final Activity activity = getActivity();
|
||||
final Application app;
|
||||
if (activity != null) {
|
||||
app = activity.getApplication();
|
||||
} else {
|
||||
app = null;
|
||||
}
|
||||
return buildPreferenceControllers(context, app, this);
|
||||
}
|
||||
|
||||
private static List<PreferenceController> buildPreferenceControllers(Context context) {
|
||||
private static List<PreferenceController> buildPreferenceControllers(Context context,
|
||||
Application app, Fragment host) {
|
||||
final List<PreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new EmergencyBroadcastPreferenceController(context,
|
||||
"app_and_notif_cell_broadcast_settings"));
|
||||
controllers.add(new SpecialAppAccessPreferenceController(context));
|
||||
controllers.add(new AppPermissionsPreferenceController(context));
|
||||
controllers.add(new RecentAppsPreferenceController(context, app, host));
|
||||
return controllers;
|
||||
}
|
||||
|
||||
@@ -80,7 +98,7 @@ public class AppAndNotificationDashboardFragment extends DashboardFragment {
|
||||
|
||||
@Override
|
||||
public List<PreferenceController> getPreferenceControllers(Context context) {
|
||||
return buildPreferenceControllers(context);
|
||||
return buildPreferenceControllers(context, null, null /* host */);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
package com.android.settings.applications;
|
||||
|
||||
import android.app.AppGlobals;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.os.IBinder;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
@@ -293,7 +294,8 @@ public abstract class AppInfoBase extends SettingsPreferenceFragment
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String packageName = intent.getData().getSchemeSpecificPart();
|
||||
if (!mFinishing && mAppEntry.info.packageName.equals(packageName)) {
|
||||
if (!mFinishing && (mAppEntry == null || mAppEntry.info == null
|
||||
|| TextUtils.equals(mAppEntry.info.packageName, packageName))) {
|
||||
onPackageRemoved();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,17 @@
|
||||
|
||||
package com.android.settings.applications;
|
||||
|
||||
import static com.android.settings.applications.AppHeaderController.ActionType;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
|
||||
import static com.android.settings.widget.EntityHeaderController.ActionType;
|
||||
|
||||
public abstract class AppInfoWithHeader extends AppInfoBase {
|
||||
|
||||
private boolean mCreated;
|
||||
@@ -41,9 +41,9 @@ public abstract class AppInfoWithHeader extends AppInfoBase {
|
||||
mCreated = true;
|
||||
if (mPackageInfo == null) return;
|
||||
final Activity activity = getActivity();
|
||||
final Preference pref = FeatureFactory.getFactory(activity)
|
||||
.getApplicationFeatureProvider(activity)
|
||||
.newAppHeaderController(this, null /* appHeader */)
|
||||
final Preference pref = EntityHeaderController
|
||||
.newInstance(activity, this, null /* header */)
|
||||
.setRecyclerView(getListView(), getLifecycle())
|
||||
.setIcon(IconDrawableFactory.newInstance(activity)
|
||||
.getBadgedIcon(mPackageInfo.applicationInfo))
|
||||
.setLabel(mPackageInfo.applicationInfo.loadLabel(mPm))
|
||||
|
||||
@@ -28,6 +28,7 @@ import android.content.pm.PermissionInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@@ -43,6 +44,7 @@ import com.android.settings.core.InstrumentedPreferenceFragment;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -64,7 +66,7 @@ public class AppOpsDetails extends InstrumentedPreferenceFragment {
|
||||
final View appSnippet = mRootView.findViewById(R.id.app_snippet);
|
||||
CharSequence label = mPm.getApplicationLabel(pkgInfo.applicationInfo);
|
||||
Drawable icon = mPm.getApplicationIcon(pkgInfo.applicationInfo);
|
||||
InstalledAppDetails.setupAppSnippet(appSnippet, label, icon,
|
||||
setupAppSnippet(appSnippet, label, icon,
|
||||
pkgInfo != null ? pkgInfo.versionName : null);
|
||||
}
|
||||
|
||||
@@ -191,4 +193,30 @@ public class AppOpsDetails extends InstrumentedPreferenceFragment {
|
||||
setIntentAndFinish(true, true);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated app info pages should use {@link EntityHeaderController} to show the app header.
|
||||
*/
|
||||
void setupAppSnippet(View appSnippet, CharSequence label, Drawable icon,
|
||||
CharSequence versionName) {
|
||||
LayoutInflater.from(appSnippet.getContext()).inflate(R.layout.widget_text_views,
|
||||
appSnippet.findViewById(android.R.id.widget_frame));
|
||||
|
||||
ImageView iconView = appSnippet.findViewById(android.R.id.icon);
|
||||
iconView.setImageDrawable(icon);
|
||||
// Set application name.
|
||||
TextView labelView = appSnippet.findViewById(android.R.id.title);
|
||||
labelView.setText(label);
|
||||
// Version number of application
|
||||
TextView appVersion = appSnippet.findViewById(R.id.widget_text1);
|
||||
|
||||
if (!TextUtils.isEmpty(versionName)) {
|
||||
appVersion.setSelected(true);
|
||||
appVersion.setVisibility(View.VISIBLE);
|
||||
appVersion.setText(appSnippet.getContext().getString(R.string.version_text,
|
||||
String.valueOf(versionName)));
|
||||
} else {
|
||||
appVersion.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.applications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.PermissionGroupInfo;
|
||||
import android.content.pm.PermissionInfo;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Log;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class AppPermissionsPreferenceController extends PreferenceController {
|
||||
|
||||
private static final String TAG = "AppPermissionPrefCtrl";
|
||||
private static final String KEY_APP_PERMISSION_GROUPS = "manage_perms";
|
||||
private static final String[] PERMISSION_GROUPS = new String[] {
|
||||
"android.permission-group.LOCATION",
|
||||
"android.permission-group.MICROPHONE",
|
||||
"android.permission-group.CAMERA",
|
||||
"android.permission-group.SMS",
|
||||
"android.permission-group.CONTACTS",
|
||||
"android.permission-group.PHONE"};
|
||||
|
||||
private static final int NUM_PERMISSION_TO_USE = 3;
|
||||
|
||||
private final PackageManager mPackageManager;
|
||||
|
||||
public AppPermissionsPreferenceController(Context context) {
|
||||
super(context);
|
||||
mPackageManager = context.getPackageManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_APP_PERMISSION_GROUPS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
final String summary = getSummary();
|
||||
if (summary != null) {
|
||||
preference.setSummary(summary);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Summary text looks like: Apps using Permission1, Permission2, Permission3
|
||||
The 3 permissions are the first three from the list which any app has granted:
|
||||
Location, Microphone, Camera, Sms, Contacts, and Phone
|
||||
*/
|
||||
private String getSummary() {
|
||||
final Set<String> permissions = getAllPermissionsInGroups();
|
||||
Set<String> grantedPermissionGroups = getGrantedPermissionGroups(permissions);
|
||||
CharSequence summary = null;
|
||||
int count = 0;
|
||||
for (String group : PERMISSION_GROUPS) {
|
||||
if (!grantedPermissionGroups.contains(group)) {
|
||||
continue;
|
||||
}
|
||||
summary = concatSummaryText(summary, group);
|
||||
if (++count >= NUM_PERMISSION_TO_USE) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return count > 0 ? mContext.getString(R.string.app_permissions_summary, summary) : null;
|
||||
}
|
||||
|
||||
private Set<String> getGrantedPermissionGroups(Set<String> permissions) {
|
||||
ArraySet<String> grantedPermissionGroups = new ArraySet<>();
|
||||
List<PackageInfo> installedPackages =
|
||||
mPackageManager.getInstalledPackages(PackageManager.GET_PERMISSIONS);
|
||||
for (PackageInfo installedPackage : installedPackages) {
|
||||
if (installedPackage.permissions == null) {
|
||||
continue;
|
||||
}
|
||||
for (PermissionInfo permissionInfo : installedPackage.permissions) {
|
||||
if (permissions.contains(permissionInfo.name)
|
||||
&& !grantedPermissionGroups.contains(permissionInfo.group)) {
|
||||
grantedPermissionGroups.add(permissionInfo.group);
|
||||
}
|
||||
}
|
||||
}
|
||||
return grantedPermissionGroups;
|
||||
}
|
||||
|
||||
private CharSequence concatSummaryText(CharSequence currentSummary, String permission) {
|
||||
final CharSequence label = getPermissionGroupLabel(permission);
|
||||
if (TextUtils.isEmpty(currentSummary)) {
|
||||
return label;
|
||||
}
|
||||
return mContext.getString(R.string.join_many_items_middle, currentSummary, label);
|
||||
}
|
||||
|
||||
private CharSequence getPermissionGroupLabel(String group) {
|
||||
try {
|
||||
final PermissionGroupInfo groupInfo = mPackageManager.getPermissionGroupInfo(group, 0);
|
||||
return groupInfo.loadLabel(mPackageManager);
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e(TAG, "Error getting permissions label.", e);
|
||||
}
|
||||
return group;
|
||||
}
|
||||
|
||||
private Set<String> getAllPermissionsInGroups() {
|
||||
ArraySet<String> result = new ArraySet<>();
|
||||
for (String group : PERMISSION_GROUPS) {
|
||||
try {
|
||||
final List<PermissionInfo> permissions =
|
||||
mPackageManager.queryPermissionsByGroup(group, 0);
|
||||
for (PermissionInfo permissionInfo : permissions) {
|
||||
result.add(permissionInfo.name);
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
Log.e(TAG, "Error getting permissions in group "+group, e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -29,14 +29,8 @@ import java.util.Set;
|
||||
public interface ApplicationFeatureProvider {
|
||||
|
||||
/**
|
||||
* Returns a new {@link AppHeaderController} instance to customize app header.
|
||||
*/
|
||||
AppHeaderController newAppHeaderController(Fragment fragment, View appHeader);
|
||||
|
||||
/**
|
||||
*
|
||||
* Returns a new {@link InstantAppButtonsController} instance for showing buttons
|
||||
* only relevant to instant apps.
|
||||
* Returns a new {@link InstantAppButtonsController} instance for showing buttons
|
||||
* only relevant to instant apps.
|
||||
*/
|
||||
InstantAppButtonsController newInstantAppButtonsController(Fragment fragment,
|
||||
View view, InstantAppButtonsController.ShowDialogDelegate showDialogDelegate);
|
||||
@@ -45,7 +39,7 @@ public interface ApplicationFeatureProvider {
|
||||
* Calculates the total number of apps installed on the device via policy in the current user
|
||||
* and all its managed profiles.
|
||||
*
|
||||
* @param async Whether to count asynchronously in a background thread
|
||||
* @param async Whether to count asynchronously in a background thread
|
||||
* @param callback The callback to invoke with the result
|
||||
*/
|
||||
void calculateNumberOfPolicyInstalledApps(boolean async, NumberOfAppsCallback callback);
|
||||
@@ -62,10 +56,10 @@ public interface ApplicationFeatureProvider {
|
||||
* Asynchronously calculates the total number of apps installed in the current user and all its
|
||||
* managed profiles that have been granted one or more of the given permissions by the admin.
|
||||
*
|
||||
* @param permissions Only consider apps that have been granted one or more of these permissions
|
||||
* by the admin, either at run-time or install-time
|
||||
* @param async Whether to count asynchronously in a background thread
|
||||
* @param callback The callback to invoke with the result
|
||||
* @param permissions Only consider apps that have been granted one or more of these
|
||||
* permissions by the admin, either at run-time or install-time
|
||||
* @param async Whether to count asynchronously in a background thread
|
||||
* @param callback The callback to invoke with the result
|
||||
*/
|
||||
void calculateNumberOfAppsWithAdminGrantedPermissions(String[] permissions, boolean async,
|
||||
NumberOfAppsCallback callback);
|
||||
@@ -74,9 +68,9 @@ public interface ApplicationFeatureProvider {
|
||||
* Asynchronously builds the list of apps installed in the current user and all its
|
||||
* managed profiles that have been granted one or more of the given permissions by the admin.
|
||||
*
|
||||
* @param permissions Only consider apps that have been granted one or more of these permissions
|
||||
* by the admin, either at run-time or install-time
|
||||
* @param callback The callback to invoke with the result
|
||||
* @param permissions Only consider apps that have been granted one or more of these
|
||||
* permissions by the admin, either at run-time or install-time
|
||||
* @param callback The callback to invoke with the result
|
||||
*/
|
||||
void listAppsWithAdminGrantedPermissions(String[] permissions, ListOfAppsCallback callback);
|
||||
|
||||
@@ -86,10 +80,9 @@ public interface ApplicationFeatureProvider {
|
||||
* given intent (e.g. open browser), even if the user has other apps installed that would also
|
||||
* be able to handle the intent.
|
||||
*
|
||||
* @param userId ID of the user for which to find persistent preferred activities
|
||||
* @param intent The intents for which to find persistent preferred activities
|
||||
*
|
||||
* @return the persistent preferred activites for the given intents, ordered first by user id,
|
||||
* @param userId ID of the user for which to find persistent preferred activities
|
||||
* @param intents The intents for which to find persistent preferred activities
|
||||
* @return the persistent preferred activities for the given intents, ordered first by user id,
|
||||
* then by package name
|
||||
*/
|
||||
List<UserAppInfo> findPersistentPreferredActivities(@UserIdInt int userId, Intent[] intents);
|
||||
|
||||
@@ -24,7 +24,6 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.util.ArraySet;
|
||||
import android.view.View;
|
||||
@@ -53,11 +52,6 @@ public class ApplicationFeatureProviderImpl implements ApplicationFeatureProvide
|
||||
mUm = UserManager.get(mContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppHeaderController newAppHeaderController(Fragment fragment, View appHeader) {
|
||||
return new AppHeaderController(mContext, fragment, appHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstantAppButtonsController newInstantAppButtonsController(Fragment fragment,
|
||||
View view, InstantAppButtonsController.ShowDialogDelegate showDialogDelegate) {
|
||||
|
||||
@@ -24,16 +24,15 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.ChooseLockSettingsHelper;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsActivity;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.core.InstrumentedFragment;
|
||||
import com.android.settings.password.ChooseLockSettingsHelper;
|
||||
|
||||
/* Class to prompt for conversion of userdata to file based encryption
|
||||
*/
|
||||
public class ConvertToFbe extends SettingsPreferenceFragment {
|
||||
public class ConvertToFbe extends InstrumentedFragment {
|
||||
static final String TAG = "ConvertToFBE";
|
||||
static final String CONVERT_FBE_EXTRA = "ConvertFBE";
|
||||
private static final int KEYGUARD_REQUEST = 55;
|
||||
|
||||
@@ -20,8 +20,6 @@ import android.app.AppOpsManager;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
@@ -206,33 +204,6 @@ public class DrawOverlayDetails extends AppInfoWithHeader implements OnPreferenc
|
||||
|
||||
public static CharSequence getSummary(Context context, OverlayState overlayState) {
|
||||
return context.getString(overlayState.isPermissible() ?
|
||||
R.string.system_alert_window_on : R.string.system_alert_window_off);
|
||||
}
|
||||
|
||||
public static CharSequence getSummary(Context context, String pkg) {
|
||||
// first check if pkg is a system pkg
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
int uid = -1;
|
||||
try {
|
||||
ApplicationInfo appInfo = packageManager.getApplicationInfo(pkg, 0);
|
||||
uid = appInfo.uid;
|
||||
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||
return context.getString(R.string.system_alert_window_on);
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// pkg doesn't even exist?
|
||||
Log.w(LOG_TAG, "Package " + pkg + " not found", e);
|
||||
return context.getString(R.string.system_alert_window_off);
|
||||
}
|
||||
|
||||
AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context
|
||||
.APP_OPS_SERVICE);
|
||||
if (uid == -1) {
|
||||
return context.getString(R.string.system_alert_window_off);
|
||||
}
|
||||
|
||||
int mode = appOpsManager.noteOpNoThrow(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, uid, pkg);
|
||||
return context.getString((mode == AppOpsManager.MODE_ALLOWED) ?
|
||||
R.string.system_alert_window_on : R.string.system_alert_window_off);
|
||||
R.string.app_permission_summary_allowed : R.string.app_permission_summary_not_allowed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,6 @@
|
||||
*/
|
||||
package com.android.settings.applications;
|
||||
|
||||
import static android.app.Activity.RESULT_CANCELED;
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
@@ -29,12 +24,16 @@ import android.os.UserManager;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Settings;
|
||||
import com.android.settings.applications.AppStateInstallAppsBridge.InstallAppsState;
|
||||
import com.android.settingslib.RestrictedSwitchPreference;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
|
||||
import static android.app.Activity.RESULT_CANCELED;
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
public class ExternalSourcesDetails extends AppInfoWithHeader
|
||||
implements OnPreferenceChangeListener {
|
||||
|
||||
@@ -90,15 +89,12 @@ public class ExternalSourcesDetails extends AppInfoWithHeader
|
||||
return context.getString(R.string.disabled);
|
||||
}
|
||||
|
||||
final InstallAppsState appsState;
|
||||
if (entry.extraInfo instanceof InstallAppsState) {
|
||||
appsState = (InstallAppsState) entry.extraInfo;
|
||||
} else {
|
||||
appsState = new AppStateInstallAppsBridge(context, null, null)
|
||||
.createInstallAppsStateFor(entry.info.packageName, entry.info.uid);
|
||||
}
|
||||
return context.getString(appsState.canInstallApps() ? R.string.external_source_trusted
|
||||
: R.string.external_source_untrusted);
|
||||
final InstallAppsState appsState = new AppStateInstallAppsBridge(context, null, null)
|
||||
.createInstallAppsStateFor(entry.info.packageName, entry.info.uid);
|
||||
|
||||
return context.getString(appsState.canInstallApps()
|
||||
? R.string.app_permission_summary_allowed
|
||||
: R.string.app_permission_summary_not_allowed);
|
||||
}
|
||||
|
||||
private void setCanInstallApps(boolean newState) {
|
||||
|
||||
@@ -37,7 +37,6 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.icu.text.ListFormatter;
|
||||
import android.net.INetworkStatsService;
|
||||
import android.net.INetworkStatsSession;
|
||||
@@ -60,16 +59,12 @@ import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.IWebViewUpdateService;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.internal.os.BatterySipper;
|
||||
@@ -96,7 +91,7 @@ import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.notification.AppNotificationSettings;
|
||||
import com.android.settings.notification.NotificationBackend;
|
||||
import com.android.settings.notification.NotificationBackend.AppRow;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
import com.android.settingslib.AppItem;
|
||||
import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.settingslib.applications.AppUtils;
|
||||
@@ -214,7 +209,7 @@ public class InstalledAppDetails extends AppInfoBase
|
||||
|
||||
@Override
|
||||
public Loader<BatteryStatsHelper> onCreateLoader(int id, Bundle args) {
|
||||
return new BatteryStatsHelperLoader(getContext(), args);
|
||||
return new BatteryStatsHelperLoader(getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -381,7 +376,7 @@ public class InstalledAppDetails extends AppInfoBase
|
||||
}
|
||||
|
||||
setHasOptionsMenu(true);
|
||||
addPreferencesFromResource(R.xml.installed_app_details_ia);
|
||||
addPreferencesFromResource(R.xml.installed_app_details);
|
||||
addDynamicPrefs();
|
||||
if (Utils.isBandwidthControlEnabled()) {
|
||||
INetworkStatsService statsService = INetworkStatsService.Stub.asInterface(
|
||||
@@ -447,14 +442,13 @@ public class InstalledAppDetails extends AppInfoBase
|
||||
final Activity activity = getActivity();
|
||||
mHeader = (LayoutPreference) findPreference(KEY_HEADER);
|
||||
mActionButtons = (LayoutPreference) findPreference(KEY_ACTION_BUTTONS);
|
||||
FeatureFactory.getFactory(activity)
|
||||
.getApplicationFeatureProvider(activity)
|
||||
.newAppHeaderController(this, mHeader.findViewById(R.id.app_snippet))
|
||||
EntityHeaderController.newInstance(activity, this, mHeader.findViewById(R.id.entity_header))
|
||||
.setRecyclerView(getListView(), getLifecycle())
|
||||
.setPackageName(mPackageName)
|
||||
.setButtonActions(AppHeaderController.ActionType.ACTION_APP_PREFERENCE,
|
||||
AppHeaderController.ActionType.ACTION_NONE)
|
||||
.setButtonActions(EntityHeaderController.ActionType.ACTION_APP_PREFERENCE,
|
||||
EntityHeaderController.ActionType.ACTION_NONE)
|
||||
.styleActionBar(activity)
|
||||
.bindAppHeaderButtons();
|
||||
.bindHeaderButtons();
|
||||
prepareUninstallAndStop();
|
||||
|
||||
mNotificationPreference = findPreference(KEY_NOTIFICATION);
|
||||
@@ -620,20 +614,18 @@ public class InstalledAppDetails extends AppInfoBase
|
||||
|
||||
// Utility method to set application label and icon.
|
||||
private void setAppLabelAndIcon(PackageInfo pkgInfo) {
|
||||
final View appSnippet = mHeader.findViewById(R.id.app_snippet);
|
||||
final View appSnippet = mHeader.findViewById(R.id.entity_header);
|
||||
mState.ensureIcon(mAppEntry);
|
||||
final Activity activity = getActivity();
|
||||
final boolean isInstantApp = AppUtils.isInstant(mPackageInfo.applicationInfo);
|
||||
final CharSequence summary =
|
||||
isInstantApp ? null : getString(Utils.getInstallationStatus(mAppEntry.info));
|
||||
FeatureFactory.getFactory(activity)
|
||||
.getApplicationFeatureProvider(activity)
|
||||
.newAppHeaderController(this, appSnippet)
|
||||
.setLabel(mAppEntry)
|
||||
.setIcon(mAppEntry)
|
||||
.setSummary(summary)
|
||||
.setIsInstantApp(isInstantApp)
|
||||
.done(activity, false /* rebindActions */);
|
||||
EntityHeaderController.newInstance(activity, this, appSnippet)
|
||||
.setLabel(mAppEntry)
|
||||
.setIcon(mAppEntry)
|
||||
.setSummary(summary)
|
||||
.setIsInstantApp(isInstantApp)
|
||||
.done(activity, false /* rebindActions */);
|
||||
mVersionPreference.setSummary(getString(R.string.version_text, pkgInfo.versionName));
|
||||
}
|
||||
|
||||
@@ -1058,9 +1050,10 @@ public class InstalledAppDetails extends AppInfoBase
|
||||
} else if (preference == mBatteryPreference) {
|
||||
if (isBatteryStatsAvailable()) {
|
||||
BatteryEntry entry = new BatteryEntry(getContext(), null, mUserManager, mSipper);
|
||||
entry.defaultPackageName = mPackageName;
|
||||
AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
|
||||
this, mBatteryHelper, BatteryStats.STATS_SINCE_CHARGED, entry,
|
||||
mBatteryPercent);
|
||||
mBatteryPercent, null /* mAnomalies */);
|
||||
} else {
|
||||
AdvancedPowerUsageDetail.startBatteryDetailPage((SettingsActivity) getActivity(),
|
||||
this, mPackageName);
|
||||
@@ -1256,7 +1249,8 @@ public class InstalledAppDetails extends AppInfoBase
|
||||
Preference pref = findPreference("default_home");
|
||||
|
||||
if (pref != null) {
|
||||
pref.setSummary(DefaultHomePreferenceController.isHomeDefault(mPackageName, context)
|
||||
pref.setSummary(DefaultHomePreferenceController.isHomeDefault(mPackageName,
|
||||
new PackageManagerWrapperImpl(context.getPackageManager()))
|
||||
? R.string.yes : R.string.no);
|
||||
}
|
||||
pref = findPreference("default_browser");
|
||||
@@ -1300,32 +1294,6 @@ public class InstalledAppDetails extends AppInfoBase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated app info pages should use {@link AppHeaderController} to show the app header.
|
||||
*/
|
||||
public static void setupAppSnippet(View appSnippet, CharSequence label, Drawable icon,
|
||||
CharSequence versionName) {
|
||||
LayoutInflater.from(appSnippet.getContext()).inflate(R.layout.widget_text_views,
|
||||
(ViewGroup) appSnippet.findViewById(android.R.id.widget_frame));
|
||||
|
||||
ImageView iconView = (ImageView) appSnippet.findViewById(R.id.app_detail_icon);
|
||||
iconView.setImageDrawable(icon);
|
||||
// Set application name.
|
||||
TextView labelView = (TextView) appSnippet.findViewById(R.id.app_detail_title);
|
||||
labelView.setText(label);
|
||||
// Version number of application
|
||||
TextView appVersion = (TextView) appSnippet.findViewById(R.id.widget_text1);
|
||||
|
||||
if (!TextUtils.isEmpty(versionName)) {
|
||||
appVersion.setSelected(true);
|
||||
appVersion.setVisibility(View.VISIBLE);
|
||||
appVersion.setText(appSnippet.getContext().getString(R.string.version_text,
|
||||
String.valueOf(versionName)));
|
||||
} else {
|
||||
appVersion.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public static NetworkTemplate getTemplate(Context context) {
|
||||
if (DataUsageList.hasReadyMobileRadio(context)) {
|
||||
return NetworkTemplate.buildTemplateMobileWildcard();
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.applications;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v4.content.res.TypedArrayUtils;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.util.AttributeSet;
|
||||
@@ -33,19 +34,30 @@ import com.android.settings.Utils;
|
||||
public class LayoutPreference extends Preference {
|
||||
|
||||
private final View.OnClickListener mClickListener = v -> performClick(v);
|
||||
private boolean mAllowDividerAbove;
|
||||
private boolean mAllowDividerBelow;
|
||||
|
||||
@VisibleForTesting
|
||||
View mRootView;
|
||||
|
||||
public LayoutPreference(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
final TypedArray a = context.obtainStyledAttributes(
|
||||
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Preference);
|
||||
mAllowDividerAbove = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerAbove,
|
||||
R.styleable.Preference_allowDividerAbove, false);
|
||||
mAllowDividerBelow = TypedArrayUtils.getBoolean(a, R.styleable.Preference_allowDividerBelow,
|
||||
R.styleable.Preference_allowDividerBelow, false);
|
||||
a.recycle();
|
||||
|
||||
a = context.obtainStyledAttributes(
|
||||
attrs, com.android.internal.R.styleable.Preference, 0, 0);
|
||||
int layoutResource = a.getResourceId(com.android.internal.R.styleable.Preference_layout,
|
||||
0);
|
||||
if (layoutResource == 0) {
|
||||
throw new IllegalArgumentException("LayoutPreference requires a layout to be defined");
|
||||
}
|
||||
a.recycle();
|
||||
|
||||
// Need to create view now so that findViewById can be called immediately.
|
||||
final View view = LayoutInflater.from(getContext())
|
||||
.inflate(layoutResource, null, false);
|
||||
@@ -78,6 +90,8 @@ public class LayoutPreference extends Preference {
|
||||
final boolean selectable = isSelectable();
|
||||
holder.itemView.setFocusable(selectable);
|
||||
holder.itemView.setClickable(selectable);
|
||||
holder.setDividerAllowedAbove(mAllowDividerAbove);
|
||||
holder.setDividerAllowedBelow(mAllowDividerBelow);
|
||||
|
||||
FrameLayout layout = (FrameLayout) holder.itemView;
|
||||
layout.removeAllViews();
|
||||
@@ -88,7 +102,7 @@ public class LayoutPreference extends Preference {
|
||||
layout.addView(mRootView);
|
||||
}
|
||||
|
||||
public View findViewById(int id) {
|
||||
public <T extends View> T findViewById(int id) {
|
||||
return mRootView.findViewById(id);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.applications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
public class LinearColorPreference extends Preference {
|
||||
float mRedRatio;
|
||||
float mYellowRatio;
|
||||
float mGreenRatio;
|
||||
int mRedColor = 0xffaa5030;
|
||||
int mYellowColor = 0xffaaaa30;
|
||||
int mGreenColor = 0xff30aa50;
|
||||
int mColoredRegions = LinearColorBar.REGION_ALL;
|
||||
LinearColorBar.OnRegionTappedListener mOnRegionTappedListener;
|
||||
|
||||
public LinearColorPreference(Context context) {
|
||||
super(context);
|
||||
setLayoutResource(R.layout.preference_linearcolor);
|
||||
}
|
||||
|
||||
public void setRatios(float red, float yellow, float green) {
|
||||
mRedRatio = red;
|
||||
mYellowRatio = yellow;
|
||||
mGreenRatio = green;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
public void setColors(int red, int yellow, int green) {
|
||||
mRedColor = red;
|
||||
mYellowColor = yellow;
|
||||
mGreenColor = green;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
public void setOnRegionTappedListener(LinearColorBar.OnRegionTappedListener listener) {
|
||||
mOnRegionTappedListener = listener;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
public void setColoredRegions(int regions) {
|
||||
mColoredRegions = regions;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(PreferenceViewHolder view) {
|
||||
super.onBindViewHolder(view);
|
||||
|
||||
LinearColorBar colors = (LinearColorBar)view.findViewById(
|
||||
R.id.linear_color_bar);
|
||||
colors.setShowIndicator(false);
|
||||
colors.setColors(mRedColor, mYellowColor, mGreenColor);
|
||||
colors.setRatios(mRedRatio, mYellowRatio, mGreenRatio);
|
||||
colors.setColoredRegions(mColoredRegions);
|
||||
colors.setOnRegionTappedListener(mOnRegionTappedListener);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.android.settings.applications;
|
||||
|
||||
import android.annotation.IdRes;
|
||||
import android.annotation.Nullable;
|
||||
import android.annotation.StringRes;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -148,7 +149,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
public static final int FILTER_APPS_COUNT = 13; // This should always be the last entry
|
||||
|
||||
// Mapping to string labels for the FILTER_APPS_* constants above.
|
||||
public static final @IdRes int[] FILTER_LABELS = new int[FILTER_APPS_COUNT];
|
||||
@IdRes
|
||||
public static final int[] FILTER_LABELS = new int[FILTER_APPS_COUNT];
|
||||
|
||||
// Mapping to filters for the FILTER_APPS_* constants above.
|
||||
public static final AppFilter[] FILTERS = new AppFilter[FILTER_APPS_COUNT];
|
||||
@@ -212,8 +214,9 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
}
|
||||
|
||||
// Storage types. Used to determine what the extra item in the list of preferences is.
|
||||
public static final int STORAGE_TYPE_DEFAULT = 0;
|
||||
public static final int STORAGE_TYPE_DEFAULT = 0; // Show all apps that are not categorized.
|
||||
public static final int STORAGE_TYPE_MUSIC = 1;
|
||||
public static final int STORAGE_TYPE_LEGACY = 2; // Show apps even if they can be categorized.
|
||||
|
||||
// sort order
|
||||
private int mSortOrder = R.id.sort_order_alpha;
|
||||
@@ -261,8 +264,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
|
||||
// List types that should show instant apps.
|
||||
public static final Set<Integer> LIST_TYPES_WITH_INSTANT = new ArraySet<>(Arrays.asList(
|
||||
LIST_TYPE_MAIN,
|
||||
LIST_TYPE_STORAGE));
|
||||
LIST_TYPE_MAIN,
|
||||
LIST_TYPE_STORAGE));
|
||||
|
||||
private View mRootView;
|
||||
|
||||
@@ -338,13 +341,12 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
Bundle savedInstanceState) {
|
||||
// initialize the inflater
|
||||
mInflater = inflater;
|
||||
|
||||
mRootView = inflater.inflate(R.layout.manage_applications_apps, null);
|
||||
mLoadingContainer = mRootView.findViewById(R.id.loading_container);
|
||||
mLoadingContainer.setVisibility(View.VISIBLE);
|
||||
mListContainer = mRootView.findViewById(R.id.list_container);
|
||||
if (mListContainer != null) {
|
||||
// Create adapter and list view here
|
||||
@@ -393,7 +395,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
return mRootView;
|
||||
}
|
||||
|
||||
private void createHeader() {
|
||||
@VisibleForTesting
|
||||
void createHeader() {
|
||||
Activity activity = getActivity();
|
||||
FrameLayout pinnedHeader = (FrameLayout) mRootView.findViewById(R.id.pinned_header);
|
||||
mSpinnerHeader = activity.getLayoutInflater()
|
||||
@@ -425,12 +428,13 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static @Nullable AppFilter getCompositeFilter(int listType, int storageType, String volumeUuid) {
|
||||
@Nullable
|
||||
static AppFilter getCompositeFilter(int listType, int storageType, String volumeUuid) {
|
||||
AppFilter filter = new VolumeFilter(volumeUuid);
|
||||
if (listType == LIST_TYPE_STORAGE) {
|
||||
if (storageType == STORAGE_TYPE_MUSIC) {
|
||||
filter = new CompoundFilter(ApplicationsState.FILTER_AUDIO, filter);
|
||||
} else {
|
||||
} else if (storageType == STORAGE_TYPE_DEFAULT) {
|
||||
filter = new CompoundFilter(ApplicationsState.FILTER_OTHER_APPS, filter);
|
||||
}
|
||||
return filter;
|
||||
@@ -506,10 +510,9 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
updateView();
|
||||
updateOptionsMenu();
|
||||
if (mApplications != null) {
|
||||
mApplications.resume(mSortOrder);
|
||||
mApplications.updateLoading();
|
||||
@@ -527,16 +530,11 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
if (mApplications != null) {
|
||||
mApplications.pause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
mResetAppsHelper.stop();
|
||||
}
|
||||
|
||||
@@ -572,8 +570,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
private void startApplicationDetailsActivity() {
|
||||
switch (mListType) {
|
||||
case LIST_TYPE_NOTIFICATION:
|
||||
startAppInfoFragment(AppNotificationSettings.class,
|
||||
R.string.app_notifications_title);
|
||||
startAppInfoFragment(AppNotificationSettings.class, R.string.notifications_title);
|
||||
break;
|
||||
case LIST_TYPE_USAGE_ACCESS:
|
||||
startAppInfoFragment(UsageAccessDetails.class, R.string.usage_access);
|
||||
@@ -601,8 +598,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
startAppInfoFragment(AppStorageSettings.class, R.string.storage_movies_tv);
|
||||
break;
|
||||
// TODO: Figure out if there is a way where we can spin up the profile's settings
|
||||
// process ahead of time, to avoid a long load of data when user clicks on a managed app.
|
||||
// Maybe when they load the list of apps that contains managed profile apps.
|
||||
// process ahead of time, to avoid a long load of data when user clicks on a managed
|
||||
// app. Maybe when they load the list of apps that contains managed profile apps.
|
||||
default:
|
||||
startAppInfoFragment(InstalledAppDetails.class, R.string.application_info_label);
|
||||
break;
|
||||
@@ -616,8 +613,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
HelpUtils.prepareHelpMenuItem(getActivity(), menu, mListType == LIST_TYPE_MAIN
|
||||
? R.string.help_uri_apps : R.string.help_uri_notifications, getClass().getName());
|
||||
HelpUtils.prepareHelpMenuItem(getActivity(), menu, getHelpResource(), getClass().getName());
|
||||
mOptionsMenu = menu;
|
||||
inflater.inflate(R.menu.manage_apps, menu);
|
||||
updateOptionsMenu();
|
||||
@@ -633,11 +629,21 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
mOptionsMenu = null;
|
||||
}
|
||||
|
||||
@StringRes
|
||||
int getHelpResource() {
|
||||
if (mListType == LIST_TYPE_MAIN) {
|
||||
return R.string.help_uri_apps;
|
||||
} else if (mListType == LIST_TYPE_USAGE_ACCESS) {
|
||||
return R.string.help_url_usage_access;
|
||||
} else {
|
||||
return R.string.help_uri_notifications;
|
||||
}
|
||||
}
|
||||
|
||||
void updateOptionsMenu() {
|
||||
if (mOptionsMenu == null) {
|
||||
return;
|
||||
}
|
||||
final Context context = getActivity();
|
||||
mOptionsMenu.findItem(R.id.advanced).setVisible(false);
|
||||
|
||||
mOptionsMenu.findItem(R.id.sort_order_alpha).setVisible(mListType == LIST_TYPE_STORAGE
|
||||
@@ -649,6 +655,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
&& mListType != LIST_TYPE_HIGH_POWER);
|
||||
mOptionsMenu.findItem(R.id.hide_system).setVisible(mShowSystem
|
||||
&& mListType != LIST_TYPE_HIGH_POWER);
|
||||
|
||||
mOptionsMenu.findItem(R.id.reset_app_preferences).setVisible(mListType == LIST_TYPE_MAIN);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -675,7 +683,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
if (mListType == LIST_TYPE_NOTIFICATION) {
|
||||
((SettingsActivity) getActivity()).startPreferencePanel(this,
|
||||
ConfigureNotificationSettings.class.getName(), null,
|
||||
R.string.configure_notification_settings, null, this, ADVANCED_SETTINGS);
|
||||
R.string.configure_notification_settings, null, this,
|
||||
ADVANCED_SETTINGS);
|
||||
} else {
|
||||
((SettingsActivity) getActivity()).startPreferencePanel(this,
|
||||
AdvancedAppSettings.class.getName(), null, R.string.configure_apps,
|
||||
@@ -826,6 +835,10 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
static class ApplicationsAdapter extends BaseAdapter implements Filterable,
|
||||
ApplicationsState.Callbacks, AppStateBaseBridge.Callback,
|
||||
AbsListView.RecyclerListener, SectionIndexer {
|
||||
|
||||
// how long to wait for app list to populate without showing the loading container
|
||||
private static final long DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS = 100L;
|
||||
|
||||
private static final SectionInfo[] EMPTY_SECTIONS = new SectionInfo[0];
|
||||
|
||||
private final ApplicationsState mState;
|
||||
@@ -881,8 +894,15 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
}
|
||||
};
|
||||
|
||||
private Runnable mShowLoadingContainerRunnable = new Runnable() {
|
||||
public void run() {
|
||||
Utils.handleLoadingContainer(mManageApplications.mLoadingContainer,
|
||||
mManageApplications.mListContainer, false /* done */, false /* animate */);
|
||||
}
|
||||
};
|
||||
|
||||
public ApplicationsAdapter(ApplicationsState state, ManageApplications manageApplications,
|
||||
int filterMode) {
|
||||
int filterMode) {
|
||||
mState = state;
|
||||
mFgHandler = new Handler();
|
||||
mBgHandler = new Handler(mState.getBackgroundLooper());
|
||||
@@ -955,7 +975,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
// Record the current scroll position before pausing.
|
||||
mLastIndex = mManageApplications.mListView.getFirstVisiblePosition();
|
||||
View v = mManageApplications.mListView.getChildAt(0);
|
||||
mLastTop = (v == null) ? 0 : (v.getTop() - mManageApplications.mListView.getPaddingTop());
|
||||
mLastTop =
|
||||
(v == null) ? 0 : (v.getTop() - mManageApplications.mListView.getPaddingTop());
|
||||
}
|
||||
|
||||
public void release() {
|
||||
@@ -1042,8 +1063,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
}
|
||||
|
||||
private ArrayList<ApplicationsState.AppEntry> removeDuplicateIgnoringUser(
|
||||
ArrayList<ApplicationsState.AppEntry> entries)
|
||||
{
|
||||
ArrayList<ApplicationsState.AppEntry> entries) {
|
||||
int size = entries.size();
|
||||
// returnList will not have more entries than entries
|
||||
ArrayList<ApplicationsState.AppEntry> returnEntries = new
|
||||
@@ -1089,6 +1109,9 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
|
||||
if (mSession.getAllApps().size() != 0
|
||||
&& mManageApplications.mListContainer.getVisibility() != View.VISIBLE) {
|
||||
// Cancel any pending task to show the loading animation and show the list of
|
||||
// apps directly.
|
||||
mFgHandler.removeCallbacks(mShowLoadingContainerRunnable);
|
||||
Utils.handleLoadingContainer(mManageApplications.mLoadingContainer,
|
||||
mManageApplications.mListContainer, true, true);
|
||||
}
|
||||
@@ -1102,7 +1125,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
}
|
||||
|
||||
private void rebuildSections() {
|
||||
if (mEntries!= null && mManageApplications.mListView.isFastScrollEnabled()) {
|
||||
if (mEntries != null && mManageApplications.mListView.isFastScrollEnabled()) {
|
||||
// Rebuild sections
|
||||
if (mIndex == null) {
|
||||
LocaleList locales = mContext.getResources().getConfiguration().getLocales();
|
||||
@@ -1140,14 +1163,20 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLoading() {
|
||||
Utils.handleLoadingContainer(mManageApplications.mLoadingContainer,
|
||||
mManageApplications.mListContainer,
|
||||
mHasReceivedLoadEntries && mSession.getAllApps().size() != 0, false);
|
||||
@VisibleForTesting
|
||||
void updateLoading() {
|
||||
final boolean appLoaded = mHasReceivedLoadEntries && mSession.getAllApps().size() != 0;
|
||||
if (appLoaded) {
|
||||
Utils.handleLoadingContainer(mManageApplications.mLoadingContainer,
|
||||
mManageApplications.mListContainer, true /* done */, false /* animate */);
|
||||
} else {
|
||||
mFgHandler.postDelayed(
|
||||
mShowLoadingContainerRunnable, DELAY_SHOW_LOADING_CONTAINER_THRESHOLD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList<ApplicationsState.AppEntry> applyPrefixFilter(CharSequence prefix,
|
||||
ArrayList<ApplicationsState.AppEntry> origEntries) {
|
||||
ArrayList<ApplicationsState.AppEntry> origEntries) {
|
||||
if (prefix == null || prefix.length() == 0) {
|
||||
return origEntries;
|
||||
} else {
|
||||
@@ -1366,8 +1395,9 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
case LIST_TYPE_USAGE_ACCESS:
|
||||
if (holder.entry.extraInfo != null) {
|
||||
holder.summary.setText((new UsageState((PermissionState) holder.entry
|
||||
.extraInfo)).isPermissible() ? R.string.switch_on_text :
|
||||
R.string.switch_off_text);
|
||||
.extraInfo)).isPermissible()
|
||||
? R.string.app_permission_summary_allowed
|
||||
: R.string.app_permission_summary_not_allowed);
|
||||
} else {
|
||||
holder.summary.setText(null);
|
||||
}
|
||||
@@ -1468,7 +1498,7 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
||||
= new SummaryLoader.SummaryProviderFactory() {
|
||||
@Override
|
||||
public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity,
|
||||
SummaryLoader summaryLoader) {
|
||||
SummaryLoader summaryLoader) {
|
||||
return new SummaryProvider(activity, summaryLoader);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.settings.applications;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.support.annotation.WorkerThread;
|
||||
@@ -38,6 +39,7 @@ public class MusicViewHolderController implements FileViewHolderController {
|
||||
private static final String TAG = "MusicViewHolderController";
|
||||
|
||||
private static final String AUTHORITY_MEDIA = "com.android.providers.media.documents";
|
||||
private static final int INSET_SIZE = 24; // dp
|
||||
|
||||
private Context mContext;
|
||||
private StorageStatsSource mSource;
|
||||
@@ -71,7 +73,8 @@ public class MusicViewHolderController implements FileViewHolderController {
|
||||
|
||||
@Override
|
||||
public void setupView(AppViewHolder holder) {
|
||||
holder.appIcon.setImageDrawable(mContext.getDrawable(R.drawable.ic_headset_24dp));
|
||||
holder.appIcon.setImageDrawable(
|
||||
new InsetDrawable(mContext.getDrawable(R.drawable.ic_headset_24dp), INSET_SIZE));
|
||||
holder.appName.setText(mContext.getText(R.string.audio_files_title));
|
||||
holder.summary.setText(Formatter.formatFileSize(mContext, mMusicSize));
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.android.settings.applications;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.dashboard.SummaryLoader;
|
||||
@@ -29,23 +28,24 @@ import com.android.settings.notification.NotificationBackend;
|
||||
*/
|
||||
public class NotificationApps extends ManageApplications {
|
||||
|
||||
private static class SummaryProvider implements SummaryLoader.SummaryProvider {
|
||||
public static class SummaryProvider implements SummaryLoader.SummaryProvider {
|
||||
|
||||
private final Context mContext;
|
||||
private final SummaryLoader mLoader;
|
||||
private final NotificationBackend mNotificationBackend;
|
||||
private final PackageManagerWrapper mPackageManager;
|
||||
|
||||
private SummaryProvider(Context context, SummaryLoader loader) {
|
||||
public SummaryProvider(Context context, SummaryLoader loader) {
|
||||
mContext = context;
|
||||
mLoader = loader;
|
||||
mNotificationBackend = new NotificationBackend();
|
||||
mPackageManager = new PackageManagerWrapperImpl(mContext.getPackageManager());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setListening(boolean listening) {
|
||||
if (listening) {
|
||||
new AppCounter(mContext,
|
||||
new PackageManagerWrapperImpl(mContext.getPackageManager())) {
|
||||
new AppCounter(mContext, mPackageManager) {
|
||||
@Override
|
||||
protected void onCountComplete(int num) {
|
||||
updateSummary(num);
|
||||
|
||||
@@ -101,13 +101,16 @@ public interface PackageManagerWrapper {
|
||||
void replacePreferredActivity(IntentFilter homeFilter, int matchCategoryEmpty,
|
||||
ComponentName[] componentNames, ComponentName component);
|
||||
|
||||
/**
|
||||
* Calls {@code PackageManager.getPrimaryStorageCurrentVolume}
|
||||
*/
|
||||
VolumeInfo getPrimaryStorageCurrentVolume();
|
||||
|
||||
/**
|
||||
* Calls {@code PackageManager.deletePackageAsUser}
|
||||
*/
|
||||
void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
|
||||
int userId);
|
||||
/**
|
||||
* Calls {@code PackageManager.getPrimaryStorageCurrentVolume}
|
||||
*/
|
||||
VolumeInfo getPrimaryStorageCurrentVolume();
|
||||
|
||||
int getPackageUidAsUser(String pkg, int userId) throws PackageManager.NameNotFoundException;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,11 @@ public class PackageManagerWrapperImpl implements PackageManagerWrapper {
|
||||
mPm.replacePreferredActivity(homeFilter, matchCategoryEmpty, componentNames, component);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VolumeInfo getPrimaryStorageCurrentVolume() {
|
||||
return mPm.getPrimaryStorageCurrentVolume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePackageAsUser(String packageName, IPackageDeleteObserver observer, int flags,
|
||||
int userId) {
|
||||
@@ -100,7 +105,8 @@ public class PackageManagerWrapperImpl implements PackageManagerWrapper {
|
||||
}
|
||||
|
||||
@Override
|
||||
public VolumeInfo getPrimaryStorageCurrentVolume() {
|
||||
return mPm.getPrimaryStorageCurrentVolume();
|
||||
public int getPackageUidAsUser(String pkg, int userId)
|
||||
throws PackageManager.NameNotFoundException {
|
||||
return mPm.getPackageUidAsUser(pkg, userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,10 +15,6 @@
|
||||
*/
|
||||
package com.android.settings.applications;
|
||||
|
||||
import static android.app.AppOpsManager.MODE_ALLOWED;
|
||||
import static android.app.AppOpsManager.MODE_ERRORED;
|
||||
import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.AppOpsManager;
|
||||
import android.content.Context;
|
||||
@@ -34,6 +30,10 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
import static android.app.AppOpsManager.MODE_ALLOWED;
|
||||
import static android.app.AppOpsManager.MODE_ERRORED;
|
||||
import static android.app.AppOpsManager.OP_PICTURE_IN_PICTURE;
|
||||
|
||||
public class PictureInPictureDetails extends AppInfoWithHeader
|
||||
implements OnPreferenceChangeListener {
|
||||
|
||||
@@ -124,7 +124,8 @@ public class PictureInPictureDetails extends AppInfoWithHeader
|
||||
static int getPreferenceSummary(Context context, int uid, String packageName) {
|
||||
final boolean enabled = PictureInPictureDetails.getEnterPipStateForPackage(context, uid,
|
||||
packageName);
|
||||
return enabled ? R.string.picture_in_picture_on : R.string.picture_in_picture_off;
|
||||
return enabled ? R.string.app_permission_summary_allowed
|
||||
: R.string.app_permission_summary_not_allowed;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package com.android.settings.applications;
|
||||
|
||||
import static com.android.settings.applications.AppHeaderController.ActionType;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningServiceInfo;
|
||||
@@ -53,7 +51,7 @@ import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.SummaryPreference;
|
||||
import com.android.settings.applications.ProcStatsEntry.Service;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settings.widget.EntityHeaderController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -61,6 +59,8 @@ import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static com.android.settings.widget.EntityHeaderController.ActionType;
|
||||
|
||||
public class ProcessStatsDetail extends SettingsPreferenceFragment {
|
||||
|
||||
private static final String TAG = "ProcessStatsDetail";
|
||||
@@ -126,19 +126,19 @@ public class ProcessStatsDetail extends SettingsPreferenceFragment {
|
||||
return;
|
||||
}
|
||||
final Activity activity = getActivity();
|
||||
final Preference pref = FeatureFactory.getFactory(activity)
|
||||
.getApplicationFeatureProvider(activity)
|
||||
.newAppHeaderController(this, null /* appHeader */)
|
||||
.setIcon(mApp.mUiTargetApp != null
|
||||
? IconDrawableFactory.newInstance(activity).getBadgedIcon(mApp.mUiTargetApp)
|
||||
: new ColorDrawable(0))
|
||||
.setLabel(mApp.mUiLabel)
|
||||
.setPackageName(mApp.mPackage)
|
||||
.setUid(mApp.mUiTargetApp != null
|
||||
? mApp.mUiTargetApp.uid
|
||||
: UserHandle.USER_NULL)
|
||||
.setButtonActions(ActionType.ACTION_APP_INFO, ActionType.ACTION_NONE)
|
||||
.done(activity, getPrefContext());
|
||||
final Preference pref = EntityHeaderController
|
||||
.newInstance(activity, this, null /* appHeader */)
|
||||
.setRecyclerView(getListView(), getLifecycle())
|
||||
.setIcon(mApp.mUiTargetApp != null
|
||||
? IconDrawableFactory.newInstance(activity).getBadgedIcon(mApp.mUiTargetApp)
|
||||
: new ColorDrawable(0))
|
||||
.setLabel(mApp.mUiLabel)
|
||||
.setPackageName(mApp.mPackage)
|
||||
.setUid(mApp.mUiTargetApp != null
|
||||
? mApp.mUiTargetApp.uid
|
||||
: UserHandle.USER_NULL)
|
||||
.setButtonActions(ActionType.ACTION_APP_INFO, ActionType.ACTION_NONE)
|
||||
.done(activity, getPrefContext());
|
||||
getPreferenceScreen().addPreference(pref);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,11 @@ public class ProcessStatsSummary extends ProcessStatsBase implements OnPreferenc
|
||||
return MetricsEvent.PROCESS_STATS_SUMMARY;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_uri_process_stats_summary;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
if (preference == mAppListPreference) {
|
||||
|
||||
@@ -95,6 +95,11 @@ public class ProcessStatsUi extends ProcessStatsBase {
|
||||
return MetricsEvent.APPLICATIONS_PROCESS_STATS_UI;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getHelpResource() {
|
||||
return R.string.help_uri_process_stats_apps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* Copyright (C) 2017 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.applications;
|
||||
|
||||
import android.app.Application;
|
||||
import android.app.Fragment;
|
||||
import android.app.usage.UsageStats;
|
||||
import android.app.usage.UsageStatsManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.UserHandle;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceCategory;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.IconDrawableFactory;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settingslib.applications.ApplicationsState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent
|
||||
.SETTINGS_APP_NOTIF_CATEGORY;
|
||||
|
||||
/**
|
||||
* This controller displays a list of recently used apps and a "See all" button. If there is
|
||||
* no recently used app, "See all" will be displayed as "App info".
|
||||
*/
|
||||
public class RecentAppsPreferenceController extends PreferenceController
|
||||
implements Comparator<UsageStats> {
|
||||
|
||||
private static final String TAG = "RecentAppsCtrl";
|
||||
private static final String KEY_PREF_CATEGORY = "recent_apps_category";
|
||||
@VisibleForTesting
|
||||
static final String KEY_DIVIDER = "all_app_info_divider";
|
||||
@VisibleForTesting
|
||||
static final String KEY_SEE_ALL = "all_app_info";
|
||||
private static final int SHOW_RECENT_APP_COUNT = 5;
|
||||
private static final Set<String> SKIP_SYSTEM_PACKAGES = new ArraySet<>();
|
||||
|
||||
private final Fragment mHost;
|
||||
private final PackageManager mPm;
|
||||
private final UsageStatsManager mUsageStatsManager;
|
||||
private final ApplicationsState mApplicationsState;
|
||||
private final int mUserId;
|
||||
private final IconDrawableFactory mIconDrawableFactory;
|
||||
|
||||
private Calendar mCal;
|
||||
private List<UsageStats> mStats;
|
||||
|
||||
private PreferenceCategory mCategory;
|
||||
private Preference mSeeAllPref;
|
||||
private Preference mDivider;
|
||||
private boolean mHasRecentApps;
|
||||
|
||||
static {
|
||||
SKIP_SYSTEM_PACKAGES.addAll(Arrays.asList(
|
||||
"android",
|
||||
"com.android.phone",
|
||||
"com.android.settings",
|
||||
"com.android.systemui",
|
||||
"com.android.providers.calendar",
|
||||
"com.android.providers.media"
|
||||
));
|
||||
}
|
||||
|
||||
public RecentAppsPreferenceController(Context context, Application app, Fragment host) {
|
||||
this(context, app == null ? null : ApplicationsState.getInstance(app), host);
|
||||
}
|
||||
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.NONE)
|
||||
RecentAppsPreferenceController(Context context, ApplicationsState appState, Fragment host) {
|
||||
super(context);
|
||||
mIconDrawableFactory = IconDrawableFactory.newInstance(context);
|
||||
mUserId = UserHandle.myUserId();
|
||||
mPm = context.getPackageManager();
|
||||
mHost = host;
|
||||
mUsageStatsManager =
|
||||
(UsageStatsManager) context.getSystemService(Context.USAGE_STATS_SERVICE);
|
||||
mApplicationsState = appState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPreferenceKey() {
|
||||
return KEY_PREF_CATEGORY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNonIndexableKeys(List<String> keys) {
|
||||
super.updateNonIndexableKeys(keys);
|
||||
// Don't index category name into search. It's not actionable.
|
||||
keys.add(KEY_PREF_CATEGORY);
|
||||
keys.add(KEY_DIVIDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayPreference(PreferenceScreen screen) {
|
||||
mCategory = (PreferenceCategory) screen.findPreference(getPreferenceKey());
|
||||
mSeeAllPref = screen.findPreference(KEY_SEE_ALL);
|
||||
mDivider = screen.findPreference(KEY_DIVIDER);
|
||||
super.displayPreference(screen);
|
||||
refreshUi(mCategory.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateState(Preference preference) {
|
||||
super.updateState(preference);
|
||||
refreshUi(mCategory.getContext());
|
||||
// Show total number of installed apps as See all's summary.
|
||||
new InstalledAppCounter(mContext, InstalledAppCounter.IGNORE_INSTALL_REASON,
|
||||
new PackageManagerWrapperImpl(mContext.getPackageManager())) {
|
||||
@Override
|
||||
protected void onCountComplete(int num) {
|
||||
if (mHasRecentApps) {
|
||||
mSeeAllPref.setTitle(mContext.getString(R.string.see_all_apps_title, num));
|
||||
} else {
|
||||
mSeeAllPref.setSummary(mContext.getString(R.string.apps_summary, num));
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final int compare(UsageStats a, UsageStats b) {
|
||||
// return by descending order
|
||||
return Long.compare(b.getLastTimeUsed(), a.getLastTimeUsed());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void refreshUi(Context prefContext) {
|
||||
reloadData();
|
||||
final List<UsageStats> recentApps = getDisplayableRecentAppList();
|
||||
if (recentApps != null && !recentApps.isEmpty()) {
|
||||
mHasRecentApps = true;
|
||||
displayRecentApps(prefContext, recentApps);
|
||||
} else {
|
||||
mHasRecentApps = false;
|
||||
displayOnlyAppInfo();
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void reloadData() {
|
||||
mCal = Calendar.getInstance();
|
||||
mCal.add(Calendar.DAY_OF_YEAR, -1);
|
||||
mStats = mUsageStatsManager.queryUsageStats(
|
||||
UsageStatsManager.INTERVAL_BEST, mCal.getTimeInMillis(),
|
||||
System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private void displayOnlyAppInfo() {
|
||||
mCategory.setTitle(null);
|
||||
mDivider.setVisible(false);
|
||||
mSeeAllPref.setTitle(R.string.applications_settings);
|
||||
mSeeAllPref.setIcon(null);
|
||||
int prefCount = mCategory.getPreferenceCount();
|
||||
for (int i = prefCount - 1; i >= 0; i--) {
|
||||
final Preference pref = mCategory.getPreference(i);
|
||||
if (!TextUtils.equals(pref.getKey(), KEY_SEE_ALL)) {
|
||||
mCategory.removePreference(pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void displayRecentApps(Context prefContext, List<UsageStats> recentApps) {
|
||||
mCategory.setTitle(R.string.recent_app_category_title);
|
||||
mDivider.setVisible(true);
|
||||
mSeeAllPref.setSummary(null);
|
||||
mSeeAllPref.setIcon(R.drawable.ic_chevron_right_24dp);
|
||||
|
||||
// Rebind prefs/avoid adding new prefs if possible. Adding/removing prefs causes jank.
|
||||
// Build a cached preference pool
|
||||
final Map<String, Preference> appPreferences = new ArrayMap<>();
|
||||
int prefCount = mCategory.getPreferenceCount();
|
||||
for (int i = 0; i < prefCount; i++) {
|
||||
final Preference pref = mCategory.getPreference(i);
|
||||
final String key = pref.getKey();
|
||||
if (!TextUtils.equals(key, KEY_SEE_ALL)) {
|
||||
appPreferences.put(key, pref);
|
||||
}
|
||||
}
|
||||
final int recentAppsCount = recentApps.size();
|
||||
for (int i = 0; i < recentAppsCount; i++) {
|
||||
final UsageStats stat = recentApps.get(i);
|
||||
// Bind recent apps to existing prefs if possible, or create a new pref.
|
||||
final String pkgName = stat.getPackageName();
|
||||
final ApplicationsState.AppEntry appEntry =
|
||||
mApplicationsState.getEntry(pkgName, mUserId);
|
||||
if (appEntry == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean rebindPref = true;
|
||||
Preference pref = appPreferences.remove(pkgName);
|
||||
if (pref == null) {
|
||||
pref = new Preference(prefContext);
|
||||
rebindPref = false;
|
||||
}
|
||||
pref.setKey(pkgName);
|
||||
pref.setTitle(appEntry.label);
|
||||
pref.setIcon(mIconDrawableFactory.getBadgedIcon(appEntry.info));
|
||||
pref.setSummary(TextUtils.expandTemplate(
|
||||
mContext.getResources().getText(R.string.recent_app_summary),
|
||||
Utils.formatElapsedTime(mContext,
|
||||
System.currentTimeMillis() - stat.getLastTimeUsed(), false)));
|
||||
pref.setOrder(i);
|
||||
pref.setOnPreferenceClickListener(preference -> {
|
||||
AppInfoBase.startAppInfoFragment(InstalledAppDetails.class,
|
||||
R.string.application_info_label, pkgName, appEntry.info.uid, mHost,
|
||||
1001 /*RequestCode*/, SETTINGS_APP_NOTIF_CATEGORY);
|
||||
return true;
|
||||
});
|
||||
if (!rebindPref) {
|
||||
mCategory.addPreference(pref);
|
||||
}
|
||||
}
|
||||
// Remove unused prefs from pref cache pool
|
||||
for (Preference unusedPrefs : appPreferences.values()) {
|
||||
mCategory.removePreference(unusedPrefs);
|
||||
}
|
||||
}
|
||||
|
||||
private List<UsageStats> getDisplayableRecentAppList() {
|
||||
final List<UsageStats> recentApps = new ArrayList<>();
|
||||
final Map<String, UsageStats> map = new ArrayMap<>();
|
||||
final int statCount = mStats.size();
|
||||
for (int i = 0; i < statCount; i++) {
|
||||
final UsageStats pkgStats = mStats.get(i);
|
||||
if (!shouldIncludePkgInRecents(pkgStats)) {
|
||||
continue;
|
||||
}
|
||||
final String pkgName = pkgStats.getPackageName();
|
||||
final UsageStats existingStats = map.get(pkgName);
|
||||
if (existingStats == null) {
|
||||
map.put(pkgName, pkgStats);
|
||||
} else {
|
||||
existingStats.add(pkgStats);
|
||||
}
|
||||
}
|
||||
final List<UsageStats> packageStats = new ArrayList<>();
|
||||
packageStats.addAll(map.values());
|
||||
Collections.sort(packageStats, this /* comparator */);
|
||||
int count = 0;
|
||||
for (UsageStats stat : packageStats) {
|
||||
final ApplicationsState.AppEntry appEntry = mApplicationsState.getEntry(
|
||||
stat.getPackageName(), mUserId);
|
||||
if (appEntry == null) {
|
||||
continue;
|
||||
}
|
||||
recentApps.add(stat);
|
||||
count++;
|
||||
if (count >= SHOW_RECENT_APP_COUNT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return recentApps;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not the app should be included in recent list.
|
||||
*/
|
||||
private boolean shouldIncludePkgInRecents(UsageStats stat) {
|
||||
final String pkgName = stat.getPackageName();
|
||||
if (stat.getLastTimeUsed() < mCal.getTimeInMillis()) {
|
||||
Log.d(TAG, "Invalid timestamp, skipping " + pkgName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SKIP_SYSTEM_PACKAGES.contains(pkgName)) {
|
||||
Log.d(TAG, "System package, skipping " + pkgName);
|
||||
return false;
|
||||
}
|
||||
final Intent launchIntent = new Intent().addCategory(Intent.CATEGORY_LAUNCHER)
|
||||
.setPackage(pkgName);
|
||||
|
||||
if (mPm.resolveActivity(launchIntent, 0) == null) {
|
||||
// Not visible on launcher -> likely not a user visible app, skip
|
||||
Log.d(TAG, "Not a user visible app, skipping " + pkgName);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -22,10 +22,10 @@ import android.support.v7.preference.Preference;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnCreate;
|
||||
import com.android.settings.core.lifecycle.events.OnSaveInstanceState;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnCreate;
|
||||
import com.android.settingslib.core.lifecycle.events.OnSaveInstanceState;
|
||||
|
||||
public class ResetAppPrefPreferenceController extends PreferenceController
|
||||
implements LifecycleObserver, OnCreate, OnSaveInstanceState {
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.android.settings.applications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.support.v4.content.res.TypedArrayUtils;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceViewHolder;
|
||||
import android.util.AttributeSet;
|
||||
@@ -33,7 +34,9 @@ public class SpacePreference extends Preference {
|
||||
private int mHeight;
|
||||
|
||||
public SpacePreference(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, com.android.internal.R.attr.preferenceStyle);
|
||||
this(context, attrs, TypedArrayUtils.getAttr(context,
|
||||
android.support.v7.preference.R.attr.preferenceStyle,
|
||||
android.R.attr.preferenceStyle));
|
||||
}
|
||||
|
||||
public SpacePreference(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
|
||||
@@ -14,20 +14,54 @@
|
||||
|
||||
package com.android.settings.applications;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.content.Context;
|
||||
import android.provider.SearchIndexableResource;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
|
||||
public class SpecialAccessSettings extends SettingsPreferenceFragment {
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class SpecialAccessSettings extends DashboardFragment {
|
||||
|
||||
private static final String TAG = "SpecialAccessSettings";
|
||||
|
||||
@Override
|
||||
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
|
||||
addPreferencesFromResource(R.xml.special_access);
|
||||
protected String getLogTag() {
|
||||
return TAG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getPreferenceScreenResId() {
|
||||
return R.xml.special_access;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<PreferenceController> getPreferenceControllers(Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsEvent.SPECIAL_ACCESS;
|
||||
}
|
||||
|
||||
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
|
||||
new BaseSearchIndexProvider() {
|
||||
@Override
|
||||
public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
|
||||
boolean enabled) {
|
||||
final ArrayList<SearchIndexableResource> result = new ArrayList<>();
|
||||
|
||||
final SearchIndexableResource sir = new SearchIndexableResource(context);
|
||||
sir.xmlResId = R.xml.special_access;
|
||||
result.add(sir);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -20,8 +20,6 @@ import android.app.AppOpsManager;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
@@ -38,8 +36,6 @@ import com.android.settings.applications.AppStateWriteSettingsBridge.WriteSettin
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
import com.android.settingslib.applications.ApplicationsState.AppEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class WriteSettingsDetails extends AppInfoWithHeader implements OnPreferenceChangeListener,
|
||||
OnPreferenceClickListener {
|
||||
|
||||
@@ -182,47 +178,8 @@ public class WriteSettingsDetails extends AppInfoWithHeader implements OnPrefere
|
||||
}
|
||||
|
||||
public static CharSequence getSummary(Context context, WriteSettingsState writeSettingsState) {
|
||||
return context.getString(writeSettingsState.isPermissible() ? R.string.write_settings_on :
|
||||
R.string.write_settings_off);
|
||||
}
|
||||
|
||||
public static CharSequence getSummary(Context context, String pkg) {
|
||||
// first check if pkg is a system pkg
|
||||
boolean isSystem = false;
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
try {
|
||||
ApplicationInfo appInfo = packageManager.getApplicationInfo(pkg, 0);
|
||||
if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
|
||||
isSystem = true;
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
// pkg doesn't even exist?
|
||||
Log.w(LOG_TAG, "Package " + pkg + " not found", e);
|
||||
return context.getString(R.string.write_settings_off);
|
||||
}
|
||||
|
||||
AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context
|
||||
.APP_OPS_SERVICE);
|
||||
List<AppOpsManager.PackageOps> packageOps = appOpsManager.getPackagesForOps(
|
||||
APP_OPS_OP_CODE);
|
||||
if (packageOps == null) {
|
||||
return context.getString(R.string.write_settings_off);
|
||||
}
|
||||
|
||||
int uid = isSystem ? 0 : -1;
|
||||
for (AppOpsManager.PackageOps packageOp : packageOps) {
|
||||
if (pkg.equals(packageOp.getPackageName())) {
|
||||
uid = packageOp.getUid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (uid == -1) {
|
||||
return context.getString(R.string.write_settings_off);
|
||||
}
|
||||
|
||||
int mode = appOpsManager.noteOpNoThrow(AppOpsManager.OP_WRITE_SETTINGS, uid, pkg);
|
||||
return context.getString((mode == AppOpsManager.MODE_ALLOWED) ?
|
||||
R.string.write_settings_on : R.string.write_settings_off);
|
||||
return context.getString(writeSettingsState.isPermissible()
|
||||
? R.string.app_permission_summary_allowed
|
||||
: R.string.app_permission_summary_not_allowed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,10 +26,10 @@ import android.support.v7.preference.TwoStatePreference;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -28,10 +28,10 @@ import android.support.v7.preference.TwoStatePreference;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -26,10 +26,10 @@ import android.support.v7.preference.TwoStatePreference;
|
||||
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -27,10 +27,10 @@ import android.text.TextUtils;
|
||||
import com.android.internal.app.AssistUtils;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppInfo;
|
||||
import com.android.settings.applications.defaultapps.DefaultAppPreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settings.core.lifecycle.events.OnPause;
|
||||
import com.android.settings.core.lifecycle.events.OnResume;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
import com.android.settingslib.core.lifecycle.LifecycleObserver;
|
||||
import com.android.settingslib.core.lifecycle.events.OnPause;
|
||||
import com.android.settingslib.core.lifecycle.events.OnResume;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ import android.provider.SearchIndexableResource;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.core.lifecycle.Lifecycle;
|
||||
import com.android.settings.dashboard.DashboardFragment;
|
||||
import com.android.settings.gestures.AssistGesturePreferenceController;
|
||||
import com.android.settings.search.BaseSearchIndexProvider;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settingslib.core.lifecycle.Lifecycle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -72,7 +72,8 @@ public class ManageAssist extends DashboardFragment {
|
||||
Lifecycle lifecycle) {
|
||||
final List<PreferenceController> controllers = new ArrayList<>();
|
||||
controllers.add(new DefaultAssistPreferenceController(context));
|
||||
controllers.add(new AssistGesturePreferenceController(context, lifecycle, KEY_ASSIST));
|
||||
controllers.add(new AssistGesturePreferenceController(context, lifecycle, KEY_ASSIST,
|
||||
true /* assistOnly */));
|
||||
controllers.add(new AssistContextPreferenceController(context, lifecycle));
|
||||
controllers.add(new AssistScreenshotPreferenceController(context, lifecycle));
|
||||
controllers.add(new AssistFlashScreenPreferenceController(context, lifecycle));
|
||||
@@ -102,6 +103,5 @@ public class ManageAssist extends DashboardFragment {
|
||||
keys.add(KEY_ASSIST);
|
||||
return keys;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@@ -23,11 +23,11 @@ import android.app.DialogFragment;
|
||||
import android.app.Fragment;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnClickListener;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.android.internal.logging.nano.MetricsProto;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.applications.PackageManagerWrapper;
|
||||
import com.android.settings.applications.PackageManagerWrapperImpl;
|
||||
@@ -62,6 +62,16 @@ public abstract class DefaultAppPickerFragment extends RadioButtonPickerFragment
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRadioButtonConfirmed(String selectedKey) {
|
||||
mMetricsFeatureProvider.action(getContext(),
|
||||
MetricsEvent.ACTION_SETTINGS_UPDATE_DEFAULT_APP,
|
||||
selectedKey,
|
||||
Pair.create(MetricsEvent.FIELD_CONTEXT, getMetricsCategory()));
|
||||
|
||||
super.onRadioButtonConfirmed(selectedKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindPreferenceExtra(RadioButtonPreference pref,
|
||||
String key, CandidateInfo info, String defaultKey, String systemDefaultKey) {
|
||||
@@ -97,7 +107,7 @@ public abstract class DefaultAppPickerFragment extends RadioButtonPickerFragment
|
||||
|
||||
@Override
|
||||
public int getMetricsCategory() {
|
||||
return MetricsProto.MetricsEvent.DEFAULT_APP_PICKER_CONFIRMATION_DIALOG;
|
||||
return MetricsEvent.DEFAULT_APP_PICKER_CONFIRMATION_DIALOG;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,16 +18,20 @@ package com.android.settings.applications.defaultapps;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ComponentInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DefaultBrowserPreferenceController extends DefaultAppPreferenceController {
|
||||
|
||||
private static final String TAG = "BrowserPrefCtrl";
|
||||
|
||||
static final Intent BROWSE_PROBE = new Intent()
|
||||
.setAction(Intent.ACTION_VIEW)
|
||||
.addCategory(Intent.CATEGORY_BROWSABLE)
|
||||
@@ -60,9 +64,10 @@ public class DefaultBrowserPreferenceController extends DefaultAppPreferenceCont
|
||||
@Override
|
||||
protected DefaultAppInfo getDefaultAppInfo() {
|
||||
try {
|
||||
final String packageName = mPackageManager.getDefaultBrowserPackageNameAsUser(mUserId);
|
||||
Log.d(TAG, "Get default browser package: " + packageName);
|
||||
return new DefaultAppInfo(mPackageManager,
|
||||
mPackageManager.getPackageManager().getApplicationInfo(
|
||||
mPackageManager.getDefaultBrowserPackageNameAsUser(mUserId), 0));
|
||||
mPackageManager.getPackageManager().getApplicationInfo(packageName, 0));
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
@@ -90,7 +95,12 @@ public class DefaultBrowserPreferenceController extends DefaultAppPreferenceCont
|
||||
// Resolve that intent and check that the handleAllWebDataURI boolean is set
|
||||
final List<ResolveInfo> list = getCandidates();
|
||||
if (list != null && list.size() == 1) {
|
||||
return list.get(0).loadLabel(mPackageManager.getPackageManager()).toString();
|
||||
final ResolveInfo info = list.get(0);
|
||||
final String label = info.loadLabel(mPackageManager.getPackageManager()).toString();
|
||||
final ComponentInfo cn = info.getComponentInfo();
|
||||
final String packageName = cn == null ? null : cn.packageName;
|
||||
Log.d(TAG, "Getting label for the only browser app: " + packageName + label);
|
||||
return label;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import android.content.pm.ResolveInfo;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.android.settings.applications.PackageManagerWrapper;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -106,11 +108,10 @@ public class DefaultHomePreferenceController extends DefaultAppPreferenceControl
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isHomeDefault(String pkg, Context context) {
|
||||
ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
|
||||
PackageManager pm = context.getPackageManager();
|
||||
public static boolean isHomeDefault(String pkg, PackageManagerWrapper pm) {
|
||||
final ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
|
||||
ComponentName def = pm.getHomeActivities(homeActivities);
|
||||
|
||||
return def != null && def.getPackageName().equals(pkg);
|
||||
return def == null || def.getPackageName().equals(pkg);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user