Rearrange configure/default apps

Bug: 27276982
Bug: 27279305
Change-Id: I443e9d2bc0c3fd9bcc13ee86716c14fbb55af0ba
This commit is contained in:
Jason Monk
2016-02-23 15:31:09 -05:00
parent e57f7cbc8c
commit 91e2f89b0f
26 changed files with 483 additions and 503 deletions

View File

@@ -2768,7 +2768,7 @@
</intent-filter>
</activity>
<activity android:name="Settings$ManageDefaultAppsActivity"
<activity android:name="Settings$AdvancedAppsActivity"
android:taskAffinity=""
android:exported="true">
<intent-filter android:priority="1">
@@ -2780,7 +2780,7 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.applications.ManageDefaultApps" />
android:value="com.android.settings.applications.AdvancedAppSettings" />
</activity>
<service

View File

@@ -126,4 +126,8 @@
<!-- Confirm device credentials screen -->
<attr name="confirmDeviceCredentialsSideMargin" format="dimension" />
<attr name="confirmDeviceCredentialsTopMargin" format="dimension" />
<declare-styleable name="WorkPreference">
<attr name="forWork" format="boolean" />
</declare-styleable>
</resources>

View File

@@ -6511,7 +6511,10 @@
<string name="fingerprint_not_recognized">Not recognized</string>
<!-- Title for Default Apps settings [CHAR LIMIT=30] -->
<string name="default_apps_title">Default Apps</string>
<string name="default_apps_title">Default</string>
<!-- Title for Default Apps settings for work [CHAR LIMIT=30] -->
<string name="default_for_work">Default for work</string>
<!-- Title for Assist and voice input settings [CHAR LIMIT=30] -->
<string name="assist_and_voice_input_title">Assist &amp; voice input</string>
@@ -7246,4 +7249,8 @@
<string name="notification_log_details_default">default</string>
<!-- Notification log debug tool: the word 'none' -->
<string name="notification_log_details_none">none</string>
<!-- [CHAR_LIMIT=60] Label for special access screen -->
<string name="special_access">Special access</string>
</resources>

View File

@@ -24,52 +24,80 @@
android:title="@string/app_permissions"
settings:keywords="@string/keywords_app_permissions" />
<PreferenceScreen
<PreferenceCategory
android:title="@string/default_apps_title">
<PreferenceScreen
android:key="domain_urls"
android:title="@string/domain_urls_title"
android:fragment="com.android.settings.applications.ManageApplications">
<extra
<extra
android:name="classname"
android:value="com.android.settings.Settings$DomainsURLsAppListActivity" />
</PreferenceScreen>
</PreferenceScreen>
<Preference
android:key="assist_and_voice_input"
android:fragment="com.android.settings.applications.ManageAssist"
android:title="@string/assist_and_voice_input_title" />
<com.android.settings.applications.DefaultHomePreference
android:key="default_home"
android:title="@string/home_app"
android:summary="@string/no_default_home" />
<com.android.settings.applications.DefaultBrowserPreference
android:key="default_browser"
android:title="@string/default_browser_title"
android:summary="@string/default_browser_title_none" />
<com.android.settings.applications.DefaultPhonePreference
android:key="default_phone_app"
android:title="@string/default_phone_title"
settings:keywords="@string/keywords_default_phone_app" />
<com.android.settings.applications.DefaultEmergencyPreference
android:key="default_emergency_app"
android:title="@string/default_emergency_app"
settings:keywords="@string/keywords_emergency_app" />
<com.android.settings.applications.DefaultSmsPreference
android:key="default_sms_app"
android:title="@string/sms_application_title"
settings:keywords="@string/keywords_more_default_sms_app" />
<com.android.settings.applications.DefaultNotificationAssistantPreference
android:key="default_notification_asst_app"
android:title="@string/default_notification_assistant" />
</PreferenceCategory>
<com.android.settings.WorkOnlyCategory
android:key="work_defaults"
android:title="@string/default_for_work">
<com.android.settings.applications.DefaultBrowserPreference
android:key="work_default_browser"
android:title="@string/default_browser_title"
android:summary="@string/default_browser_title_none"
settings:forWork="true" />
<com.android.settings.applications.DefaultPhonePreference
android:key="work_default_phone_app"
android:title="@string/default_phone_title"
settings:keywords="@string/keywords_default_phone_app"
settings:forWork="true" />
</com.android.settings.WorkOnlyCategory>
<PreferenceCategory
android:title="@string/advanced_apps" />
android:title="@string/advanced_apps">
<PreferenceScreen
android:key="default_apps"
android:fragment="com.android.settings.applications.ManageDefaultApps"
android:title="@string/default_apps_title"
settings:keywords="@string/keywords_default_apps" />
<PreferenceScreen
android:key="system_alert_window"
android:title="@string/system_alert_window_settings"
android:fragment="com.android.settings.applications.ManageApplications"
settings:keywords="@string/keywords_system_alert_window">
<extra
android:name="classname"
android:value="com.android.settings.Settings$OverlaySettingsActivity" />
</PreferenceScreen>
<PreferenceScreen
android:key="write_settings_apps"
android:title="@string/write_settings"
android:fragment="com.android.settings.applications.ManageApplications"
settings:keywords="@string/keywords_write_settings">
<extra
android:name="classname"
android:value="com.android.settings.Settings$WriteSettingsActivity" />
</PreferenceScreen>
<PreferenceScreen
android:key="high_power_apps"
android:title="@string/high_power_apps"
android:fragment="com.android.settings.applications.ManageApplications"
settings:keywords="@string/keywords_ignore_optimizations">
<extra
android:name="classname"
android:value="com.android.settings.Settings$HighPowerApplicationsActivity" />
</PreferenceScreen>
<PreferenceScreen
android:key="special_access"
android:fragment="com.android.settings.applications.SpecialAccessSettings"
android:title="@string/special_access" />
</PreferenceCategory>
</PreferenceScreen>

View File

@@ -1,62 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:key="default_apps">
<Preference
android:key="assist_and_voice_input"
android:fragment="com.android.settings.applications.ManageAssist"
android:title="@string/assist_and_voice_input_title"
/>
<com.android.settings.applications.DefaultHomePreference
android:key="default_home"
android:title="@string/home_app"
android:summary="@string/no_default_home"
/>
<com.android.settings.applications.DefaultBrowserPreference
android:key="default_browser"
android:title="@string/default_browser_title"
android:summary="@string/default_browser_title_none"
/>
<com.android.settings.applications.DefaultPhonePreference
android:key="default_phone_app"
android:title="@string/default_phone_title"
settings:keywords="@string/keywords_default_phone_app"
/>
<com.android.settings.applications.DefaultEmergencyPreference
android:key="default_emergency_app"
android:title="@string/default_emergency_app"
settings:keywords="@string/keywords_emergency_app"
/>
<com.android.settings.applications.DefaultSmsPreference
android:key="default_sms_app"
android:title="@string/sms_application_title"
settings:keywords="@string/keywords_more_default_sms_app"
/>
<com.android.settings.applications.DefaultNotificationAssistantPreference
android:key="default_notification_asst_app"
android:title="@string/default_notification_assistant" />
</PreferenceScreen>

View File

@@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings">
<PreferenceScreen
android:key="high_power_apps"
android:title="@string/high_power_apps"
android:fragment="com.android.settings.applications.ManageApplications"
settings:keywords="@string/keywords_ignore_optimizations">
<extra
android:name="classname"
android:value="com.android.settings.Settings$HighPowerApplicationsActivity" />
</PreferenceScreen>
<PreferenceScreen
android:key="device_administrators"
android:title="@string/manage_device_admin"
android:fragment="com.android.settings.DeviceAdminSettings" />
<PreferenceScreen
android:key="zen_access"
android:title="@string/manage_zen_access_title"
android:fragment="com.android.settings.notification.ZenAccessSettings" />
<PreferenceScreen
android:key="system_alert_window"
android:title="@string/system_alert_window_settings"
android:fragment="com.android.settings.applications.ManageApplications"
settings:keywords="@string/keywords_system_alert_window">
<extra
android:name="classname"
android:value="com.android.settings.Settings$OverlaySettingsActivity" />
</PreferenceScreen>
<PreferenceScreen
android:key="write_settings_apps"
android:title="@string/write_settings"
android:fragment="com.android.settings.applications.ManageApplications"
settings:keywords="@string/keywords_write_settings">
<extra
android:name="classname"
android:value="com.android.settings.Settings$WriteSettingsActivity" />
</PreferenceScreen>
<PreferenceScreen
android:key="notification_access"
android:title="@string/manage_notification_access_title"
android:fragment="com.android.settings.notification.NotificationAccessSettings" />
<PreferenceScreen
android:key="data_saver"
android:title="@string/unrestricted_data_saver"
android:fragment="com.android.settings.datausage.UnrestrictedDataAccess" />
<PreferenceScreen
android:key="usage_access"
android:title="@string/usage_access"
android:fragment="com.android.settings.applications.ManageApplications"
settings:keywords="@string/keywords_write_settings">
<extra
android:name="classname"
android:value="com.android.settings.Settings$UsageAccessSettingsActivity" />
</PreferenceScreen>
</PreferenceScreen>

View File

@@ -23,9 +23,12 @@ import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
@@ -47,6 +50,9 @@ public class AppListPreference extends CustomListPreference {
public static final String ITEM_NONE_VALUE = "";
protected final boolean mForWork;
protected final int mUserId;
private Drawable[] mEntryDrawables;
private boolean mShowItemNone = false;
private CharSequence[] mSummaries;
@@ -91,13 +97,24 @@ public class AppListPreference extends CustomListPreference {
}
}
public AppListPreference(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
public AppListPreference(Context context, AttributeSet attrs, int defStyle, int defAttrs) {
super(context, attrs, defStyle, defAttrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WorkPreference, 0, 0);
mForWork = a.getBoolean(R.styleable.WorkPreference_forWork, false);
final UserHandle managedProfile = Utils.getManagedProfile(UserManager.get(context));
mUserId = mForWork && managedProfile != null ? managedProfile.getIdentifier()
: UserHandle.myUserId();
}
public AppListPreference(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.WorkPreference, 0, 0);
mForWork = a.getBoolean(R.styleable.WorkPreference_forWork, false);
final UserHandle managedProfile = Utils.getManagedProfile(UserManager.get(context));
mUserId = mForWork && managedProfile != null ? managedProfile.getIdentifier()
: UserHandle.myUserId();
}
public void setShowItemNone(boolean showItemNone) {
@@ -114,7 +131,8 @@ public class AppListPreference extends CustomListPreference {
int selectedIndex = -1;
for (int i = 0; i < packageNames.length; i++) {
try {
ApplicationInfo appInfo = pm.getApplicationInfo(packageNames[i].toString(), 0);
ApplicationInfo appInfo = pm.getApplicationInfoAsUser(packageNames[i].toString(), 0,
mUserId);
applicationNames.add(appInfo.loadLabel(pm));
validatedPackageNames.add(appInfo.packageName);
entryDrawables.add(appInfo.loadIcon(pm));
@@ -162,8 +180,8 @@ public class AppListPreference extends CustomListPreference {
int selectedIndex = -1;
for (int i = 0; i < componentNames.length; i++) {
try {
ApplicationInfo appInfo = pm.getApplicationInfo(
componentNames[i].getPackageName().toString(), 0);
ApplicationInfo appInfo = pm.getApplicationInfoAsUser(
componentNames[i].getPackageName().toString(), 0, mUserId);
applicationNames.add(appInfo.loadLabel(pm));
validatedComponentNames.add(componentNames[i].flattenToString());
entryDrawables.add(appInfo.loadIcon(pm));

View File

@@ -47,6 +47,7 @@ public abstract class InstrumentedFragment extends PreferenceFragment {
// Used for generic logging of Settings Preference Persistence, should not be used
// outside SharedPreferencesLogger.
public static final int ACTION_GENERIC_PACKAGE = UNDECLARED + 16;
public static final int SPECIAL_ACCESS = UNDECLARED + 17;
/**
* Declare the view of this category.

View File

@@ -21,7 +21,7 @@ import android.content.Context;
/**
* Interface for classes whose instances can provide the availability of the preference.
*/
public interface PreferenceAvailabilityProvider {
public interface SelfAvailablePreference {
/**
* @return the availability of the preference. Please make sure the availability in managed
* profile is taken into account.

View File

@@ -124,7 +124,7 @@ public class Settings extends SettingsActivity {
public static class WriteSettingsActivity extends SettingsActivity { /* empty */ }
public static class AppDrawOverlaySettingsActivity extends SettingsActivity { /* empty */ }
public static class AppWriteSettingsActivity extends SettingsActivity { /* empty */ }
public static class ManageDefaultAppsActivity extends SettingsActivity { /* empty */ }
public static class AdvancedAppsActivity extends SettingsActivity { /* empty */ }
public static class WifiCallingSuggestionActivity extends SettingsActivity { /* empty */ }
public static class ZenModeAutomationSuggestionActivity extends SettingsActivity { /* empty */ }

View File

@@ -56,11 +56,11 @@ import com.android.settings.accessibility.AccessibilitySettingsForSetupWizard;
import com.android.settings.accessibility.CaptionPropertiesFragment;
import com.android.settings.accounts.AccountSettings;
import com.android.settings.accounts.AccountSyncSettings;
import com.android.settings.applications.AdvancedAppSettings;
import com.android.settings.applications.DrawOverlayDetails;
import com.android.settings.applications.InstalledAppDetails;
import com.android.settings.applications.ManageApplications;
import com.android.settings.applications.ManageAssist;
import com.android.settings.applications.ManageDefaultApps;
import com.android.settings.applications.ProcessStatsSummary;
import com.android.settings.applications.ProcessStatsUi;
import com.android.settings.applications.UsageAccessDetails;
@@ -315,7 +315,7 @@ public class SettingsActivity extends SettingsDrawerActivity
ProcessStatsSummary.class.getName(),
DrawOverlayDetails.class.getName(),
WriteSettingsDetails.class.getName(),
ManageDefaultApps.class.getName(),
AdvancedAppSettings.class.getName(),
WallpaperTypeSettings.class.getName(),
};

View File

@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.XmlRes;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceGroupAdapter;
@@ -132,6 +133,25 @@ public abstract class SettingsPreferenceFragment extends InstrumentedPreferenceF
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
}
@Override
public void addPreferencesFromResource(@XmlRes int preferencesResId) {
super.addPreferencesFromResource(preferencesResId);
checkAvailablePrefs(getPreferenceScreen());
}
private void checkAvailablePrefs(PreferenceGroup preferenceGroup) {
if (preferenceGroup == null) return;
for (int i = 0; i < preferenceGroup.getPreferenceCount(); i++) {
Preference pref = preferenceGroup.getPreference(i);
if (pref instanceof SelfAvailablePreference
&& !((SelfAvailablePreference) pref).isAvailable(getContext())) {
preferenceGroup.removePreference(pref);
} else if (pref instanceof PreferenceGroup) {
checkAvailablePrefs((PreferenceGroup) pref);
}
}
}
public FloatingActionButton getFloatingActionButton() {
return mFloatingActionButton;
}

View File

@@ -64,6 +64,8 @@ import android.provider.ContactsContract.RawContacts;
import android.service.persistentdata.PersistentDataBlockManager;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceManager;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.TelephonyManager;
import android.text.Spannable;
import android.text.SpannableString;
@@ -83,7 +85,6 @@ import android.view.animation.AnimationUtils;
import android.widget.ListView;
import android.widget.TabWidget;
import com.android.internal.util.UserIcons;
import com.android.settings.datausage.DataUsageList;
import java.io.IOException;
import java.io.InputStream;
@@ -1025,5 +1026,41 @@ public final class Utils extends com.android.settingslib.Utils {
.toString();
}
}
public static List<String> getNonIndexable(int xml, Context context) {
List<String> ret = new ArrayList<>();
PreferenceManager manager = new PreferenceManager(context);
PreferenceScreen screen = manager.inflateFromResource(context, xml, null);
checkPrefs(screen, ret);
return ret;
}
private static void checkPrefs(PreferenceGroup group, List<String> ret) {
if (group == null) return;
for (int i = 0; i < group.getPreferenceCount(); i++) {
Preference pref = group.getPreference(i);
if (pref instanceof SelfAvailablePreference
&& !((SelfAvailablePreference) pref).isAvailable(group.getContext())) {
ret.add(pref.getKey());
if (pref instanceof PreferenceGroup) {
addAll((PreferenceGroup) pref, ret);
}
} else if (pref instanceof PreferenceGroup) {
checkPrefs((PreferenceGroup) pref, ret);
}
}
}
private static void addAll(PreferenceGroup group, List<String> ret) {
if (group == null) return;
for (int i = 0; i < group.getPreferenceCount(); i++) {
Preference pref = group.getPreference(i);
ret.add(pref.getKey());
if (pref instanceof PreferenceGroup) {
addAll((PreferenceGroup) pref, ret);
}
}
}
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.android.settings;
import android.content.Context;
import android.os.UserManager;
import android.support.v7.preference.PreferenceCategory;
import android.util.AttributeSet;
/**
* A PreferenceCategory that is only visible when the device has a work profile.
*/
public class WorkOnlyCategory extends PreferenceCategory implements SelfAvailablePreference {
public WorkOnlyCategory(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean isAvailable(Context context) {
return Utils.getManagedProfile(UserManager.get(context)) != null;
}
}

View File

@@ -16,23 +16,29 @@
package com.android.settings.applications;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.support.v7.preference.Preference;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.applications.PermissionsSummaryHelper.PermissionsResultCallback;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settingslib.applications.ApplicationsState;
import com.android.settingslib.applications.ApplicationsState.AppEntry;
import com.android.settingslib.applications.ApplicationsState.Session;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class AdvancedAppSettings extends SettingsPreferenceFragment implements
ApplicationsState.Callbacks {
ApplicationsState.Callbacks, Indexable {
static final String TAG = "AdvancedAppSettings";
@@ -176,4 +182,20 @@ public class AdvancedAppSettings extends SettingsPreferenceFragment implements
}
}
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.advanced_apps;
return Arrays.asList(sir);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
return Utils.getNonIndexable(R.xml.advanced_apps, context);
}
};
}

View File

@@ -21,17 +21,25 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.UserHandle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import com.android.internal.content.PackageMonitor;
import com.android.settings.AppListPreference;
import com.android.settings.PreferenceAvailabilityProvider;
import com.android.settings.R;
import java.util.ArrayList;
import java.util.List;
public class DefaultBrowserPreference extends AppListPreference {
private static final String TAG = "DefaultBrowserPref";
private static final long DELAY_UPDATE_BROWSER_MILLIS = 500;
private final Handler mHandler = new Handler();
final private PackageManager mPm;
public DefaultBrowserPreference(Context context, AttributeSet attrs) {
@@ -41,12 +49,70 @@ public class DefaultBrowserPreference extends AppListPreference {
refreshBrowserApps();
}
@Override
public void onAttached() {
super.onAttached();
updateDefaultBrowserPreference();
mPackageMonitor.register(getContext(), getContext().getMainLooper(), false);
}
@Override
public void onDetached() {
mPackageMonitor.unregister();
super.onDetached();
}
@Override
protected boolean persistString(String newValue) {
if (newValue == null) {
return false;
}
final CharSequence packageName = (CharSequence) newValue;
if (TextUtils.isEmpty(packageName)) {
return false;
}
boolean result = mPm.setDefaultBrowserPackageNameAsUser(
packageName.toString(), mUserId);
if (result) {
setSummary("%s");
}
return result && super.persistString(newValue);
}
public void refreshBrowserApps() {
List<String> browsers = resolveBrowserApps();
setPackageNames(browsers.toArray(new String[browsers.size()]), null);
}
private void updateDefaultBrowserPreference() {
refreshBrowserApps();
final PackageManager pm = getContext().getPackageManager();
String packageName = pm.getDefaultBrowserPackageNameAsUser(mUserId);
if (!TextUtils.isEmpty(packageName)) {
// Check if the default Browser package is still there
Intent intent = new Intent();
intent.setPackage(packageName);
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse("http:"));
ResolveInfo info = mPm.resolveActivityAsUser(intent, 0, mUserId);
if (info != null) {
setValue(packageName);
setSummary("%s");
} else {
setSummary(R.string.default_browser_title_none);
}
} else {
setSummary(R.string.default_browser_title_none);
Log.d(TAG, "Cannot set empty default Browser value!");
}
}
private List<String> resolveBrowserApps() {
List<String> result = new ArrayList<>();
@@ -58,7 +124,7 @@ public class DefaultBrowserPreference extends AppListPreference {
// Resolve that intent and check that the handleAllWebDataURI boolean is set
List<ResolveInfo> list = mPm.queryIntentActivitiesAsUser(intent, PackageManager.MATCH_ALL,
UserHandle.myUserId());
mUserId);
final int count = list.size();
for (int i=0; i<count; i++) {
@@ -74,10 +140,36 @@ public class DefaultBrowserPreference extends AppListPreference {
return result;
}
public static class AvailabilityProvider implements PreferenceAvailabilityProvider {
private final Runnable mUpdateRunnable = new Runnable() {
@Override
public boolean isAvailable(Context context) {
return true;
public void run() {
updateDefaultBrowserPreference();
}
}
};
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override
public void onPackageAdded(String packageName, int uid) {
sendUpdate();
}
@Override
public void onPackageAppeared(String packageName, int reason) {
sendUpdate();
}
@Override
public void onPackageDisappeared(String packageName, int reason) {
sendUpdate();
}
@Override
public void onPackageRemoved(String packageName, int uid) {
sendUpdate();
}
private void sendUpdate() {
mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_BROWSER_MILLIS);
}
};
}

View File

@@ -24,16 +24,13 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.AsyncTask;
import android.os.UserManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.AttributeSet;
import com.android.settings.AppListPreference;
import com.android.settings.PreferenceAvailabilityProvider;
import com.android.settings.Utils;
import com.android.settings.SelfAvailablePreference;
import java.util.List;
import java.util.Objects;
@@ -42,7 +39,8 @@ import java.util.Set;
/**
* A preference for choosing the default emergency app
*/
public class DefaultEmergencyPreference extends AppListPreference {
public class DefaultEmergencyPreference extends AppListPreference
implements SelfAvailablePreference {
private final ContentResolver mContentResolver;
@@ -144,12 +142,8 @@ public class DefaultEmergencyPreference extends AppListPreference {
&& (info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
public static class AvailabilityProvider implements PreferenceAvailabilityProvider {
@Override
public boolean isAvailable(Context context) {
return isCapable(context)
&& context.getPackageManager().resolveActivity(QUERY_INTENT, 0) != null
&& !Utils.isManagedProfile(UserManager.get(context));
}
public boolean isAvailable(Context context) {
return isCapable(context)
&& context.getPackageManager().resolveActivity(QUERY_INTENT, 0) != null;
}
}

View File

@@ -26,11 +26,8 @@ import android.content.pm.UserInfo;
import android.os.Build;
import android.os.UserManager;
import android.util.AttributeSet;
import com.android.settings.AppListPreference;
import com.android.settings.PreferenceAvailabilityProvider;
import com.android.settings.R;
import com.android.settings.Utils;
import java.util.ArrayList;
import java.util.List;
@@ -117,11 +114,4 @@ public class DefaultHomePreference extends AppListPreference {
}
return false;
}
public static class AvailabilityProvider implements PreferenceAvailabilityProvider {
@Override
public boolean isAvailable(Context context) {
return !Utils.isManagedProfile(UserManager.get(context));
}
}
}

View File

@@ -16,8 +16,6 @@
package com.android.settings.applications;
import com.android.settings.AppListPreference;
import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
@@ -25,20 +23,17 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.UserManager;
import android.provider.Settings;
import android.service.notification.NotificationAssistantService;
import android.util.AttributeSet;
import android.util.Slog;
import com.android.settings.AppListPreference;
import com.android.settings.R;
import com.android.settings.notification.ManagedServiceSettings;
import java.util.ArrayList;
import java.util.List;
import com.android.settings.PreferenceAvailabilityProvider;
import com.android.settings.R;
import com.android.settings.Utils;
import com.android.settings.notification.ManagedServiceSettings;
public class DefaultNotificationAssistantPreference extends AppListPreference {
private static final String TAG = "DefaultNotiAssist";
@@ -111,11 +106,4 @@ public class DefaultNotificationAssistantPreference extends AppListPreference {
c.emptyText = R.string.no_notification_listeners;
return c;
}
public static class AvailabilityProvider implements PreferenceAvailabilityProvider {
@Override
public boolean isAvailable(Context context) {
return !Utils.isManagedProfile(UserManager.get(context));
}
}
}

View File

@@ -19,19 +19,16 @@ package com.android.settings.applications;
import android.content.Context;
import android.os.UserManager;
import android.telecom.DefaultDialerManager;
import android.telecom.TelecomManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.AttributeSet;
import com.android.settings.AppListPreference;
import com.android.settings.PreferenceAvailabilityProvider;
import com.android.settings.Utils;
import com.android.settings.SelfAvailablePreference;
import java.util.List;
import java.util.Objects;
public class DefaultPhonePreference extends AppListPreference {
public class DefaultPhonePreference extends AppListPreference implements SelfAvailablePreference {
private final Context mContext;
public DefaultPhonePreference(Context context, AttributeSet attrs) {
@@ -44,7 +41,7 @@ public class DefaultPhonePreference extends AppListPreference {
@Override
protected boolean persistString(String value) {
if (!TextUtils.isEmpty(value) && !Objects.equals(value, getDefaultPackage())) {
TelecomManager.from(mContext).setDefaultDialer(value);
DefaultDialerManager.setDefaultDialerApplication(getContext(), value, mUserId);
}
setSummary(getEntry());
return true;
@@ -52,7 +49,7 @@ public class DefaultPhonePreference extends AppListPreference {
private void loadDialerApps() {
List<String> dialerPackages =
DefaultDialerManager.getInstalledDialerApplications(getContext());
DefaultDialerManager.getInstalledDialerApplications(getContext(), mUserId);
final String[] dialers = new String[dialerPackages.size()];
for (int i = 0; i < dialerPackages.size(); i++) {
@@ -62,22 +59,19 @@ public class DefaultPhonePreference extends AppListPreference {
}
private String getDefaultPackage() {
return DefaultDialerManager.getDefaultDialerApplication(getContext());
return DefaultDialerManager.getDefaultDialerApplication(getContext(), mUserId);
}
public static class AvailabilityProvider implements PreferenceAvailabilityProvider {
@Override
public boolean isAvailable(Context context) {
final TelephonyManager tm =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (!tm.isVoiceCapable()) {
return false;
}
final UserManager um =
(UserManager) context.getSystemService(Context.USER_SERVICE);
return !um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS);
@Override
public boolean isAvailable(Context context) {
final TelephonyManager tm =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (!tm.isVoiceCapable()) {
return false;
}
final UserManager um =
(UserManager) context.getSystemService(Context.USER_SERVICE);
return !um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS);
}
}

View File

@@ -22,17 +22,15 @@ import android.os.UserManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.AttributeSet;
import com.android.internal.telephony.SmsApplication;
import com.android.internal.telephony.SmsApplication.SmsApplicationData;
import com.android.settings.AppListPreference;
import com.android.settings.PreferenceAvailabilityProvider;
import com.android.settings.Utils;
import com.android.settings.SelfAvailablePreference;
import java.util.Collection;
import java.util.Objects;
public class DefaultSmsPreference extends AppListPreference {
public class DefaultSmsPreference extends AppListPreference implements SelfAvailablePreference {
public DefaultSmsPreference(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -70,18 +68,13 @@ public class DefaultSmsPreference extends AppListPreference {
return true;
}
public static class AvailabilityProvider implements PreferenceAvailabilityProvider {
@Override
public boolean isAvailable(Context context) {
boolean isRestrictedUser =
UserManager.get(context)
.getUserInfo(UserHandle.myUserId()).isRestricted();
TelephonyManager tm =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return !isRestrictedUser
&& tm.isSmsCapable()
&& !Utils.isManagedProfile(UserManager.get(context));
}
@Override
public boolean isAvailable(Context context) {
boolean isRestrictedUser =
UserManager.get(context)
.getUserInfo(UserHandle.myUserId()).isRestricted();
TelephonyManager tm =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
return !isRestrictedUser && tm.isSmsCapable();
}
}

View File

@@ -18,20 +18,15 @@ package com.android.settings.applications;
import android.app.AlertDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserManager;
import android.provider.Settings;
import android.support.v14.preference.SwitchPreference;
import android.support.v7.preference.Preference;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.PreferenceAvailabilityProvider;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.Utils;
import com.android.settings.voice.VoiceInputListPreference;
/**
@@ -179,11 +174,4 @@ public class ManageAssist extends SettingsPreferenceFragment
mDefaultAssitPref.setValue(assistPackage);
updateUi();
}
public static class AvailabilityProvider implements PreferenceAvailabilityProvider {
@Override
public boolean isAvailable(Context context) {
return !Utils.isManagedProfile(UserManager.get(context));
}
}
}

View File

@@ -1,281 +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.applications;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.UserHandle;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.support.v4.util.ArrayMap;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceScreen;
import android.text.TextUtils;
import android.util.Log;
import com.android.internal.content.PackageMonitor;
import com.android.internal.logging.MetricsProto.MetricsEvent;
import com.android.settings.PreferenceAvailabilityProvider;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Index;
import com.android.settings.search.Indexable;
import com.android.settings.utils.ProfileSettingsPreferenceFragment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class ManageDefaultApps extends ProfileSettingsPreferenceFragment
implements Preference.OnPreferenceClickListener, Indexable {
private static final String TAG = ManageDefaultApps.class.getSimpleName();
private static final String KEY_DEFAULT_HOME = "default_home";
private static final String KEY_ASSIST_AND_VOICE_INPUT = "assist_and_voice_input";
private static final String KEY_DEFAULT_BROWSER = "default_browser";
private static final String KEY_DEFAULT_PHONE_APP = "default_phone_app";
private static final String KEY_DEFAULT_EMERGENCY_APP = "default_emergency_app";
private static final String KEY_SMS_APPLICATION = "default_sms_app";
private static final String KEY_DEFAULT_NOTIFICATION_ASST = "default_notification_asst_app";
private static final String[] PREFERENCE_KEYS = new String[] {
KEY_DEFAULT_HOME, KEY_ASSIST_AND_VOICE_INPUT, KEY_DEFAULT_BROWSER,
KEY_DEFAULT_PHONE_APP, KEY_DEFAULT_EMERGENCY_APP, KEY_SMS_APPLICATION,
KEY_DEFAULT_NOTIFICATION_ASST
};
private DefaultBrowserPreference mDefaultBrowserPreference;
private PackageManager mPm;
private int myUserId;
private static final long DELAY_UPDATE_BROWSER_MILLIS = 500;
private final Handler mHandler = new Handler();
private final Runnable mUpdateRunnable = new Runnable() {
@Override
public void run() {
updateDefaultBrowserPreference();
}
};
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
@Override
public void onPackageAdded(String packageName, int uid) {
sendUpdate();
}
@Override
public void onPackageAppeared(String packageName, int reason) {
sendUpdate();
}
@Override
public void onPackageDisappeared(String packageName, int reason) {
sendUpdate();
}
@Override
public void onPackageRemoved(String packageName, int uid) {
sendUpdate();
}
private void sendUpdate() {
mHandler.postDelayed(mUpdateRunnable, DELAY_UPDATE_BROWSER_MILLIS);
}
};
private void updateDefaultBrowserPreference() {
mDefaultBrowserPreference.refreshBrowserApps();
final PackageManager pm = getPackageManager();
String packageName = pm.getDefaultBrowserPackageNameAsUser(UserHandle.myUserId());
if (!TextUtils.isEmpty(packageName)) {
// Check if the default Browser package is still there
Intent intent = new Intent();
intent.setPackage(packageName);
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
intent.setData(Uri.parse("http:"));
ResolveInfo info = mPm.resolveActivityAsUser(intent, 0, myUserId);
if (info != null) {
mDefaultBrowserPreference.setValue(packageName);
CharSequence label = info.loadLabel(pm);
mDefaultBrowserPreference.setSummary(label);
} else {
mDefaultBrowserPreference.setSummary(R.string.default_browser_title_none);
}
} else {
mDefaultBrowserPreference.setSummary(R.string.default_browser_title_none);
Log.d(TAG, "Cannot set empty default Browser value!");
}
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.default_apps);
mPm = getPackageManager();
myUserId = UserHandle.myUserId();
mDefaultBrowserPreference = (DefaultBrowserPreference) findPreference(KEY_DEFAULT_BROWSER);
mDefaultBrowserPreference.setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (newValue == null) {
return false;
}
final CharSequence packageName = (CharSequence) newValue;
if (TextUtils.isEmpty(packageName)) {
return false;
}
boolean result = mPm.setDefaultBrowserPackageNameAsUser(
packageName.toString(), myUserId);
if (result) {
mDefaultBrowserPreference.setValue(packageName.toString());
final CharSequence appName = mDefaultBrowserPreference.getEntry();
mDefaultBrowserPreference.setSummary(appName);
}
return result;
}
});
updatePreferenceVisibility();
// Update the index.
Index.getInstance(getActivity()).updateFromClassNameResource(
ManageDefaultApps.class.getName(), true, true);
}
/**
* Iterate all preferences and hide it if it is unavailable.
*/
private void updatePreferenceVisibility() {
PreferenceScreen preferenceScreen = getPreferenceScreen();
int count = preferenceScreen.getPreferenceCount();
List<String> preferenceKeys = new ArrayList<>();
for (int i = 0; i < count; i++) {
String preferenceKey = preferenceScreen.getPreference(i).getKey();
if (!TextUtils.isEmpty(preferenceKey)) {
preferenceKeys.add(preferenceKey);
}
}
for (String preferenceKey : preferenceKeys) {
boolean isAvailable = getPreferenceAvailability(getContext(), preferenceKey);
if (!isAvailable) {
Preference preference = preferenceScreen.findPreference(preferenceKey);
preferenceScreen.removePreference(preference);
}
}
}
/**
* Get availability of preference from {@link PreferenceAvailabilityProvider}.
*/
private static boolean getPreferenceAvailability(Context context,
String preferenceKey) {
// Consider the preference is unavailable if no corresponding provider is found.
PreferenceAvailabilityProvider provider = getPreferenceAvailabilityProvider(preferenceKey);
return (provider == null) ? false : provider.isAvailable(context);
}
private static PreferenceAvailabilityProvider getPreferenceAvailabilityProvider(
String preferenceKey) {
switch (preferenceKey) {
case KEY_ASSIST_AND_VOICE_INPUT:
return new ManageAssist.AvailabilityProvider();
case KEY_DEFAULT_BROWSER:
return new DefaultBrowserPreference.AvailabilityProvider();
case KEY_DEFAULT_EMERGENCY_APP:
return new DefaultEmergencyPreference.AvailabilityProvider();
case KEY_DEFAULT_HOME:
return new DefaultHomePreference.AvailabilityProvider();
case KEY_DEFAULT_NOTIFICATION_ASST:
return new DefaultNotificationAssistantPreference.AvailabilityProvider();
case KEY_DEFAULT_PHONE_APP:
return new DefaultPhonePreference.AvailabilityProvider();
case KEY_SMS_APPLICATION:
return new DefaultSmsPreference.AvailabilityProvider();
}
Log.w(TAG, "getPreferenceAvailabilityProvider: Cannot find provider for " + preferenceKey);
return null;
}
@Override
public void onResume() {
super.onResume();
updateDefaultBrowserPreference();
mPackageMonitor.register(getActivity(), getActivity().getMainLooper(), false);
}
@Override
public void onPause() {
super.onPause();
mPackageMonitor.unregister();
}
@Override
protected int getMetricsCategory() {
return MetricsEvent.APPLICATIONS_DEFAULT_APPS;
}
@Override
public boolean onPreferenceClick(Preference preference) {
return false;
}
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@Override
public List<SearchIndexableResource> getXmlResourcesToIndex(
Context context, boolean enabled) {
SearchIndexableResource sir = new SearchIndexableResource(context);
sir.xmlResId = R.xml.default_apps;
return Arrays.asList(sir);
}
@Override
public List<String> getNonIndexableKeys(Context context) {
// Iterate all preferences to see which is not available.
final ArrayList<String> result = new ArrayList<>();
for (String key : PREFERENCE_KEYS) {
boolean isAvailable = getPreferenceAvailability(context, key);
if (!isAvailable) {
result.add(key);
}
}
return result;
}
};
protected String getIntentActionString() {
return Settings.ACTION_MANAGE_DEFAULT_APPS_SETTINGS;
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.android.settings.applications;
import android.os.Bundle;
import com.android.settings.InstrumentedFragment;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
public class SpecialAccessSettings extends SettingsPreferenceFragment {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.special_access);
}
@Override
protected int getMetricsCategory() {
return InstrumentedFragment.SPECIAL_ACCESS;
}
}

View File

@@ -32,7 +32,7 @@ import com.android.settings.WirelessSettings;
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accounts.AccountSettings;
import com.android.settings.applications.AdvancedAppSettings;
import com.android.settings.applications.ManageDefaultApps;
import com.android.settings.applications.SpecialAccessSettings;
import com.android.settings.bluetooth.BluetoothSettings;
import com.android.settings.datausage.DataUsageMeteredSettings;
import com.android.settings.datausage.DataUsageSummary;
@@ -148,7 +148,7 @@ public final class Ranking {
// Advanced app settings
sRankMap.put(AdvancedAppSettings.class.getName(), RANK_APPS);
sRankMap.put(ManageDefaultApps.class.getName(), RANK_APPS);
sRankMap.put(SpecialAccessSettings.class.getName(), RANK_APPS);
// Users
sRankMap.put(UserSettings.class.getName(), RANK_USERS);

View File

@@ -16,6 +16,7 @@
package com.android.settings.search;
import android.provider.SearchIndexableResource;
import com.android.settings.DateTimeSettings;
import com.android.settings.DevelopmentSettings;
import com.android.settings.DeviceInfoSettings;
@@ -32,7 +33,7 @@ import com.android.settings.WirelessSettings;
import com.android.settings.accessibility.AccessibilitySettings;
import com.android.settings.accounts.AccountSettings;
import com.android.settings.applications.AdvancedAppSettings;
import com.android.settings.applications.ManageDefaultApps;
import com.android.settings.applications.SpecialAccessSettings;
import com.android.settings.bluetooth.BluetoothSettings;
import com.android.settings.datausage.DataUsageMeteredSettings;
import com.android.settings.datausage.DataUsageSummary;
@@ -56,8 +57,6 @@ import com.android.settings.wifi.AdvancedWifiSettings;
import com.android.settings.wifi.SavedAccessPointsWifiSettings;
import com.android.settings.wifi.WifiSettings;
import android.provider.SearchIndexableResource;
import java.util.Collection;
import java.util.HashMap;
@@ -212,15 +211,15 @@ public final class SearchIndexableResources {
sResMap.put(AdvancedAppSettings.class.getName(),
new SearchIndexableResource(
Ranking.getRankForClassName(AdvancedAppSettings.class.getName()),
R.xml.advanced_apps,
NO_DATA_RES_ID,
AdvancedAppSettings.class.getName(),
R.drawable.ic_settings_applications));
sResMap.put(ManageDefaultApps.class.getName(),
sResMap.put(SpecialAccessSettings.class.getName(),
new SearchIndexableResource(
Ranking.getRankForClassName(ManageDefaultApps.class.getName()),
NO_DATA_RES_ID,
ManageDefaultApps.class.getName(),
Ranking.getRankForClassName(SpecialAccessSettings.class.getName()),
R.xml.special_access,
SpecialAccessSettings.class.getName(),
R.drawable.ic_settings_applications));
sResMap.put(UserSettings.class.getName(),