diff --git a/src/com/android/settings/PreferenceAvailabilityProvider.java b/src/com/android/settings/PreferenceAvailabilityProvider.java new file mode 100644 index 00000000000..bb33aee9c41 --- /dev/null +++ b/src/com/android/settings/PreferenceAvailabilityProvider.java @@ -0,0 +1,30 @@ +/* + * 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; + +/** + * Interface for classes whose instances can provide the availability of the preference. + */ +public interface PreferenceAvailabilityProvider { + /** + * @return the availability of the preference. Please make sure the availability in managed + * profile is taken into account. + */ + boolean isAvailable(Context context); +} diff --git a/src/com/android/settings/applications/DefaultBrowserPreference.java b/src/com/android/settings/applications/DefaultBrowserPreference.java index 32f77ba8110..a9a4e2a5c2d 100644 --- a/src/com/android/settings/applications/DefaultBrowserPreference.java +++ b/src/com/android/settings/applications/DefaultBrowserPreference.java @@ -25,6 +25,7 @@ import android.os.UserHandle; import android.util.AttributeSet; import com.android.settings.AppListPreference; +import com.android.settings.PreferenceAvailabilityProvider; import java.util.ArrayList; import java.util.List; @@ -72,4 +73,11 @@ public class DefaultBrowserPreference extends AppListPreference { return result; } + + public static class AvailabilityProvider implements PreferenceAvailabilityProvider { + @Override + public boolean isAvailable(Context context) { + return true; + } + } } diff --git a/src/com/android/settings/applications/DefaultEmergencyPreference.java b/src/com/android/settings/applications/DefaultEmergencyPreference.java index 7c9b1245992..bb6e84d62ef 100644 --- a/src/com/android/settings/applications/DefaultEmergencyPreference.java +++ b/src/com/android/settings/applications/DefaultEmergencyPreference.java @@ -32,6 +32,7 @@ import android.util.ArraySet; import android.util.AttributeSet; import com.android.settings.AppListPreference; +import com.android.settings.PreferenceAvailabilityProvider; import com.android.settings.Utils; import java.util.List; @@ -51,10 +52,7 @@ public class DefaultEmergencyPreference extends AppListPreference { public DefaultEmergencyPreference(Context context, AttributeSet attrs) { super(context, attrs); mContentResolver = context.getContentResolver(); - - if (isAvailable(context)) { - load(); - } + load(); } @Override @@ -135,13 +133,7 @@ public class DefaultEmergencyPreference extends AppListPreference { return packages; } - public static boolean isAvailable(Context context) { - return isCapable(context) - && context.getPackageManager().resolveActivity(QUERY_INTENT, 0) != null - && !Utils.isManagedProfile(UserManager.get(context)) ; - } - - public static boolean isCapable(Context context) { + private static boolean isCapable(Context context) { return TelephonyManager.EMERGENCY_ASSISTANCE_ENABLED && context.getResources().getBoolean( com.android.internal.R.bool.config_voice_capable); @@ -151,4 +143,13 @@ public class DefaultEmergencyPreference extends AppListPreference { return info.applicationInfo != null && (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)); + } + } } diff --git a/src/com/android/settings/applications/DefaultHomePreference.java b/src/com/android/settings/applications/DefaultHomePreference.java index 7426ce69020..2837a975b09 100644 --- a/src/com/android/settings/applications/DefaultHomePreference.java +++ b/src/com/android/settings/applications/DefaultHomePreference.java @@ -26,8 +26,11 @@ 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; @@ -115,4 +118,10 @@ 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)); + } + } } diff --git a/src/com/android/settings/applications/DefaultNotificationAssistantPreference.java b/src/com/android/settings/applications/DefaultNotificationAssistantPreference.java index 186c442a401..ab3a0b27d70 100644 --- a/src/com/android/settings/applications/DefaultNotificationAssistantPreference.java +++ b/src/com/android/settings/applications/DefaultNotificationAssistantPreference.java @@ -34,6 +34,7 @@ import android.util.Slog; 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; @@ -111,7 +112,10 @@ public class DefaultNotificationAssistantPreference extends AppListPreference { return c; } - public static boolean isAvailable(Context context) { - return !Utils.isManagedProfile(UserManager.get(context)); + public static class AvailabilityProvider implements PreferenceAvailabilityProvider { + @Override + public boolean isAvailable(Context context) { + return !Utils.isManagedProfile(UserManager.get(context)); + } } } diff --git a/src/com/android/settings/applications/DefaultPhonePreference.java b/src/com/android/settings/applications/DefaultPhonePreference.java index 3d9131eb395..7ab6325a84c 100644 --- a/src/com/android/settings/applications/DefaultPhonePreference.java +++ b/src/com/android/settings/applications/DefaultPhonePreference.java @@ -25,6 +25,8 @@ import android.text.TextUtils; import android.util.AttributeSet; import com.android.settings.AppListPreference; +import com.android.settings.PreferenceAvailabilityProvider; +import com.android.settings.Utils; import java.util.List; import java.util.Objects; @@ -36,9 +38,7 @@ public class DefaultPhonePreference extends AppListPreference { super(context, attrs); mContext = context.getApplicationContext(); - if (isAvailable(context)) { - loadDialerApps(); - } + loadDialerApps(); } @Override @@ -65,15 +65,19 @@ public class DefaultPhonePreference extends AppListPreference { return DefaultDialerManager.getDefaultDialerApplication(getContext()); } - public static boolean isAvailable(Context context) { - final TelephonyManager tm = - (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - if (!tm.isVoiceCapable()) { - return false; - } + public static class AvailabilityProvider implements PreferenceAvailabilityProvider { + @Override + public boolean isAvailable(Context context) { - final UserManager um = - (UserManager) context.getSystemService(Context.USER_SERVICE); - return !um.hasUserRestriction(UserManager.DISALLOW_OUTGOING_CALLS); + 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); + } } } diff --git a/src/com/android/settings/applications/DefaultSmsPreference.java b/src/com/android/settings/applications/DefaultSmsPreference.java index 72813943677..73404bbc905 100644 --- a/src/com/android/settings/applications/DefaultSmsPreference.java +++ b/src/com/android/settings/applications/DefaultSmsPreference.java @@ -17,6 +17,7 @@ package com.android.settings.applications; import android.content.ComponentName; import android.content.Context; +import android.os.UserHandle; import android.os.UserManager; import android.telephony.TelephonyManager; import android.text.TextUtils; @@ -25,6 +26,7 @@ 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 java.util.Collection; @@ -68,10 +70,18 @@ public class DefaultSmsPreference extends AppListPreference { return true; } - public static boolean isAvailable(Context context) { - TelephonyManager tm = - (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - return tm.isSmsCapable() && !Utils.isManagedProfile(UserManager.get(context)); + 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)); + } } } diff --git a/src/com/android/settings/applications/ManageAssist.java b/src/com/android/settings/applications/ManageAssist.java index fca124fdf88..5a17a315744 100644 --- a/src/com/android/settings/applications/ManageAssist.java +++ b/src/com/android/settings/applications/ManageAssist.java @@ -28,6 +28,7 @@ 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; @@ -179,7 +180,10 @@ public class ManageAssist extends SettingsPreferenceFragment updateUi(); } - public static boolean isAvailable(Context context) { - return !Utils.isManagedProfile(UserManager.get(context)); + public static class AvailabilityProvider implements PreferenceAvailabilityProvider { + @Override + public boolean isAvailable(Context context) { + return !Utils.isManagedProfile(UserManager.get(context)); + } } } diff --git a/src/com/android/settings/applications/ManageDefaultApps.java b/src/com/android/settings/applications/ManageDefaultApps.java index b421c9d0523..327c98b1d19 100644 --- a/src/com/android/settings/applications/ManageDefaultApps.java +++ b/src/com/android/settings/applications/ManageDefaultApps.java @@ -24,15 +24,17 @@ import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.os.UserHandle; -import android.os.UserManager; 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; @@ -48,18 +50,23 @@ public class ManageDefaultApps extends ProfileSettingsPreferenceFragment 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(); @@ -140,6 +147,7 @@ public class ManageDefaultApps extends ProfileSettingsPreferenceFragment new Preference.OnPreferenceChangeListener() { @Override public boolean onPreferenceChange(Preference preference, Object newValue) { + if (newValue == null) { return false; } @@ -157,35 +165,65 @@ public class ManageDefaultApps extends ProfileSettingsPreferenceFragment return result; } }); - final boolean isRestrictedUser = UserManager.get(getActivity()) - .getUserInfo(myUserId).isRestricted(); - // Restricted users cannot currently read/write SMS. - // Remove SMS Application if the device does not support SMS - if (isRestrictedUser || !DefaultSmsPreference.isAvailable(getActivity())) { - removePreference(KEY_SMS_APPLICATION); - } + updatePreferenceVisibility(); + // Update the index. + Index.getInstance(getActivity()).updateFromClassNameResource( + ManageDefaultApps.class.getName(), true, true); + } - if (!DefaultPhonePreference.isAvailable(getActivity())) { - removePreference(KEY_DEFAULT_PHONE_APP); + /** + * Iterate all preferences and hide it if it is unavailable. + */ + private void updatePreferenceVisibility() { + PreferenceScreen preferenceScreen = getPreferenceScreen(); + int count = preferenceScreen.getPreferenceCount(); + List 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); + } + } + } - if (!DefaultEmergencyPreference.isAvailable(getActivity())) { - removePreference(KEY_DEFAULT_EMERGENCY_APP); - } + /** + * 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); + } - if (!ManageAssist.isAvailable(getActivity())) { - removePreference(KEY_ASSIST_AND_VOICE_INPUT); - } - - if (!DefaultNotificationAssistantPreference.isAvailable(getActivity())) { - removePreference(KEY_DEFAULT_NOTIFICATION_ASST); - } - - if (DefaultEmergencyPreference.isCapable(getActivity())) { - Index.getInstance(getActivity()).updateFromClassNameResource( - ManageDefaultApps.class.getName(), true, true); + 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 @@ -224,19 +262,14 @@ public class ManageDefaultApps extends ProfileSettingsPreferenceFragment @Override public List getNonIndexableKeys(Context context) { - final ArrayList result = new ArrayList(); - - // Remove SMS Application if the device does not support SMS - final boolean isRestrictedUser = UserManager.get(context) - .getUserInfo(UserHandle.myUserId()).isRestricted(); - if (!DefaultSmsPreference.isAvailable(context) || isRestrictedUser) { - result.add(KEY_SMS_APPLICATION); + // Iterate all preferences to see which is not available. + final ArrayList result = new ArrayList<>(); + for (String key : PREFERENCE_KEYS) { + boolean isAvailable = getPreferenceAvailability(context, key); + if (!isAvailable) { + result.add(key); + } } - - if (!DefaultEmergencyPreference.isAvailable(context)) { - result.add(KEY_DEFAULT_EMERGENCY_APP); - } - return result; } };