summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/android/settings/LinkifyUtils.java84
-rw-r--r--src/com/android/settings/Settings.java2
-rw-r--r--src/com/android/settings/SetupChooseLockGeneric.java8
-rw-r--r--src/com/android/settings/Utils.java41
-rw-r--r--src/com/android/settings/applications/AdvancedAppSettings.java44
-rw-r--r--src/com/android/settings/applications/AppDomainsPreference.java44
-rw-r--r--src/com/android/settings/applications/AppLaunchSettings.java185
-rw-r--r--src/com/android/settings/applications/AppOpsState.java8
-rw-r--r--src/com/android/settings/applications/AppViewHolder.java16
-rw-r--r--src/com/android/settings/applications/ApplicationsState.java28
-rw-r--r--src/com/android/settings/applications/ClearDefaultsPreference.java172
-rwxr-xr-xsrc/com/android/settings/applications/InstalledAppDetails.java13
-rw-r--r--src/com/android/settings/applications/ManageApplications.java106
-rwxr-xr-xsrc/com/android/settings/bluetooth/BluetoothSettings.java37
-rw-r--r--src/com/android/settings/notification/ZenModeAutomationSettings.java453
-rw-r--r--src/com/android/settings/notification/ZenModeSettings.java371
-rw-r--r--src/com/android/settings/notification/ZenModeSettingsBase.java6
-rw-r--r--src/com/android/settings/search/Ranking.java2
-rw-r--r--src/com/android/settings/search/SearchIndexableResources.java8
-rw-r--r--src/com/android/settings/users/AppRestrictionsFragment.java7
-rw-r--r--src/com/android/settings/users/RestrictionUtils.java14
-rw-r--r--src/com/android/settings/wifi/WifiSettings.java51
22 files changed, 1137 insertions, 563 deletions
diff --git a/src/com/android/settings/LinkifyUtils.java b/src/com/android/settings/LinkifyUtils.java
new file mode 100644
index 0000000..5550db5
--- /dev/null
+++ b/src/com/android/settings/LinkifyUtils.java
@@ -0,0 +1,84 @@
+/*
+ * 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.text.Spannable;
+import android.text.TextPaint;
+import android.text.method.LinkMovementMethod;
+import android.text.style.ClickableSpan;
+import android.view.View;
+import android.widget.TextView;
+import android.widget.TextView.BufferType;
+
+/**
+ * Utility class to create clickable links inside {@link TextView TextViews}.
+ */
+public class LinkifyUtils {
+ private static final String PLACE_HOLDER_LINK_BEGIN = "LINK_BEGIN";
+ private static final String PLACE_HOLDER_LINK_END = "LINK_END";
+
+ private LinkifyUtils() {
+ }
+
+ /** Interface that handles the click event of the link */
+ public interface OnClickListener {
+ void onClick();
+ }
+
+ /**
+ * Applies the text into the {@link TextView} and part of it a clickable link.
+ * The text surrounded with "LINK_BEGIN" and "LINK_END" will become a clickable link. Only
+ * supports at most one link.
+ * @return true if the link has been successfully applied, or false if the original text
+ * contains no link place holders.
+ */
+ public static boolean linkify(TextView textView, StringBuilder text,
+ final OnClickListener listener) {
+ // Remove place-holders from the string and record their positions
+ final int beginIndex = text.indexOf(PLACE_HOLDER_LINK_BEGIN);
+ if (beginIndex == -1) {
+ textView.setText(text);
+ return false;
+ }
+ text.delete(beginIndex, beginIndex + PLACE_HOLDER_LINK_BEGIN.length());
+ final int endIndex = text.indexOf(PLACE_HOLDER_LINK_END);
+ if (endIndex == -1) {
+ textView.setText(text);
+ return false;
+ }
+ text.delete(endIndex, endIndex + PLACE_HOLDER_LINK_END.length());
+
+ textView.setText(text.toString(), BufferType.SPANNABLE);
+ textView.setMovementMethod(LinkMovementMethod.getInstance());
+ Spannable spannableContent = (Spannable) textView.getText();
+ ClickableSpan spannableLink = new ClickableSpan() {
+ @Override
+ public void onClick(View widget) {
+ listener.onClick();
+ }
+
+ @Override
+ public void updateDrawState(TextPaint ds) {
+ super.updateDrawState(ds);
+ ds.setUnderlineText(false);
+ }
+ };
+ spannableContent.setSpan(spannableLink, beginIndex, endIndex,
+ Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ return true;
+ }
+}
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 4ed1026..70455a4 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -95,10 +95,12 @@ public class Settings extends SettingsActivity {
public static class PrintJobSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenModeSettingsActivity extends SettingsActivity { /* empty */ }
public static class ZenModePrioritySettingsActivity extends SettingsActivity { /* empty */ }
+ public static class ZenModeAutomationSettingsActivity extends SettingsActivity { /* empty */ }
public static class NotificationSettingsActivity extends SettingsActivity { /* empty */ }
public static class NotificationAppListActivity extends SettingsActivity { /* empty */ }
public static class AppNotificationSettingsActivity extends SettingsActivity { /* empty */ }
public static class OtherSoundSettingsActivity extends SettingsActivity { /* empty */ }
+ public static class DomainsURLsAppListActivity extends SettingsActivity { /* empty */ }
public static class TopLevelSettings extends SettingsActivity { /* empty */ }
public static class ApnSettingsActivity extends SettingsActivity { /* empty */ }
diff --git a/src/com/android/settings/SetupChooseLockGeneric.java b/src/com/android/settings/SetupChooseLockGeneric.java
index 10bac15..a631caf 100644
--- a/src/com/android/settings/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/SetupChooseLockGeneric.java
@@ -24,6 +24,7 @@ import android.content.Intent;
import android.content.res.Resources;
import android.os.Bundle;
import android.preference.PreferenceFragment;
+import android.hardware.fingerprint.FingerprintManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -82,6 +83,13 @@ public class SetupChooseLockGeneric extends ChooseLockGeneric
final View header = inflater.inflate(R.layout.setup_wizard_header, list, false);
list.addHeaderView(header, null, false);
}
+ final FingerprintManager fpm = (FingerprintManager)
+ getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
+ if (fpm != null && fpm.isHardwareDetected()) {
+ final View footer = inflater.inflate(
+ R.layout.setup_screen_lock_fingerprint_details, list, false);
+ list.addFooterView(footer, null, false);
+ }
return view;
}
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index bc6cbed..23b2c85 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -25,10 +25,12 @@ import android.app.AlertDialog;
import android.app.Dialog;
import android.app.Fragment;
import android.app.IActivityManager;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -43,6 +45,7 @@ import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
+import android.hardware.usb.IUsbManager;
import android.net.ConnectivityManager;
import android.net.LinkProperties;
import android.net.Uri;
@@ -76,6 +79,7 @@ import android.widget.TabWidget;
import com.android.internal.util.UserIcons;
import com.android.settings.UserAdapter.UserDetails;
+import com.android.settings.applications.ApplicationsState;
import com.android.settings.dashboard.DashboardTile;
import com.android.settings.drawable.CircleFramedDrawable;
@@ -84,6 +88,7 @@ import java.io.InputStream;
import java.net.InetAddress;
import java.text.NumberFormat;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@@ -1101,7 +1106,6 @@ public final class Utils {
return (sm.getStorageBytesUntilLow(context.getFilesDir()) < 0);
}
-
/**
* Returns a default user icon (as a {@link Bitmap}) for the given user.
*
@@ -1119,4 +1123,39 @@ public final class Utils {
}
return bitmap;
}
+
+ public static boolean hasUsbDefaults(IUsbManager usbManager, String packageName) {
+ try {
+ if (usbManager != null) {
+ return usbManager.hasDefaults(packageName, UserHandle.myUserId());
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "mUsbManager.hasDefaults", e);
+ }
+ return false;
+ }
+
+ public static boolean hasPreferredActivities(PackageManager pm, String packageName) {
+ // Get list of preferred activities
+ List<ComponentName> prefActList = new ArrayList<>();
+ // Intent list cannot be null. so pass empty list
+ List<IntentFilter> intentList = new ArrayList<>();
+ pm.getPreferredActivities(intentList, prefActList, packageName);
+ Log.d(TAG, "Have " + prefActList.size() + " number of activities in preferred list");
+ return prefActList.size() > 0;
+ }
+
+ public static CharSequence getLaunchByDeafaultSummary(ApplicationsState.AppEntry appEntry,
+ IUsbManager usbManager, PackageManager pm, Context context) {
+ String packageName = appEntry.info.packageName;
+ boolean hasPreferred = hasPreferredActivities(pm, packageName)
+ || hasUsbDefaults(usbManager, packageName);
+ int status = pm.getIntentVerificationStatus(packageName, UserHandle.myUserId());
+ boolean hasDomainURLsPreference =
+ (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) ||
+ (status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER);
+ return context.getString(hasPreferred || hasDomainURLsPreference
+ ? R.string.launch_defaults_some
+ : R.string.launch_defaults_none);
+ }
}
diff --git a/src/com/android/settings/applications/AdvancedAppSettings.java b/src/com/android/settings/applications/AdvancedAppSettings.java
index d5ab8dc..3d3c9f6 100644
--- a/src/com/android/settings/applications/AdvancedAppSettings.java
+++ b/src/com/android/settings/applications/AdvancedAppSettings.java
@@ -18,6 +18,7 @@ package com.android.settings.applications;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
+import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.AppOpsManager;
@@ -26,7 +27,6 @@ import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
-import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.NetworkPolicyManager;
import android.os.AsyncTask;
@@ -35,11 +35,9 @@ import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
-import android.os.UserManager;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.util.Log;
-import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -63,14 +61,16 @@ public class AdvancedAppSettings extends SettingsPreferenceFragment implements C
private static final String KEY_APP_PERM = "manage_perms";
private static final String KEY_ALL_APPS = "all_apps";
+ private static final String KEY_APP_DOMAIN_URLS = "domain_urls";
private static final String KEY_RESET_ALL = "reset_all";
private static final String EXTRA_RESET_DIALOG = "resetDialog";
private ApplicationsState mApplicationsState;
private Session mSession;
- private Preference mAppPerms;
- private Preference mAllApps;
- private Preference mResetAll;
+ private Preference mAppPermsPreference;
+ private Preference mAppDomainURLsPreference;
+ private Preference mAllAppsPreference;
+ private Preference mResetAllPreference;
AlertDialog mResetDialog;
@@ -91,17 +91,18 @@ public class AdvancedAppSettings extends SettingsPreferenceFragment implements C
mApplicationsState = ApplicationsState.getInstance(getActivity().getApplication());
mSession = mApplicationsState.newSession(this);
- mAppPerms = findPreference(KEY_APP_PERM);
- mAllApps = findPreference(KEY_ALL_APPS);
- mResetAll = findPreference(KEY_RESET_ALL);
- mResetAll.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ mAppPermsPreference = findPreference(KEY_APP_PERM);
+ mAppDomainURLsPreference = findPreference(KEY_APP_DOMAIN_URLS);
+ mAllAppsPreference = findPreference(KEY_ALL_APPS);
+ mResetAllPreference = findPreference(KEY_RESET_ALL);
+ mResetAllPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
buildResetDialog();
return true;
}
});
- updateAllAppsSummary();
+ updateUI();
mPm = getActivity().getPackageManager();
mIPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
@@ -112,8 +113,19 @@ public class AdvancedAppSettings extends SettingsPreferenceFragment implements C
mHandler = new Handler(getActivity().getMainLooper());
}
- private void updateAllAppsSummary() {
- mAllApps.setSummary(getString(R.string.all_apps_summary, mSession.getAllApps().size()));
+ private void updateUI() {
+ ArrayList<AppEntry> allApps = mSession.getAllApps();
+ mAllAppsPreference.setSummary(getString(R.string.all_apps_summary, allApps.size()));
+
+ int countAppWithDomainURLs = 0;
+ for (AppEntry entry : allApps) {
+ boolean hasDomainURLs =
+ (entry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
+ if (hasDomainURLs) countAppWithDomainURLs++;
+ }
+ String summary = getResources().getQuantityString(
+ R.plurals.domain_urls_apps_summary, countAppWithDomainURLs, countAppWithDomainURLs);
+ mAppDomainURLsPreference.setSummary(summary);
}
@Override
@@ -241,7 +253,7 @@ public class AdvancedAppSettings extends SettingsPreferenceFragment implements C
@Override
public void onPackageListChanged() {
- updateAllAppsSummary();
+ updateUI();
}
@Override
@@ -276,7 +288,9 @@ public class AdvancedAppSettings extends SettingsPreferenceFragment implements C
@Override
public void onPermissionLoadComplete() {
- mAppPerms.setSummary(getActivity().getString(R.string.app_permissions_summary,
+ Activity activity = getActivity();
+ if (activity == null) return;
+ mAppPermsPreference.setSummary(activity.getString(R.string.app_permissions_summary,
mPermissionsInfo.getRuntimePermAppsGrantedCount(),
mPermissionsInfo.getRuntimePermAppsCount()));
}
diff --git a/src/com/android/settings/applications/AppDomainsPreference.java b/src/com/android/settings/applications/AppDomainsPreference.java
new file mode 100644
index 0000000..7e29a20
--- /dev/null
+++ b/src/com/android/settings/applications/AppDomainsPreference.java
@@ -0,0 +1,44 @@
+/*
+ * 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.util.AttributeSet;
+import android.view.View;
+import android.widget.TextView;
+import com.android.settings.accessibility.ListDialogPreference;
+
+import com.android.settings.R;
+
+public class AppDomainsPreference extends ListDialogPreference {
+
+ public AppDomainsPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ setDialogLayoutResource(R.layout.app_domains_dialog);
+ setListItemLayoutResource(R.layout.app_domains_item);
+ }
+
+ @Override
+ protected void onBindListItem(View view, int index) {
+ final CharSequence title = getTitleAt(index);
+ if (title != null) {
+ final TextView domainName = (TextView) view.findViewById(R.id.domain_name);
+ domainName.setText(title);
+ }
+ }
+}
diff --git a/src/com/android/settings/applications/AppLaunchSettings.java b/src/com/android/settings/applications/AppLaunchSettings.java
index ffb84ef..c0a662a 100644
--- a/src/com/android/settings/applications/AppLaunchSettings.java
+++ b/src/com/android/settings/applications/AppLaunchSettings.java
@@ -17,117 +17,78 @@
package com.android.settings.applications;
import android.app.AlertDialog;
-import android.appwidget.AppWidgetManager;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.IntentFilter;
+import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.PackageManager;
-import android.hardware.usb.IUsbManager;
import android.os.Bundle;
-import android.os.RemoteException;
import android.os.UserHandle;
-import android.text.SpannableString;
-import android.text.TextUtils;
-import android.text.style.BulletSpan;
-import android.util.Log;
-import android.view.LayoutInflater;
+import android.preference.Preference;
+import android.preference.SwitchPreference;
+import android.util.ArraySet;
import android.view.View;
import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
import com.android.settings.R;
-import com.android.settings.Utils;
-import com.android.settings.applications.ApplicationsState.AppEntry;
-import java.util.ArrayList;
import java.util.List;
-public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListener {
+public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListener,
+ Preference.OnPreferenceChangeListener {
- private Button mActivitiesButton;
- private AppWidgetManager mAppWidgetManager;
+ private static final String KEY_OPEN_DOMAIN_URLS = "app_launch_open_domain_urls";
+ private static final String KEY_SUPPORTED_DOMAIN_URLS = "app_launch_supported_domain_urls";
+ private static final String KEY_CLEAR_DEFAULTS = "app_launch_clear_defaults";
- private View mRootView;
+ private PackageManager mPm;
+
+ private SwitchPreference mOpenDomainUrls;
+ private AppDomainsPreference mAppDomainUrls;
+ private ClearDefaultsPreference mClearDefaultsPreference;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mAppWidgetManager = AppWidgetManager.getInstance(getActivity());
- }
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- final View view = inflater.inflate(R.layout.app_preferred_settings, container, false);
+ addPreferencesFromResource(R.xml.installed_app_launch_settings);
+
+ mPm = getActivity().getPackageManager();
+ final int myUserId = UserHandle.myUserId();
- final ViewGroup allDetails = (ViewGroup) view.findViewById(R.id.all_details);
- Utils.forceCustomPadding(allDetails, true /* additive padding */);
+ mOpenDomainUrls = (SwitchPreference) findPreference(KEY_OPEN_DOMAIN_URLS);
+ mOpenDomainUrls.setOnPreferenceChangeListener(this);
- mActivitiesButton = (Button) view.findViewById(R.id.clear_activities_button);
- mRootView = view;
+ final int status = mPm.getIntentVerificationStatus(mPackageName, myUserId);
+ boolean checked = status == PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
+ mOpenDomainUrls.setChecked(checked);
- return view;
+ mAppDomainUrls = (AppDomainsPreference) findPreference(KEY_SUPPORTED_DOMAIN_URLS);
+ CharSequence[] entries = getEntries(mPackageName);
+ mAppDomainUrls.setTitles(entries);
+ mAppDomainUrls.setValues(new int[entries.length]);
+
+ mClearDefaultsPreference = (ClearDefaultsPreference) findPreference(KEY_CLEAR_DEFAULTS);
}
- @Override
- protected boolean refreshUi() {
- retrieveAppEntry();
- boolean hasBindAppWidgetPermission =
- mAppWidgetManager.hasBindAppWidgetPermission(mAppEntry.info.packageName);
-
- TextView autoLaunchTitleView = (TextView) mRootView.findViewById(R.id.auto_launch_title);
- TextView autoLaunchView = (TextView) mRootView.findViewById(R.id.auto_launch);
- boolean autoLaunchEnabled = hasPreferredActivities(mPm, mPackageName)
- || hasUsbDefaults(mUsbManager, mPackageName);
- if (!autoLaunchEnabled && !hasBindAppWidgetPermission) {
- resetLaunchDefaultsUi(autoLaunchTitleView, autoLaunchView);
- } else {
- boolean useBullets = hasBindAppWidgetPermission && autoLaunchEnabled;
-
- if (hasBindAppWidgetPermission) {
- autoLaunchTitleView.setText(R.string.auto_launch_label_generic);
- } else {
- autoLaunchTitleView.setText(R.string.auto_launch_label);
- }
+ private CharSequence[] getEntries(String packageName) {
+ ArraySet<String> result = new ArraySet<>();
- CharSequence text = null;
- int bulletIndent = getResources()
- .getDimensionPixelSize(R.dimen.installed_app_details_bullet_offset);
- if (autoLaunchEnabled) {
- CharSequence autoLaunchEnableText = getText(R.string.auto_launch_enable_text);
- SpannableString s = new SpannableString(autoLaunchEnableText);
- if (useBullets) {
- s.setSpan(new BulletSpan(bulletIndent), 0, autoLaunchEnableText.length(), 0);
- }
- text = (text == null) ?
- TextUtils.concat(s, "\n") : TextUtils.concat(text, "\n", s, "\n");
- }
- if (hasBindAppWidgetPermission) {
- CharSequence alwaysAllowBindAppWidgetsText =
- getText(R.string.always_allow_bind_appwidgets_text);
- SpannableString s = new SpannableString(alwaysAllowBindAppWidgetsText);
- if (useBullets) {
- s.setSpan(new BulletSpan(bulletIndent),
- 0, alwaysAllowBindAppWidgetsText.length(), 0);
- }
- text = (text == null) ?
- TextUtils.concat(s, "\n") : TextUtils.concat(text, "\n", s, "\n");
+ List<IntentFilterVerificationInfo> list =
+ mPm.getIntentFilterVerifications(packageName);
+ for (IntentFilterVerificationInfo ivi : list) {
+ for (String host : ivi.getDomains()) {
+ result.add(host);
}
- autoLaunchView.setText(text);
- mActivitiesButton.setEnabled(true);
- mActivitiesButton.setOnClickListener(this);
}
- return true;
+
+ return result.toArray(new CharSequence[0]);
}
- private void resetLaunchDefaultsUi(TextView title, TextView autoLaunchView) {
- title.setText(R.string.auto_launch_label);
- autoLaunchView.setText(R.string.auto_launch_disable_text);
- // Disable clear activities button
- mActivitiesButton.setEnabled(false);
+ @Override
+ protected boolean refreshUi() {
+ mClearDefaultsPreference.setPackageName(mPackageName);
+ mClearDefaultsPreference.setAppEntry(mAppEntry);
+
+ return true;
}
@Override
@@ -136,56 +97,24 @@ public class AppLaunchSettings extends AppInfoWithHeader implements OnClickListe
return null;
}
+
@Override
public void onClick(View v) {
- if (v == mActivitiesButton) {
- if (mUsbManager != null) {
- mPm.clearPackagePreferredActivities(mPackageName);
- try {
- mUsbManager.clearDefaults(mPackageName, UserHandle.myUserId());
- } catch (RemoteException e) {
- Log.e(TAG, "mUsbManager.clearDefaults", e);
- }
- mAppWidgetManager.setBindAppWidgetPermission(mPackageName, false);
- TextView autoLaunchTitleView =
- (TextView) mRootView.findViewById(R.id.auto_launch_title);
- TextView autoLaunchView = (TextView) mRootView.findViewById(R.id.auto_launch);
- resetLaunchDefaultsUi(autoLaunchTitleView, autoLaunchView);
- }
- }
- }
-
- private static boolean hasUsbDefaults(IUsbManager usbManager, String packageName) {
- try {
- if (usbManager != null) {
- return usbManager.hasDefaults(packageName, UserHandle.myUserId());
- }
- } catch (RemoteException e) {
- Log.e(TAG, "mUsbManager.hasDefaults", e);
- }
- return false;
+ // Nothing to do
}
- private static boolean hasPreferredActivities(PackageManager pm, String packageName) {
- // Get list of preferred activities
- List<ComponentName> prefActList = new ArrayList<>();
- // Intent list cannot be null. so pass empty list
- List<IntentFilter> intentList = new ArrayList<>();
- pm.getPreferredActivities(intentList, prefActList, packageName);
- if (localLOGV) {
- Log.i(TAG, "Have " + prefActList.size() + " number of activities in preferred list");
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ boolean ret = false;
+ final String key = preference.getKey();
+ if (KEY_OPEN_DOMAIN_URLS.equals(key)) {
+ SwitchPreference pref = (SwitchPreference) preference;
+ int status = !pref.isChecked() ?
+ PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS :
+ PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
+ ret = mPm.updateIntentVerificationStatus(mPackageName, status, UserHandle.myUserId());
}
- return prefActList.size() > 0;
- }
-
- public static CharSequence getSummary(AppEntry appEntry, IUsbManager usbManager,
- PackageManager pm, Context context) {
- String packageName = appEntry.info.packageName;
- boolean hasPreferred = hasPreferredActivities(pm, packageName)
- || hasUsbDefaults(usbManager, packageName);
- return context.getString(hasPreferred
- ? R.string.launch_defaults_some
- : R.string.launch_defaults_none);
+ return ret;
}
@Override
diff --git a/src/com/android/settings/applications/AppOpsState.java b/src/com/android/settings/applications/AppOpsState.java
index 1ab3c73..77c4582 100644
--- a/src/com/android/settings/applications/AppOpsState.java
+++ b/src/com/android/settings/applications/AppOpsState.java
@@ -191,7 +191,9 @@ public class AppOpsState {
AppOpsManager.OP_SYSTEM_ALERT_WINDOW,
AppOpsManager.OP_WAKE_LOCK,
AppOpsManager.OP_PROJECT_MEDIA,
- AppOpsManager.OP_ACTIVATE_VPN, },
+ AppOpsManager.OP_ACTIVATE_VPN,
+ AppOpsManager.OP_ASSIST_STRUCTURE,
+ AppOpsManager.OP_ASSIST_SCREENSHOT},
new boolean[] { false,
true,
true,
@@ -199,7 +201,9 @@ public class AppOpsState {
true,
true,
false,
- false, }
+ false,
+ false,
+ false }
);
public static final OpsTemplate[] ALL_TEMPLATES = new OpsTemplate[] {
diff --git a/src/com/android/settings/applications/AppViewHolder.java b/src/com/android/settings/applications/AppViewHolder.java
index 176ccca..92aa87a 100644
--- a/src/com/android/settings/applications/AppViewHolder.java
+++ b/src/com/android/settings/applications/AppViewHolder.java
@@ -1,3 +1,19 @@
+/*
+ * 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 com.android.settings.R;
diff --git a/src/com/android/settings/applications/ApplicationsState.java b/src/com/android/settings/applications/ApplicationsState.java
index daa3842..71d0790 100644
--- a/src/com/android/settings/applications/ApplicationsState.java
+++ b/src/com/android/settings/applications/ApplicationsState.java
@@ -1,3 +1,19 @@
+/*
+ * 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.app.ActivityManager;
@@ -116,7 +132,7 @@ public class ApplicationsState {
}
// Need to synchronize on 'this' for the following.
- ApplicationInfo info;
+ public ApplicationInfo info;
Drawable icon;
String sizeStr;
String internalSizeStr;
@@ -323,6 +339,16 @@ public class ApplicationsState {
}
};
+ public static final AppFilter FILTER_WITH_DOMAIN_URLS = new AppFilter() {
+ public void init() {
+ }
+
+ @Override
+ public boolean filterApp(AppEntry entry) {
+ return (entry.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
+ }
+ };
+
final Context mContext;
final PackageManager mPm;
final IPackageManager mIpm;
diff --git a/src/com/android/settings/applications/ClearDefaultsPreference.java b/src/com/android/settings/applications/ClearDefaultsPreference.java
new file mode 100644
index 0000000..1799cad
--- /dev/null
+++ b/src/com/android/settings/applications/ClearDefaultsPreference.java
@@ -0,0 +1,172 @@
+/*
+ * 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.appwidget.AppWidgetManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.usb.IUsbManager;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.preference.Preference;
+import android.text.SpannableString;
+import android.text.TextUtils;
+import android.text.style.BulletSpan;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.TextView;
+
+import com.android.settings.R;
+import com.android.settings.Utils;
+
+public class ClearDefaultsPreference extends Preference {
+
+ protected static final String TAG = ClearDefaultsPreference.class.getSimpleName();
+
+ private View mRootView;
+ private Button mActivitiesButton;
+
+ private AppWidgetManager mAppWidgetManager;
+ private IUsbManager mUsbManager;
+ private PackageManager mPm;
+ private String mPackageName;
+ protected ApplicationsState.AppEntry mAppEntry;
+
+ public ClearDefaultsPreference(Context context, AttributeSet attrs, int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ setLayoutResource(R.layout.app_preferred_settings);
+
+ mAppWidgetManager = AppWidgetManager.getInstance(context);
+ mPm = context.getPackageManager();
+ IBinder b = ServiceManager.getService(Context.USB_SERVICE);
+ mUsbManager = IUsbManager.Stub.asInterface(b);
+ }
+
+ public ClearDefaultsPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+ this(context, attrs, defStyleAttr, 0);
+ }
+
+ public ClearDefaultsPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ClearDefaultsPreference(Context context) {
+ this(context, null);
+ }
+
+ public void setPackageName(String packageName) {
+ mPackageName = packageName;
+ }
+
+ public void setAppEntry(ApplicationsState.AppEntry entry) {
+ mAppEntry = entry;
+ }
+
+ @Override
+ protected View onCreateView(ViewGroup parent) {
+ mRootView = super.onCreateView(parent);
+
+ mActivitiesButton = (Button) mRootView.findViewById(R.id.clear_activities_button);
+ mActivitiesButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ if (mUsbManager != null) {
+ mPm.clearPackagePreferredActivities(mPackageName);
+ try {
+ mUsbManager.clearDefaults(mPackageName, UserHandle.myUserId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "mUsbManager.clearDefaults", e);
+ }
+ mAppWidgetManager.setBindAppWidgetPermission(mPackageName, false);
+ TextView autoLaunchView = (TextView) mRootView.findViewById(R.id.auto_launch);
+ resetLaunchDefaultsUi(autoLaunchView);
+ }
+ }
+ });
+
+ return mRootView;
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+
+ updateUI();
+ }
+
+ public boolean updateUI() {
+ boolean hasBindAppWidgetPermission =
+ mAppWidgetManager.hasBindAppWidgetPermission(mAppEntry.info.packageName);
+
+ TextView autoLaunchView = (TextView) mRootView.findViewById(R.id.auto_launch);
+ boolean autoLaunchEnabled = Utils.hasPreferredActivities(mPm, mPackageName)
+ || Utils.hasUsbDefaults(mUsbManager, mPackageName);
+ if (!autoLaunchEnabled && !hasBindAppWidgetPermission) {
+ resetLaunchDefaultsUi(autoLaunchView);
+ } else {
+ boolean useBullets = hasBindAppWidgetPermission && autoLaunchEnabled;
+
+ if (hasBindAppWidgetPermission) {
+ autoLaunchView.setText(R.string.auto_launch_label_generic);
+ } else {
+ autoLaunchView.setText(R.string.auto_launch_label);
+ }
+
+ Context context = getContext();
+ CharSequence text = null;
+ int bulletIndent = context.getResources().getDimensionPixelSize(
+ R.dimen.installed_app_details_bullet_offset);
+ if (autoLaunchEnabled) {
+ CharSequence autoLaunchEnableText = context.getText(
+ R.string.auto_launch_enable_text);
+ SpannableString s = new SpannableString(autoLaunchEnableText);
+ if (useBullets) {
+ s.setSpan(new BulletSpan(bulletIndent), 0, autoLaunchEnableText.length(), 0);
+ }
+ text = (text == null) ?
+ TextUtils.concat(s, "\n") : TextUtils.concat(text, "\n", s, "\n");
+ }
+ if (hasBindAppWidgetPermission) {
+ CharSequence alwaysAllowBindAppWidgetsText =
+ context.getText(R.string.always_allow_bind_appwidgets_text);
+ SpannableString s = new SpannableString(alwaysAllowBindAppWidgetsText);
+ if (useBullets) {
+ s.setSpan(new BulletSpan(bulletIndent),
+ 0, alwaysAllowBindAppWidgetsText.length(), 0);
+ }
+ text = (text == null) ?
+ TextUtils.concat(s, "\n") : TextUtils.concat(text, "\n", s, "\n");
+ }
+ autoLaunchView.setText(text);
+ mActivitiesButton.setEnabled(true);
+ }
+ return true;
+ }
+
+ private void resetLaunchDefaultsUi(TextView autoLaunchView) {
+ autoLaunchView.setText(R.string.auto_launch_disable_text);
+ // Disable clear activities button
+ mActivitiesButton.setEnabled(false);
+ }
+}
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 9f6c969..33a7428 100755
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -261,10 +261,17 @@ public class InstalledAppDetails extends AppInfoBase
mStoragePreference.setOnPreferenceClickListener(this);
mPermissionsPreference = findPreference(KEY_PERMISSION);
mPermissionsPreference.setOnPreferenceClickListener(this);
- mLaunchPreference = findPreference(KEY_LAUNCH);
- mLaunchPreference.setOnPreferenceClickListener(this);
mDataPreference = findPreference(KEY_DATA);
mDataPreference.setOnPreferenceClickListener(this);
+
+ mLaunchPreference = findPreference(KEY_LAUNCH);
+ if ((mAppEntry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+ mLaunchPreference.setEnabled(false);
+ } else if (!mAppEntry.info.enabled) {
+ mLaunchPreference.setEnabled(false);
+ } else {
+ mLaunchPreference.setOnPreferenceClickListener(this);
+ }
}
private void handleHeader() {
@@ -421,7 +428,7 @@ public class InstalledAppDetails extends AppInfoBase
Activity context = getActivity();
mStoragePreference.setSummary(AppStorageSettings.getSummary(mAppEntry, context));
mPermissionsPreference.setSummary(AppPermissionSettings.getSummary(mAppEntry, context));
- mLaunchPreference.setSummary(AppLaunchSettings.getSummary(mAppEntry, mUsbManager,
+ mLaunchPreference.setSummary(Utils.getLaunchByDeafaultSummary(mAppEntry, mUsbManager,
mPm, context));
mNotificationPreference.setSummary(getNotificationSummary(mAppEntry, context,
mBackend));
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 84b9763..b416aef 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -17,12 +17,13 @@
package com.android.settings.applications;
import android.app.Activity;
-import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
+import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
@@ -32,6 +33,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.preference.PreferenceFrameLayout;
import android.provider.Settings;
+import android.util.ArraySet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -63,10 +65,12 @@ import com.android.settings.applications.ApplicationsState.AppEntry;
import com.android.settings.applications.ApplicationsState.AppFilter;
import com.android.settings.notification.NotificationBackend;
import com.android.settings.notification.NotificationBackend.AppRow;
+import com.android.settings.Settings.DomainsURLsAppListActivity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
+import java.util.List;
final class CanBeOnSdCardChecker {
final IPackageManager mPm;
@@ -145,6 +149,7 @@ public class ManageApplications extends InstrumentedFragment
public static final int FILTER_APPS_SENSITIVE = 6;
public static final int FILTER_APPS_PERSONAL = 7;
public static final int FILTER_APPS_WORK = 8;
+ public static final int FILTER_APPS_WITH_DOMAIN_URLS = 9;
// This is the string labels for the filter modes above, the order must be kept in sync.
public static final int[] FILTER_LABELS = new int[] {
@@ -157,6 +162,7 @@ public class ManageApplications extends InstrumentedFragment
R.string.filter_notif_sensitive_apps, // Sensitive Notifications
R.string.filter_personal_apps, // Personal
R.string.filter_work_apps, // Work
+ R.string.filter_with_domain_urls_apps, // Domain URLs
};
// This is the actual mapping to filters from FILTER_ constants above, the order must
// be kept in sync.
@@ -170,6 +176,7 @@ public class ManageApplications extends InstrumentedFragment
AppStateNotificationBridge.FILTER_APP_NOTIFICATION_SENSITIVE, // Sensitive Notifications
ApplicationsState.FILTER_PERSONAL, // Personal
ApplicationsState.FILTER_WORK, // Work
+ ApplicationsState.FILTER_WITH_DOMAIN_URLS, // Apps with Domain URLs
};
// sort order that can be changed through the menu can be sorted alphabetically
@@ -209,6 +216,7 @@ public class ManageApplications extends InstrumentedFragment
public static final int LIST_TYPE_MAIN = 0;
public static final int LIST_TYPE_ALL = 1;
public static final int LIST_TYPE_NOTIFICATION = 2;
+ public static final int LIST_TYPE_DOMAINS_URLS = 3;
private View mRootView;
@@ -224,7 +232,6 @@ public class ManageApplications extends InstrumentedFragment
mApplicationsState = ApplicationsState.getInstance(getActivity().getApplication());
Intent intent = getActivity().getIntent();
- String action = intent.getAction();
String className = getArguments() != null
? getArguments().getString("classname") : null;
if (className == null) {
@@ -235,6 +242,8 @@ public class ManageApplications extends InstrumentedFragment
} else if (className.equals(NotificationAppListActivity.class.getName())) {
mListType = LIST_TYPE_NOTIFICATION;
mNotifBackend = new NotificationBackend();
+ } else if (className.equals(DomainsURLsAppListActivity.class.getName())) {
+ mListType = LIST_TYPE_DOMAINS_URLS;
} else {
mListType = LIST_TYPE_MAIN;
}
@@ -311,12 +320,17 @@ public class ManageApplications extends InstrumentedFragment
mFilterAdapter.enableFilter(FILTER_APPS_BLOCKED);
mFilterAdapter.enableFilter(FILTER_APPS_PRIORITY);
mFilterAdapter.enableFilter(FILTER_APPS_SENSITIVE);
+ } else if (mListType == LIST_TYPE_DOMAINS_URLS) {
+ mFilterAdapter.disableFilter(FILTER_APPS_ALL);
+ mFilterAdapter.enableFilter(FILTER_APPS_WITH_DOMAIN_URLS);
}
}
private int getDefaultFilter() {
if (mListType == LIST_TYPE_MAIN) {
return FILTER_APPS_DOWNLOADED_AND_LAUNCHER;
+ } else if (mListType == LIST_TYPE_DOMAINS_URLS) {
+ return FILTER_APPS_WITH_DOMAIN_URLS;
}
return FILTER_APPS_ALL;
}
@@ -330,6 +344,8 @@ public class ManageApplications extends InstrumentedFragment
return MetricsLogger.MANAGE_APPLICATIONS_ALL;
case LIST_TYPE_NOTIFICATION:
return MetricsLogger.MANAGE_APPLICATIONS_NOTIFICATIONS;
+ case LIST_TYPE_DOMAINS_URLS:
+ return MetricsLogger.MANAGE_DOMAIN_URLS;
default:
return MetricsLogger.VIEW_UNKNOWN;
}
@@ -382,24 +398,39 @@ public class ManageApplications extends InstrumentedFragment
// utility method used to start sub activity
private void startApplicationDetailsActivity() {
+ Activity activity = getActivity();
if (mListType == LIST_TYPE_NOTIFICATION) {
- getActivity().startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
+ activity.startActivity(new Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.putExtra(Settings.EXTRA_APP_PACKAGE, mCurrentPkgName)
.putExtra(Settings.EXTRA_APP_UID, mCurrentUid));
+ } else if (mListType == LIST_TYPE_DOMAINS_URLS) {
+ final String title = getString(R.string.auto_launch_label);
+ startAppInfoFragment(AppLaunchSettings.class, title);
} else {
// 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.
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", mCurrentPkgName, null));
- getActivity().startActivityAsUser(intent,
- new UserHandle(UserHandle.getUserId(mCurrentUid)));
+ activity.startActivityAsUser(intent, new UserHandle(UserHandle.getUserId(mCurrentUid)));
}
}
+ private void startAppInfoFragment(Class<? extends AppInfoBase> fragment, CharSequence title) {
+ Bundle args = new Bundle();
+ args.putString("package", mCurrentPkgName);
+
+ SettingsActivity sa = (SettingsActivity) getActivity();
+ sa.startPreferencePanel(fragment.getName(), args, -1, title, this, 0);
+ }
+
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ if (mListType == LIST_TYPE_DOMAINS_URLS) {
+ // No option menu
+ return;
+ }
mOptionsMenu = menu;
if (mListType == LIST_TYPE_MAIN) {
// Only show advanced options when in the main app list (from dashboard).
@@ -426,7 +457,6 @@ public class ManageApplications extends InstrumentedFragment
if (mOptionsMenu == null) {
return;
}
-
if (mListType != LIST_TYPE_MAIN) {
// Allow sorting except on main apps list.
mOptionsMenu.findItem(SORT_ORDER_ALPHA).setVisible(mSortOrder != SORT_ORDER_ALPHA);
@@ -580,6 +610,7 @@ public class ManageApplications extends InstrumentedFragment
private int mLastSortMode=-1;
private int mWhichSize = SIZE_TOTAL;
CharSequence mCurFilterPrefix;
+ private PackageManager mPm;
private Filter mFilter = new Filter() {
@Override
@@ -607,6 +638,7 @@ public class ManageApplications extends InstrumentedFragment
mSession = state.newSession(this);
mManageApplications = manageApplications;
mContext = manageApplications.getActivity();
+ mPm = mContext.getPackageManager();
mFilterMode = filterMode;
if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
mNotifBridge = new AppStateNotificationBridge(
@@ -842,6 +874,24 @@ public class ManageApplications extends InstrumentedFragment
return mEntries.get(position).id;
}
+ @Override
+ public boolean areAllItemsEnabled() {
+ return false;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ ApplicationsState.AppEntry entry = mEntries.get(position);
+ synchronized (entry) {
+ if ((entry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
+ return false;
+ } else if (!entry.info.enabled) {
+ return false;
+ }
+ return true;
+ }
+ }
+
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unnecessary calls
// to findViewById() on each row.
@@ -860,15 +910,23 @@ public class ManageApplications extends InstrumentedFragment
if (entry.icon != null) {
holder.appIcon.setImageDrawable(entry.icon);
}
- if (mManageApplications.mListType == LIST_TYPE_NOTIFICATION) {
- if (entry.extraInfo != null) {
- holder.summary.setText(InstalledAppDetails.getNotificationSummary(
- (AppRow) entry.extraInfo, mContext));
- } else {
- holder.summary.setText("");
- }
- } else {
- holder.updateSizeText(mManageApplications.mInvalidSizeStr, mWhichSize);
+ switch (mManageApplications.mListType) {
+ case LIST_TYPE_NOTIFICATION:
+ if (entry.extraInfo != null) {
+ holder.summary.setText(InstalledAppDetails.getNotificationSummary(
+ (AppRow) entry.extraInfo, mContext));
+ } else {
+ holder.summary.setText("");
+ }
+ break;
+
+ case LIST_TYPE_DOMAINS_URLS:
+ holder.summary.setText(getDomainsSummary(entry.info.packageName));
+ break;
+
+ default:
+ holder.updateSizeText(mManageApplications.mInvalidSizeStr, mWhichSize);
+ break;
}
if ((entry.info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
holder.disabled.setVisibility(View.VISIBLE);
@@ -895,5 +953,23 @@ public class ManageApplications extends InstrumentedFragment
public void onMovedToScrapHeap(View view) {
mActive.remove(view);
}
+
+ private CharSequence getDomainsSummary(String packageName) {
+ ArraySet<String> result = new ArraySet<>();
+ List<IntentFilterVerificationInfo> list =
+ mPm.getIntentFilterVerifications(packageName);
+ for (IntentFilterVerificationInfo ivi : list) {
+ for (String host : ivi.getDomains()) {
+ result.add(host);
+ }
+ }
+ if (result.size() == 0) {
+ return mContext.getString(R.string.domain_urls_summary_none);
+ } else if (result.size() == 1) {
+ return mContext.getString(R.string.domain_urls_summary_one, result.valueAt(0));
+ } else {
+ return mContext.getString(R.string.domain_urls_summary_some, result.valueAt(0));
+ }
+ }
}
}
diff --git a/src/com/android/settings/bluetooth/BluetoothSettings.java b/src/com/android/settings/bluetooth/BluetoothSettings.java
index b1eed51..1d0dc7e 100755
--- a/src/com/android/settings/bluetooth/BluetoothSettings.java
+++ b/src/com/android/settings/bluetooth/BluetoothSettings.java
@@ -33,7 +33,10 @@ import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
+import android.text.Spannable;
+import android.text.style.TextAppearanceSpan;
import android.util.Log;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
@@ -45,8 +48,10 @@ import android.widget.EditText;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
+import com.android.settings.LinkifyUtils;
import com.android.settings.R;
import com.android.settings.SettingsActivity;
+import com.android.settings.location.ScanningSettings;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
@@ -136,6 +141,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem
mEmptyView = (TextView) getView().findViewById(android.R.id.empty);
getListView().setEmptyView(mEmptyView);
+ mEmptyView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
final SettingsActivity activity = (SettingsActivity) getActivity();
mSwitchBar = activity.getSwitchBar();
@@ -352,7 +358,7 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem
break;
case BluetoothAdapter.STATE_OFF:
- messageId = R.string.bluetooth_empty_list_bluetooth_off;
+ setOffMessage();
if (isUiRestricted()) {
messageId = R.string.bluetooth_empty_list_user_restricted;
}
@@ -366,12 +372,39 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment implem
setDeviceListGroup(preferenceScreen);
removeAllDevices();
- mEmptyView.setText(messageId);
+ if (messageId != 0) {
+ mEmptyView.setText(messageId);
+ }
if (!isUiRestricted()) {
getActivity().invalidateOptionsMenu();
}
}
+ private void setOffMessage() {
+ if (mEmptyView == null) {
+ return;
+ }
+ final CharSequence briefText = getText(R.string.bluetooth_empty_list_bluetooth_off);
+ final StringBuilder contentBuilder = new StringBuilder();
+ contentBuilder.append(briefText);
+ contentBuilder.append("\n\n");
+ contentBuilder.append(getText(R.string.ble_scan_notify_text));
+ getPreferenceScreen().removeAll();
+ LinkifyUtils.linkify(mEmptyView, contentBuilder, new LinkifyUtils.OnClickListener() {
+ @Override
+ public void onClick() {
+ final SettingsActivity activity =
+ (SettingsActivity) BluetoothSettings.this.getActivity();
+ activity.startPreferencePanel(ScanningSettings.class.getName(), null,
+ R.string.location_scanning_screen_title, null, null, 0);
+ }
+ });
+ Spannable boldSpan = (Spannable) mEmptyView.getText();
+ boldSpan.setSpan(
+ new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_Medium), 0,
+ briefText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+ }
+
@Override
public void onBluetoothStateChanged(int bluetoothState) {
super.onBluetoothStateChanged(bluetoothState);
diff --git a/src/com/android/settings/notification/ZenModeAutomationSettings.java b/src/com/android/settings/notification/ZenModeAutomationSettings.java
new file mode 100644
index 0000000..32ad3ce
--- /dev/null
+++ b/src/com/android/settings/notification/ZenModeAutomationSettings.java
@@ -0,0 +1,453 @@
+/*
+ * 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.notification;
+
+import static com.android.settings.notification.ZenModeDowntimeDaysSelection.DAYS;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.app.FragmentManager;
+import android.app.INotificationManager;
+import android.app.TimePickerDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.os.ServiceManager;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.service.notification.Condition;
+import android.service.notification.ZenModeConfig;
+import android.text.format.DateFormat;
+import android.util.Log;
+import android.util.SparseArray;
+import android.widget.TimePicker;
+
+import com.android.internal.logging.MetricsLogger;
+import com.android.settings.DropDownPreference;
+import com.android.settings.R;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.Indexable;
+import com.android.settings.search.SearchIndexableRaw;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Objects;
+
+public class ZenModeAutomationSettings extends ZenModeSettingsBase implements Indexable {
+ private static final String KEY_DOWNTIME = "downtime";
+ private static final String KEY_DAYS = "days";
+ private static final String KEY_START_TIME = "start_time";
+ private static final String KEY_END_TIME = "end_time";
+ private static final String KEY_DOWNTIME_MODE = "downtime_mode";
+
+ private static final String KEY_AUTOMATION = "automation";
+ private static final String KEY_ENTRY = "entry";
+ private static final String KEY_CONDITION_PROVIDERS = "manage_condition_providers";
+
+ private static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("EEE");
+
+ private PackageManager mPM;
+ private boolean mDisableListeners;
+ private boolean mDowntimeSupported;
+
+ private Preference mDays;
+ private TimePickerPreference mStart;
+ private TimePickerPreference mEnd;
+ private DropDownPreference mDowntimeMode;
+ private PreferenceCategory mAutomationCategory;
+ private Preference mEntry;
+ private Preference mConditionProviders;
+
+ @Override
+ public void onCreate(Bundle icicle) {
+ super.onCreate(icicle);
+ mPM = mContext.getPackageManager();
+
+ addPreferencesFromResource(R.xml.zen_mode_automation_settings);
+ final PreferenceScreen root = getPreferenceScreen();
+
+ onCreateDowntimeSettings(root);
+
+ mAutomationCategory = (PreferenceCategory) findPreference(KEY_AUTOMATION);
+ mEntry = findPreference(KEY_ENTRY);
+ mEntry.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ new AlertDialog.Builder(mContext)
+ .setTitle(R.string.zen_mode_entry_conditions_title)
+ .setView(new ZenModeAutomaticConditionSelection(mContext))
+ .setOnDismissListener(new OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ refreshAutomationSection();
+ }
+ })
+ .setPositiveButton(R.string.dlg_ok, null)
+ .show();
+ return true;
+ }
+ });
+ mConditionProviders = findPreference(KEY_CONDITION_PROVIDERS);
+ }
+
+ private void onCreateDowntimeSettings(PreferenceScreen root) {
+ mDowntimeSupported = isDowntimeSupported(mContext);
+ if (!mDowntimeSupported) {
+ removePreference(KEY_DOWNTIME);
+ return;
+ }
+ mDays = root.findPreference(KEY_DAYS);
+ mDays.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ new AlertDialog.Builder(mContext)
+ .setTitle(R.string.zen_mode_downtime_days)
+ .setView(new ZenModeDowntimeDaysSelection(mContext, mConfig.sleepMode) {
+ @Override
+ protected void onChanged(String mode) {
+ if (mDisableListeners) return;
+ if (Objects.equals(mode, mConfig.sleepMode)) return;
+ if (DEBUG) Log.d(TAG, "days.onChanged sleepMode=" + mode);
+ final ZenModeConfig newConfig = mConfig.copy();
+ newConfig.sleepMode = mode;
+ setZenModeConfig(newConfig);
+ }
+ })
+ .setOnDismissListener(new OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ updateDays();
+ }
+ })
+ .setPositiveButton(R.string.done_button, null)
+ .show();
+ return true;
+ }
+ });
+
+ final FragmentManager mgr = getFragmentManager();
+
+ mStart = new TimePickerPreference(mContext, mgr);
+ mStart.setKey(KEY_START_TIME);
+ mStart.setTitle(R.string.zen_mode_start_time);
+ mStart.setCallback(new TimePickerPreference.Callback() {
+ @Override
+ public boolean onSetTime(int hour, int minute) {
+ if (mDisableListeners) return true;
+ if (!ZenModeConfig.isValidHour(hour)) return false;
+ if (!ZenModeConfig.isValidMinute(minute)) return false;
+ if (hour == mConfig.sleepStartHour && minute == mConfig.sleepStartMinute) {
+ return true;
+ }
+ if (DEBUG) Log.d(TAG, "onPrefChange sleepStart h=" + hour + " m=" + minute);
+ final ZenModeConfig newConfig = mConfig.copy();
+ newConfig.sleepStartHour = hour;
+ newConfig.sleepStartMinute = minute;
+ return setZenModeConfig(newConfig);
+ }
+ });
+ root.addPreference(mStart);
+ mStart.setDependency(mDays.getKey());
+
+ mEnd = new TimePickerPreference(mContext, mgr);
+ mEnd.setKey(KEY_END_TIME);
+ mEnd.setTitle(R.string.zen_mode_end_time);
+ mEnd.setCallback(new TimePickerPreference.Callback() {
+ @Override
+ public boolean onSetTime(int hour, int minute) {
+ if (mDisableListeners) return true;
+ if (!ZenModeConfig.isValidHour(hour)) return false;
+ if (!ZenModeConfig.isValidMinute(minute)) return false;
+ if (hour == mConfig.sleepEndHour && minute == mConfig.sleepEndMinute) {
+ return true;
+ }
+ if (DEBUG) Log.d(TAG, "onPrefChange sleepEnd h=" + hour + " m=" + minute);
+ final ZenModeConfig newConfig = mConfig.copy();
+ newConfig.sleepEndHour = hour;
+ newConfig.sleepEndMinute = minute;
+ return setZenModeConfig(newConfig);
+ }
+ });
+ root.addPreference(mEnd);
+ mEnd.setDependency(mDays.getKey());
+
+ mDowntimeMode = (DropDownPreference) root.findPreference(KEY_DOWNTIME_MODE);
+ mDowntimeMode.addItem(R.string.zen_mode_downtime_mode_priority, false);
+ mDowntimeMode.addItem(R.string.zen_mode_downtime_mode_none, true);
+ mDowntimeMode.setCallback(new DropDownPreference.Callback() {
+ @Override
+ public boolean onItemSelected(int pos, Object value) {
+ if (mDisableListeners) return true;
+ final boolean sleepNone = value instanceof Boolean ? ((Boolean) value) : false;
+ if (mConfig == null || mConfig.sleepNone == sleepNone) return false;
+ final ZenModeConfig newConfig = mConfig.copy();
+ newConfig.sleepNone = sleepNone;
+ if (DEBUG) Log.d(TAG, "onPrefChange sleepNone=" + sleepNone);
+ return setZenModeConfig(newConfig);
+ }
+ });
+ mDowntimeMode.setOrder(10); // sort at the bottom of the category
+ mDowntimeMode.setDependency(mDays.getKey());
+ }
+
+ private void updateDays() {
+ // Compute an ordered, delimited list of day names based on the persisted user config.
+ if (mConfig != null) {
+ final int[] days = ZenModeConfig.tryParseDays(mConfig.sleepMode);
+ if (days != null && days.length != 0) {
+ final StringBuilder sb = new StringBuilder();
+ final Calendar c = Calendar.getInstance();
+ for (int i = 0; i < DAYS.length; i++) {
+ final int day = DAYS[i];
+ for (int j = 0; j < days.length; j++) {
+ if (day == days[j]) {
+ c.set(Calendar.DAY_OF_WEEK, day);
+ if (sb.length() > 0) {
+ sb.append(mContext.getString(R.string.summary_divider_text));
+ }
+ sb.append(DAY_FORMAT.format(c.getTime()));
+ break;
+ }
+ }
+ }
+ if (sb.length() > 0) {
+ mDays.setSummary(sb);
+ mDays.notifyDependencyChange(false);
+ return;
+ }
+ }
+ }
+ mDays.setSummary(R.string.zen_mode_downtime_days_none);
+ mDays.notifyDependencyChange(true);
+ }
+
+ private void updateEndSummary() {
+ if (!mDowntimeSupported) return;
+ final int startMin = 60 * mConfig.sleepStartHour + mConfig.sleepStartMinute;
+ final int endMin = 60 * mConfig.sleepEndHour + mConfig.sleepEndMinute;
+ final boolean nextDay = startMin >= endMin;
+ final int summaryFormat;
+ if (mConfig.sleepNone) {
+ summaryFormat = nextDay ? R.string.zen_mode_end_time_none_next_day_summary_format
+ : R.string.zen_mode_end_time_none_same_day_summary_format;
+ } else {
+ summaryFormat = nextDay ? R.string.zen_mode_end_time_priority_next_day_summary_format
+ : 0;
+ }
+ mEnd.setSummaryFormat(summaryFormat);
+ }
+
+ @Override
+ protected void onZenModeChanged() {
+ // don't care
+ }
+
+ @Override
+ protected void updateControls() {
+ mDisableListeners = true;
+ if (mDowntimeSupported) {
+ updateDays();
+ mStart.setTime(mConfig.sleepStartHour, mConfig.sleepStartMinute);
+ mEnd.setTime(mConfig.sleepEndHour, mConfig.sleepEndMinute);
+ mDowntimeMode.setSelectedValue(mConfig.sleepNone);
+ }
+ mDisableListeners = false;
+ refreshAutomationSection();
+ updateEndSummary();
+ }
+
+ @Override
+ protected int getMetricsCategory() {
+ return MetricsLogger.NOTIFICATION_ZEN_MODE_AUTOMATION;
+ }
+
+ private void refreshAutomationSection() {
+ if (mConditionProviders != null) {
+ final int total = ConditionProviderSettings.getProviderCount(mPM);
+ if (total == 0) {
+ getPreferenceScreen().removePreference(mAutomationCategory);
+ } else {
+ final int n = ConditionProviderSettings.getEnabledProviderCount(mContext);
+ if (n == 0) {
+ mConditionProviders.setSummary(getResources().getString(
+ R.string.manage_condition_providers_summary_zero));
+ } else {
+ mConditionProviders.setSummary(String.format(getResources().getQuantityString(
+ R.plurals.manage_condition_providers_summary_nonzero,
+ n, n)));
+ }
+ final String entrySummary = getEntryConditionSummary();
+ if (n == 0 || entrySummary == null) {
+ mEntry.setSummary(R.string.zen_mode_entry_conditions_summary_none);
+ } else {
+ mEntry.setSummary(entrySummary);
+ }
+ }
+ }
+ }
+
+ private String getEntryConditionSummary() {
+ final INotificationManager nm = INotificationManager.Stub.asInterface(
+ ServiceManager.getService(Context.NOTIFICATION_SERVICE));
+ try {
+ final Condition[] automatic = nm.getAutomaticZenModeConditions();
+ if (automatic == null || automatic.length == 0) {
+ return null;
+ }
+ final String divider = getString(R.string.summary_divider_text);
+ final StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < automatic.length; i++) {
+ if (i > 0) sb.append(divider);
+ sb.append(automatic[i].summary);
+ }
+ return sb.toString();
+ } catch (Exception e) {
+ Log.w(TAG, "Error calling getAutomaticZenModeConditions", e);
+ return null;
+ }
+ }
+
+ private static SparseArray<String> allKeyTitles(Context context) {
+ final SparseArray<String> rt = new SparseArray<String>();
+ rt.put(R.string.zen_mode_downtime_category, KEY_DOWNTIME);
+ rt.put(R.string.zen_mode_downtime_days, KEY_DAYS);
+ rt.put(R.string.zen_mode_start_time, KEY_START_TIME);
+ rt.put(R.string.zen_mode_end_time, KEY_END_TIME);
+ rt.put(R.string.zen_mode_downtime_mode_title, KEY_DOWNTIME_MODE);
+ rt.put(R.string.zen_mode_automation_category, KEY_AUTOMATION);
+ rt.put(R.string.manage_condition_providers, KEY_CONDITION_PROVIDERS);
+ return rt;
+ }
+
+ // Enable indexing of searchable data
+ public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+ new BaseSearchIndexProvider() {
+
+ @Override
+ public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
+ final SparseArray<String> keyTitles = allKeyTitles(context);
+ final int N = keyTitles.size();
+ final List<SearchIndexableRaw> result = new ArrayList<SearchIndexableRaw>(N);
+ final Resources res = context.getResources();
+ for (int i = 0; i < N; i++) {
+ final SearchIndexableRaw data = new SearchIndexableRaw(context);
+ data.key = keyTitles.valueAt(i);
+ data.title = res.getString(keyTitles.keyAt(i));
+ data.screenTitle = res.getString(R.string.zen_mode_automation_settings_title);
+ result.add(data);
+ }
+ return result;
+ }
+
+ @Override
+ public List<String> getNonIndexableKeys(Context context) {
+ final ArrayList<String> rt = new ArrayList<String>();
+ if (!isDowntimeSupported(context)) {
+ rt.add(KEY_DOWNTIME);
+ rt.add(KEY_DAYS);
+ rt.add(KEY_START_TIME);
+ rt.add(KEY_END_TIME);
+ rt.add(KEY_DOWNTIME_MODE);
+ }
+ return rt;
+ }
+ };
+
+ private static class TimePickerPreference extends Preference {
+ private final Context mContext;
+
+ private int mSummaryFormat;
+ private int mHourOfDay;
+ private int mMinute;
+ private Callback mCallback;
+
+ public TimePickerPreference(Context context, final FragmentManager mgr) {
+ super(context);
+ mContext = context;
+ setPersistent(false);
+ setOnPreferenceClickListener(new OnPreferenceClickListener(){
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ final TimePickerFragment frag = new TimePickerFragment();
+ frag.pref = TimePickerPreference.this;
+ frag.show(mgr, TimePickerPreference.class.getName());
+ return true;
+ }
+ });
+ }
+
+ public void setCallback(Callback callback) {
+ mCallback = callback;
+ }
+
+ public void setSummaryFormat(int resId) {
+ mSummaryFormat = resId;
+ updateSummary();
+ }
+
+ public void setTime(int hourOfDay, int minute) {
+ if (mCallback != null && !mCallback.onSetTime(hourOfDay, minute)) return;
+ mHourOfDay = hourOfDay;
+ mMinute = minute;
+ updateSummary();
+ }
+
+ private void updateSummary() {
+ final Calendar c = Calendar.getInstance();
+ c.set(Calendar.HOUR_OF_DAY, mHourOfDay);
+ c.set(Calendar.MINUTE, mMinute);
+ String time = DateFormat.getTimeFormat(mContext).format(c.getTime());
+ if (mSummaryFormat != 0) {
+ time = mContext.getResources().getString(mSummaryFormat, time);
+ }
+ setSummary(time);
+ }
+
+ public static class TimePickerFragment extends DialogFragment implements
+ TimePickerDialog.OnTimeSetListener {
+ public TimePickerPreference pref;
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ final boolean usePref = pref != null && pref.mHourOfDay >= 0 && pref.mMinute >= 0;
+ final Calendar c = Calendar.getInstance();
+ final int hour = usePref ? pref.mHourOfDay : c.get(Calendar.HOUR_OF_DAY);
+ final int minute = usePref ? pref.mMinute : c.get(Calendar.MINUTE);
+ return new TimePickerDialog(getActivity(), this, hour, minute,
+ DateFormat.is24HourFormat(getActivity()));
+ }
+
+ public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
+ if (pref != null) {
+ pref.setTime(hourOfDay, minute);
+ }
+ }
+ }
+
+ public interface Callback {
+ boolean onSetTime(int hour, int minute);
+ }
+ }
+}
diff --git a/src/com/android/settings/notification/ZenModeSettings.java b/src/com/android/settings/notification/ZenModeSettings.java
index 053d2ef..47d1f5d 100644
--- a/src/com/android/settings/notification/ZenModeSettings.java
+++ b/src/com/android/settings/notification/ZenModeSettings.java
@@ -16,61 +16,31 @@
package com.android.settings.notification;
-import static com.android.settings.notification.ZenModeDowntimeDaysSelection.DAYS;
-
import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.app.FragmentManager;
-import android.app.INotificationManager;
-import android.app.NotificationManager;
-import android.app.TimePickerDialog;
import android.content.Context;
import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
-import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Bundle;
-import android.os.ServiceManager;
import android.preference.Preference;
-import android.preference.Preference.OnPreferenceClickListener;
-import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import android.provider.Settings.Global;
-import android.service.notification.Condition;
-import android.service.notification.ZenModeConfig;
-import android.text.format.DateFormat;
-import android.util.Log;
import android.util.SparseArray;
import android.widget.ScrollView;
-import android.widget.TimePicker;
import com.android.internal.logging.MetricsLogger;
-import com.android.settings.DropDownPreference;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
-import java.util.Calendar;
import java.util.List;
-import java.util.Objects;
public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
private static final String KEY_ZEN_MODE = "zen_mode";
private static final String KEY_PRIORITY_SETTINGS = "priority_settings";
- private static final String KEY_DOWNTIME = "downtime";
- private static final String KEY_DAYS = "days";
- private static final String KEY_START_TIME = "start_time";
- private static final String KEY_END_TIME = "end_time";
- private static final String KEY_DOWNTIME_MODE = "downtime_mode";
-
- private static final String KEY_AUTOMATION = "automation";
- private static final String KEY_ENTRY = "entry";
- private static final String KEY_CONDITION_PROVIDERS = "manage_condition_providers";
+ private static final String KEY_AUTOMATION_SETTINGS = "automation_settings";
private static final SettingPrefWithCallback PREF_ZEN_MODE = new SettingPrefWithCallback(
SettingPref.TYPE_GLOBAL, KEY_ZEN_MODE, Global.ZEN_MODE, Global.ZEN_MODE_OFF,
@@ -90,35 +60,17 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
}
};
- private static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat("EEE");
+ private Preference mPrioritySettings;
+ private AlertDialog mDialog;
private static SparseArray<String> allKeyTitles(Context context) {
final SparseArray<String> rt = new SparseArray<String>();
rt.put(R.string.zen_mode_option_title, KEY_ZEN_MODE);
rt.put(R.string.zen_mode_priority_settings_title, KEY_PRIORITY_SETTINGS);
- rt.put(R.string.zen_mode_downtime_category, KEY_DOWNTIME);
- rt.put(R.string.zen_mode_downtime_days, KEY_DAYS);
- rt.put(R.string.zen_mode_start_time, KEY_START_TIME);
- rt.put(R.string.zen_mode_end_time, KEY_END_TIME);
- rt.put(R.string.zen_mode_downtime_mode_title, KEY_DOWNTIME_MODE);
- rt.put(R.string.zen_mode_automation_category, KEY_AUTOMATION);
- rt.put(R.string.manage_condition_providers, KEY_CONDITION_PROVIDERS);
+ rt.put(R.string.zen_mode_automation_settings_title, KEY_AUTOMATION_SETTINGS);
return rt;
}
- private PackageManager mPM;
- private boolean mDisableListeners;
- private boolean mDowntimeSupported;
- private Preference mPrioritySettings;
- private Preference mDays;
- private TimePickerPreference mStart;
- private TimePickerPreference mEnd;
- private DropDownPreference mDowntimeMode;
- private PreferenceCategory mAutomationCategory;
- private Preference mEntry;
- private Preference mConditionProviders;
- private AlertDialog mDialog;
-
@Override
protected int getMetricsCategory() {
return MetricsLogger.NOTIFICATION_ZEN_MODE;
@@ -132,7 +84,6 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mPM = mContext.getPackageManager();
addPreferencesFromResource(R.xml.zen_mode_settings);
final PreferenceScreen root = getPreferenceScreen();
@@ -148,188 +99,15 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
});
mPrioritySettings = root.findPreference(KEY_PRIORITY_SETTINGS);
-
- final PreferenceCategory downtime = (PreferenceCategory) root.findPreference(KEY_DOWNTIME);
- mDowntimeSupported = isDowntimeSupported(mContext);
- if (!mDowntimeSupported) {
- removePreference(KEY_DOWNTIME);
- } else {
- mDays = downtime.findPreference(KEY_DAYS);
- mDays.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- new AlertDialog.Builder(mContext)
- .setTitle(R.string.zen_mode_downtime_days)
- .setView(new ZenModeDowntimeDaysSelection(mContext, mConfig.sleepMode) {
- @Override
- protected void onChanged(String mode) {
- if (mDisableListeners) return;
- if (Objects.equals(mode, mConfig.sleepMode)) return;
- if (DEBUG) Log.d(TAG, "days.onChanged sleepMode=" + mode);
- final ZenModeConfig newConfig = mConfig.copy();
- newConfig.sleepMode = mode;
- setZenModeConfig(newConfig);
- }
- })
- .setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- updateDays();
- }
- })
- .setPositiveButton(R.string.done_button, null)
- .show();
- return true;
- }
- });
-
- final FragmentManager mgr = getFragmentManager();
-
- mStart = new TimePickerPreference(mContext, mgr);
- mStart.setKey(KEY_START_TIME);
- mStart.setTitle(R.string.zen_mode_start_time);
- mStart.setCallback(new TimePickerPreference.Callback() {
- @Override
- public boolean onSetTime(int hour, int minute) {
- if (mDisableListeners) return true;
- if (!ZenModeConfig.isValidHour(hour)) return false;
- if (!ZenModeConfig.isValidMinute(minute)) return false;
- if (hour == mConfig.sleepStartHour && minute == mConfig.sleepStartMinute) {
- return true;
- }
- if (DEBUG) Log.d(TAG, "onPrefChange sleepStart h=" + hour + " m=" + minute);
- final ZenModeConfig newConfig = mConfig.copy();
- newConfig.sleepStartHour = hour;
- newConfig.sleepStartMinute = minute;
- return setZenModeConfig(newConfig);
- }
- });
- downtime.addPreference(mStart);
- mStart.setDependency(mDays.getKey());
-
- mEnd = new TimePickerPreference(mContext, mgr);
- mEnd.setKey(KEY_END_TIME);
- mEnd.setTitle(R.string.zen_mode_end_time);
- mEnd.setCallback(new TimePickerPreference.Callback() {
- @Override
- public boolean onSetTime(int hour, int minute) {
- if (mDisableListeners) return true;
- if (!ZenModeConfig.isValidHour(hour)) return false;
- if (!ZenModeConfig.isValidMinute(minute)) return false;
- if (hour == mConfig.sleepEndHour && minute == mConfig.sleepEndMinute) {
- return true;
- }
- if (DEBUG) Log.d(TAG, "onPrefChange sleepEnd h=" + hour + " m=" + minute);
- final ZenModeConfig newConfig = mConfig.copy();
- newConfig.sleepEndHour = hour;
- newConfig.sleepEndMinute = minute;
- return setZenModeConfig(newConfig);
- }
- });
- downtime.addPreference(mEnd);
- mEnd.setDependency(mDays.getKey());
-
- mDowntimeMode = (DropDownPreference) downtime.findPreference(KEY_DOWNTIME_MODE);
- mDowntimeMode.addItem(R.string.zen_mode_downtime_mode_priority, false);
- mDowntimeMode.addItem(R.string.zen_mode_downtime_mode_none, true);
- mDowntimeMode.setCallback(new DropDownPreference.Callback() {
- @Override
- public boolean onItemSelected(int pos, Object value) {
- if (mDisableListeners) return true;
- final boolean sleepNone = value instanceof Boolean ? ((Boolean) value) : false;
- if (mConfig == null || mConfig.sleepNone == sleepNone) return false;
- final ZenModeConfig newConfig = mConfig.copy();
- newConfig.sleepNone = sleepNone;
- if (DEBUG) Log.d(TAG, "onPrefChange sleepNone=" + sleepNone);
- return setZenModeConfig(newConfig);
- }
- });
- mDowntimeMode.setOrder(10); // sort at the bottom of the category
- mDowntimeMode.setDependency(mDays.getKey());
+ if (!isDowntimeSupported(mContext)) {
+ removePreference(KEY_AUTOMATION_SETTINGS);
}
- mAutomationCategory = (PreferenceCategory) findPreference(KEY_AUTOMATION);
- mEntry = findPreference(KEY_ENTRY);
- mEntry.setOnPreferenceClickListener(new OnPreferenceClickListener() {
- @Override
- public boolean onPreferenceClick(Preference preference) {
- new AlertDialog.Builder(mContext)
- .setTitle(R.string.zen_mode_entry_conditions_title)
- .setView(new ZenModeAutomaticConditionSelection(mContext))
- .setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- refreshAutomationSection();
- }
- })
- .setPositiveButton(R.string.dlg_ok, null)
- .show();
- return true;
- }
- });
- mConditionProviders = findPreference(KEY_CONDITION_PROVIDERS);
-
updateControls();
}
- private void updateDays() {
- if (mConfig != null) {
- final int[] days = ZenModeConfig.tryParseDays(mConfig.sleepMode);
- if (days != null && days.length != 0) {
- final StringBuilder sb = new StringBuilder();
- final Calendar c = Calendar.getInstance();
- for (int i = 0; i < DAYS.length; i++) {
- final int day = DAYS[i];
- for (int j = 0; j < days.length; j++) {
- if (day == days[j]) {
- c.set(Calendar.DAY_OF_WEEK, day);
- if (sb.length() > 0) {
- sb.append(mContext.getString(R.string.summary_divider_text));
- }
- sb.append(DAY_FORMAT.format(c.getTime()));
- break;
- }
- }
- }
- if (sb.length() > 0) {
- mDays.setSummary(sb);
- mDays.notifyDependencyChange(false);
- return;
- }
- }
- }
- mDays.setSummary(R.string.zen_mode_downtime_days_none);
- mDays.notifyDependencyChange(true);
- }
-
- private void updateEndSummary() {
- if (!mDowntimeSupported) return;
- final int startMin = 60 * mConfig.sleepStartHour + mConfig.sleepStartMinute;
- final int endMin = 60 * mConfig.sleepEndHour + mConfig.sleepEndMinute;
- final boolean nextDay = startMin >= endMin;
- final int summaryFormat;
- if (mConfig.sleepNone) {
- summaryFormat = nextDay ? R.string.zen_mode_end_time_none_next_day_summary_format
- : R.string.zen_mode_end_time_none_same_day_summary_format;
- } else {
- summaryFormat = nextDay ? R.string.zen_mode_end_time_priority_next_day_summary_format
- : 0;
- }
- mEnd.setSummaryFormat(summaryFormat);
- }
-
@Override
protected void updateControls() {
- mDisableListeners = true;
- if (mDowntimeSupported) {
- updateDays();
- mStart.setTime(mConfig.sleepStartHour, mConfig.sleepStartMinute);
- mEnd.setTime(mConfig.sleepEndHour, mConfig.sleepEndMinute);
- mDowntimeMode.setSelectedValue(mConfig.sleepNone);
- }
- mDisableListeners = false;
- refreshAutomationSection();
- updateEndSummary();
updatePrioritySettingsSummary();
}
@@ -350,56 +128,6 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
return s;
}
- private void refreshAutomationSection() {
- if (mConditionProviders != null) {
- final int total = ConditionProviderSettings.getProviderCount(mPM);
- if (total == 0) {
- getPreferenceScreen().removePreference(mAutomationCategory);
- } else {
- final int n = ConditionProviderSettings.getEnabledProviderCount(mContext);
- if (n == 0) {
- mConditionProviders.setSummary(getResources().getString(
- R.string.manage_condition_providers_summary_zero));
- } else {
- mConditionProviders.setSummary(String.format(getResources().getQuantityString(
- R.plurals.manage_condition_providers_summary_nonzero,
- n, n)));
- }
- final String entrySummary = getEntryConditionSummary();
- if (n == 0 || entrySummary == null) {
- mEntry.setSummary(R.string.zen_mode_entry_conditions_summary_none);
- } else {
- mEntry.setSummary(entrySummary);
- }
- }
- }
- }
-
- private String getEntryConditionSummary() {
- final INotificationManager nm = INotificationManager.Stub.asInterface(
- ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- try {
- final Condition[] automatic = nm.getAutomaticZenModeConditions();
- if (automatic == null || automatic.length == 0) {
- return null;
- }
- final String divider = getString(R.string.summary_divider_text);
- final StringBuilder sb = new StringBuilder();
- for (int i = 0; i < automatic.length; i++) {
- if (i > 0) sb.append(divider);
- sb.append(automatic[i].summary);
- }
- return sb.toString();
- } catch (Exception e) {
- Log.w(TAG, "Error calling getAutomaticZenModeConditions", e);
- return null;
- }
- }
-
- protected void putZenModeSetting(int value) {
- Global.putInt(getContentResolver(), Global.ZEN_MODE, value);
- }
-
protected void showConditionSelection(final int newSettingsValue) {
if (mDialog != null) return;
@@ -440,11 +168,6 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
mDialog = null;
}
- private static boolean isDowntimeSupported(Context context) {
- return NotificationManager.from(context)
- .isSystemConditionProviderEnabled(ZenModeConfig.DOWNTIME_PATH);
- }
-
// Enable indexing of searchable data
public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider() {
@@ -469,11 +192,7 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
public List<String> getNonIndexableKeys(Context context) {
final ArrayList<String> rt = new ArrayList<String>();
if (!isDowntimeSupported(context)) {
- rt.add(KEY_DOWNTIME);
- rt.add(KEY_DAYS);
- rt.add(KEY_START_TIME);
- rt.add(KEY_END_TIME);
- rt.add(KEY_DOWNTIME_MODE);
+ rt.add(KEY_AUTOMATION_SETTINGS);
}
return rt;
}
@@ -532,80 +251,4 @@ public class ZenModeSettings extends ZenModeSettingsBase implements Indexable {
void onSettingSelected(int value);
}
}
-
- private static class TimePickerPreference extends Preference {
- private final Context mContext;
-
- private int mSummaryFormat;
- private int mHourOfDay;
- private int mMinute;
- private Callback mCallback;
-
- public TimePickerPreference(Context context, final FragmentManager mgr) {
- super(context);
- mContext = context;
- setPersistent(false);
- setOnPreferenceClickListener(new OnPreferenceClickListener(){
- @Override
- public boolean onPreferenceClick(Preference preference) {
- final TimePickerFragment frag = new TimePickerFragment();
- frag.pref = TimePickerPreference.this;
- frag.show(mgr, TimePickerPreference.class.getName());
- return true;
- }
- });
- }
-
- public void setCallback(Callback callback) {
- mCallback = callback;
- }
-
- public void setSummaryFormat(int resId) {
- mSummaryFormat = resId;
- updateSummary();
- }
-
- public void setTime(int hourOfDay, int minute) {
- if (mCallback != null && !mCallback.onSetTime(hourOfDay, minute)) return;
- mHourOfDay = hourOfDay;
- mMinute = minute;
- updateSummary();
- }
-
- private void updateSummary() {
- final Calendar c = Calendar.getInstance();
- c.set(Calendar.HOUR_OF_DAY, mHourOfDay);
- c.set(Calendar.MINUTE, mMinute);
- String time = DateFormat.getTimeFormat(mContext).format(c.getTime());
- if (mSummaryFormat != 0) {
- time = mContext.getResources().getString(mSummaryFormat, time);
- }
- setSummary(time);
- }
-
- public static class TimePickerFragment extends DialogFragment implements
- TimePickerDialog.OnTimeSetListener {
- public TimePickerPreference pref;
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final boolean usePref = pref != null && pref.mHourOfDay >= 0 && pref.mMinute >= 0;
- final Calendar c = Calendar.getInstance();
- final int hour = usePref ? pref.mHourOfDay : c.get(Calendar.HOUR_OF_DAY);
- final int minute = usePref ? pref.mMinute : c.get(Calendar.MINUTE);
- return new TimePickerDialog(getActivity(), this, hour, minute,
- DateFormat.is24HourFormat(getActivity()));
- }
-
- public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
- if (pref != null) {
- pref.setTime(hourOfDay, minute);
- }
- }
- }
-
- public interface Callback {
- boolean onSetTime(int hour, int minute);
- }
- }
}
diff --git a/src/com/android/settings/notification/ZenModeSettingsBase.java b/src/com/android/settings/notification/ZenModeSettingsBase.java
index d436965..ec17d86 100644
--- a/src/com/android/settings/notification/ZenModeSettingsBase.java
+++ b/src/com/android/settings/notification/ZenModeSettingsBase.java
@@ -17,6 +17,7 @@
package com.android.settings.notification;
import android.app.INotificationManager;
+import android.app.NotificationManager;
import android.content.Context;
import android.database.ContentObserver;
import android.net.Uri;
@@ -83,6 +84,11 @@ abstract public class ZenModeSettingsBase extends SettingsPreferenceFragment {
}
}
+ protected static boolean isDowntimeSupported(Context context) {
+ return NotificationManager.from(context)
+ .isSystemConditionProviderEnabled(ZenModeConfig.DOWNTIME_PATH);
+ }
+
private void updateZenModeConfig() {
final ZenModeConfig config = getZenModeConfig();
if (Objects.equals(config, mConfig)) return;
diff --git a/src/com/android/settings/search/Ranking.java b/src/com/android/settings/search/Ranking.java
index e4e5d12..f37e1fc 100644
--- a/src/com/android/settings/search/Ranking.java
+++ b/src/com/android/settings/search/Ranking.java
@@ -42,6 +42,7 @@ import com.android.settings.location.ScanningSettings;
import com.android.settings.net.DataUsageMeteredSettings;
import com.android.settings.notification.NotificationSettings;
import com.android.settings.notification.OtherSoundSettings;
+import com.android.settings.notification.ZenModeAutomationSettings;
import com.android.settings.notification.ZenModePrioritySettings;
import com.android.settings.notification.ZenModeSettings;
import com.android.settings.print.PrintSettingsFragment;
@@ -125,6 +126,7 @@ public final class Ranking {
sRankMap.put(OtherSoundSettings.class.getName(), RANK_NOTIFICATIONS);
sRankMap.put(ZenModeSettings.class.getName(), RANK_NOTIFICATIONS);
sRankMap.put(ZenModePrioritySettings.class.getName(), RANK_NOTIFICATIONS);
+ sRankMap.put(ZenModeAutomationSettings.class.getName(), RANK_NOTIFICATIONS);
// Storage
sRankMap.put(Memory.class.getName(), RANK_STORAGE);
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index d57a1f1..75d7d62 100644
--- a/src/com/android/settings/search/SearchIndexableResources.java
+++ b/src/com/android/settings/search/SearchIndexableResources.java
@@ -43,6 +43,7 @@ import com.android.settings.location.ScanningSettings;
import com.android.settings.net.DataUsageMeteredSettings;
import com.android.settings.notification.NotificationSettings;
import com.android.settings.notification.OtherSoundSettings;
+import com.android.settings.notification.ZenModeAutomationSettings;
import com.android.settings.notification.ZenModePrioritySettings;
import com.android.settings.notification.ZenModeSettings;
import com.android.settings.print.PrintSettingsFragment;
@@ -170,6 +171,13 @@ public final class SearchIndexableResources {
ZenModePrioritySettings.class.getName(),
R.drawable.ic_settings_notifications));
+ sResMap.put(ZenModeAutomationSettings.class.getName(),
+ new SearchIndexableResource(
+ Ranking.getRankForClassName(ZenModeAutomationSettings.class.getName()),
+ NO_DATA_RES_ID,
+ ZenModeAutomationSettings.class.getName(),
+ R.drawable.ic_settings_notifications));
+
sResMap.put(Memory.class.getName(),
new SearchIndexableResource(
Ranking.getRankForClassName(Memory.class.getName()),
diff --git a/src/com/android/settings/users/AppRestrictionsFragment.java b/src/com/android/settings/users/AppRestrictionsFragment.java
index e09d650..a166f0d 100644
--- a/src/com/android/settings/users/AppRestrictionsFragment.java
+++ b/src/com/android/settings/users/AppRestrictionsFragment.java
@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.RestrictionEntry;
+import android.content.RestrictionsManager;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
@@ -841,7 +842,7 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
continue;
}
mUserManager.setApplicationRestrictions(packageName,
- RestrictionUtils.restrictionsToBundle(restrictions),
+ RestrictionsManager.convertRestrictionsToBundle(restrictions),
mUser);
break;
}
@@ -915,7 +916,7 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
onRestrictionsReceived(preference, packageName, restrictions);
if (mRestrictedProfile) {
mUserManager.setApplicationRestrictions(packageName,
- RestrictionUtils.restrictionsToBundle(restrictions), mUser);
+ RestrictionsManager.convertRestrictionsToBundle(restrictions), mUser);
}
} else if (restrictionsIntent != null) {
preference.setRestrictions(restrictions);
@@ -1046,7 +1047,7 @@ public class AppRestrictionsFragment extends SettingsPreferenceFragment implemen
// If there's a valid result, persist it to the user manager.
pref.setRestrictions(list);
mUserManager.setApplicationRestrictions(packageName,
- RestrictionUtils.restrictionsToBundle(list), mUser);
+ RestrictionsManager.convertRestrictionsToBundle(list), mUser);
} else if (bundle != null) {
// If there's a valid result, persist it to the user manager.
mUserManager.setApplicationRestrictions(packageName, bundle, mUser);
diff --git a/src/com/android/settings/users/RestrictionUtils.java b/src/com/android/settings/users/RestrictionUtils.java
index e8d46e9..b36cb3e 100644
--- a/src/com/android/settings/users/RestrictionUtils.java
+++ b/src/com/android/settings/users/RestrictionUtils.java
@@ -90,18 +90,4 @@ public class RestrictionUtils {
}
um.setUserRestrictions(userRestrictions, user);
}
-
- public static Bundle restrictionsToBundle(ArrayList<RestrictionEntry> entries) {
- final Bundle bundle = new Bundle();
- for (RestrictionEntry entry : entries) {
- if (entry.getType() == RestrictionEntry.TYPE_BOOLEAN) {
- bundle.putBoolean(entry.getKey(), entry.getSelectedState());
- } else if (entry.getType() == RestrictionEntry.TYPE_MULTI_SELECT) {
- bundle.putStringArray(entry.getKey(), entry.getAllSelectedStrings());
- } else {
- bundle.putString(entry.getKey(), entry.getSelectedString());
- }
- }
- return bundle;
- }
}
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 238db69..cb6be53 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -18,6 +18,7 @@ package com.android.settings.wifi;
import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
import static android.os.UserManager.DISALLOW_CONFIG_WIFI;
+
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
@@ -25,7 +26,7 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.TypedArray;
-import android.location.LocationManager;
+import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
@@ -36,21 +37,27 @@ import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceScreen;
+import android.text.Spannable;
+import android.text.style.TextAppearanceSpan;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
+import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.TextView;
+import android.widget.TextView.BufferType;
import android.widget.Toast;
import com.android.internal.logging.MetricsLogger;
+import com.android.settings.LinkifyUtils;
import com.android.settings.R;
import com.android.settings.RestrictedSettingsFragment;
import com.android.settings.SettingsActivity;
+import com.android.settings.location.ScanningSettings;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.search.Indexable;
import com.android.settings.search.SearchIndexableRaw;
@@ -608,27 +615,41 @@ public class WifiSettings extends RestrictedSettingsFragment
protected TextView initEmptyView() {
TextView emptyView = (TextView) getActivity().findViewById(android.R.id.empty);
+ emptyView.setGravity(Gravity.START | Gravity.CENTER_VERTICAL);
getListView().setEmptyView(emptyView);
return emptyView;
}
private void setOffMessage() {
- if (mEmptyView != null) {
- mEmptyView.setText(R.string.wifi_empty_list_wifi_off);
- if (android.provider.Settings.Global.getInt(getActivity().getContentResolver(),
- android.provider.Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 1) {
- mEmptyView.append("\n\n");
- int resId;
- if (android.provider.Settings.Secure.isLocationProviderEnabled(
- getActivity().getContentResolver(), LocationManager.NETWORK_PROVIDER)) {
- resId = R.string.wifi_scan_notify_text_location_on;
- } else {
- resId = R.string.wifi_scan_notify_text_location_off;
+ if (mEmptyView == null) {
+ return;
+ }
+
+ final CharSequence briefText = getText(R.string.wifi_empty_list_wifi_off);
+ if (isUiRestricted()) {
+ // Show only the brief text if the user is not allowed to configure scanning settings.
+ mEmptyView.setText(briefText, BufferType.SPANNABLE);
+ } else {
+ // Append the description of scanning settings with link.
+ final StringBuilder contentBuilder = new StringBuilder();
+ contentBuilder.append(briefText);
+ contentBuilder.append("\n\n");
+ contentBuilder.append(getText(R.string.wifi_scan_notify_text));
+ LinkifyUtils.linkify(mEmptyView, contentBuilder, new LinkifyUtils.OnClickListener() {
+ @Override
+ public void onClick() {
+ final SettingsActivity activity =
+ (SettingsActivity) WifiSettings.this.getActivity();
+ activity.startPreferencePanel(ScanningSettings.class.getName(), null,
+ R.string.location_scanning_screen_title, null, null, 0);
}
- CharSequence charSeq = getText(resId);
- mEmptyView.append(charSeq);
- }
+ });
}
+ // Embolden and enlarge the brief description anyway.
+ Spannable boldSpan = (Spannable) mEmptyView.getText();
+ boldSpan.setSpan(
+ new TextAppearanceSpan(getActivity(), android.R.style.TextAppearance_Medium), 0,
+ briefText.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
getPreferenceScreen().removeAll();
}