OSDN Git Service

Allow users to choose a notification assistant.
authorJulia Reynolds <juliacr@google.com>
Mon, 14 Dec 2015 13:32:46 +0000 (08:32 -0500)
committerJulia Reynolds <juliacr@google.com>
Mon, 4 Jan 2016 21:36:56 +0000 (16:36 -0500)
Change-Id: Iddfbfedbb6a3aae246058ff41324dc06852484cb

AndroidManifest.xml
res/values/strings.xml
res/xml/default_apps.xml
src/com/android/settings/AppListPreference.java
src/com/android/settings/CustomListPreference.java
src/com/android/settings/Settings.java
src/com/android/settings/SettingsActivity.java
src/com/android/settings/applications/DefaultNotificationAssistantPreference.java [new file with mode: 0644]
src/com/android/settings/notification/ManagedServiceSettings.java

index d35a844..d8dd102 100644 (file)
             </intent-filter>
         </activity>
 
+        <activity android:name="Settings$ManageDefaultAppsActivity"
+                  android:taskAffinity=""
+                  android:exported="true">
+            <intent-filter android:priority="1">
+                <action android:name="android.settings.MANAGE_DEFAULT_APPS_SETTINGS" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.FRAGMENT_CLASS"
+                       android:value="com.android.settings.applications.ManageDefaultApps" />
+            <meta-data android:name="com.android.settings.PRIMARY_PROFILE_CONTROLLED"
+                       android:value="true" />
+        </activity>
+
         <!-- Conditional receivers, only enabled during silenced state, default off-->
         <receiver
             android:name=".dashboard.conditional.HotspotCondition$Receiver"
index 9d2f1f0..86a6195 100644 (file)
     <!-- [CHAR LIMIT=100] Notification Importance slider: max importance level description -->
     <string name="notification_importance_max">Urgent: Peek onto the screen and make sound</string>
 
+    <!-- Default Apps > Default notification assistant -->
+    <string name="default_notification_assistant">Notification assistant</string>
+
     <!-- Sound & notification > Advanced section: Title for managing notification listeners option. [CHAR LIMIT=30] -->
     <string name="manage_notification_access_title">Notification access</string>
 
index d5f9de0..a38ef4a 100644 (file)
@@ -49,4 +49,8 @@
             settings:keywords="@string/keywords_more_default_sms_app"
             />
 
+    <com.android.settings.applications.DefaultNotificationAssistantPreference
+            android:key="default_notification_asst_app"
+            android:title="@string/default_notification_assistant" />
+
 </PreferenceScreen>
index c480d5a..4d24d7f 100644 (file)
@@ -18,6 +18,7 @@ package com.android.settings;
 
 import android.app.Activity;
 import android.app.AlertDialog;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.pm.ApplicationInfo;
@@ -131,6 +132,48 @@ public class AppListPreference extends CustomListPreference {
         }
     }
 
+    public void setComponentNames(ComponentName[] componentNames, ComponentName defaultCN) {
+        // Look up all package names in PackageManager. Skip ones we can't find.
+        PackageManager pm = getContext().getPackageManager();
+        final int entryCount = componentNames.length + (mShowItemNone ? 1 : 0);
+        List<CharSequence> applicationNames = new ArrayList<>(entryCount);
+        List<CharSequence> validatedComponentNames = new ArrayList<>(entryCount);
+        List<Drawable> entryDrawables = new ArrayList<>(entryCount);
+        int selectedIndex = -1;
+        for (int i = 0; i < componentNames.length; i++) {
+            try {
+                ApplicationInfo appInfo = pm.getApplicationInfo(
+                        componentNames[i].getPackageName().toString(), 0);
+                applicationNames.add(appInfo.loadLabel(pm));
+                validatedComponentNames.add(componentNames[i].flattenToString());
+                entryDrawables.add(appInfo.loadIcon(pm));
+                if (defaultCN != null && componentNames[i].equals(defaultCN)) {
+                    selectedIndex = i;
+                }
+            } catch (NameNotFoundException e) {
+                // Skip unknown packages.
+            }
+        }
+
+        if (mShowItemNone) {
+            applicationNames.add(
+                    getContext().getResources().getText(R.string.app_list_preference_none));
+            validatedComponentNames.add(ITEM_NONE_VALUE);
+            entryDrawables.add(getContext().getDrawable(R.drawable.ic_remove_circle));
+        }
+
+        setEntries(applicationNames.toArray(new CharSequence[applicationNames.size()]));
+        setEntryValues(
+                validatedComponentNames.toArray(new CharSequence[validatedComponentNames.size()]));
+        mEntryDrawables = entryDrawables.toArray(new Drawable[entryDrawables.size()]);
+
+        if (selectedIndex != -1) {
+            setValueIndex(selectedIndex);
+        } else {
+            setValue(null);
+        }
+    }
+
     protected ListAdapter createListAdapter() {
         final String selectedValue = getValue();
         final boolean selectedNone = selectedValue == null ||
index ce37c14..645915a 100644 (file)
@@ -24,7 +24,7 @@ import android.support.v14.preference.ListPreferenceDialogFragment;
 import android.support.v7.preference.ListPreference;
 import android.util.AttributeSet;
 
-public class CustomListPreference extends ListPreference{
+public class CustomListPreference extends ListPreference {
 
     public CustomListPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
index 149ef45..edd0b4c 100644 (file)
@@ -121,6 +121,7 @@ public class Settings extends SettingsActivity {
     public static class WriteSettingsActivity extends SettingsActivity { /* empty */ }
     public static class AppDrawOverlaySettingsActivity extends SettingsActivity { /* empty */ }
     public static class AppWriteSettingsActivity extends SettingsActivity { /* empty */ }
+    public static class ManageDefaultAppsActivity extends SettingsActivity { /* empty */ }
 
     // Categories.
     public static class WirelessSettings extends SettingsActivity { /* empty */ }
index 94379b3..4d9e2f0 100644 (file)
@@ -61,6 +61,7 @@ import com.android.settings.applications.DrawOverlayDetails;
 import com.android.settings.applications.InstalledAppDetails;
 import com.android.settings.applications.ManageApplications;
 import com.android.settings.applications.ManageAssist;
+import com.android.settings.applications.ManageDefaultApps;
 import com.android.settings.applications.ProcessStatsSummary;
 import com.android.settings.applications.ProcessStatsUi;
 import com.android.settings.applications.UsageAccessDetails;
@@ -306,6 +307,7 @@ public class SettingsActivity extends SettingsDrawerActivity
             ProcessStatsSummary.class.getName(),
             DrawOverlayDetails.class.getName(),
             WriteSettingsDetails.class.getName(),
+            ManageDefaultApps.class.getName(),
     };
 
 
diff --git a/src/com/android/settings/applications/DefaultNotificationAssistantPreference.java b/src/com/android/settings/applications/DefaultNotificationAssistantPreference.java
new file mode 100644 (file)
index 0000000..20c1a9e
--- /dev/null
@@ -0,0 +1,111 @@
+/**
+ * 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.AppListPreference;
+
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.provider.Settings;
+import android.service.notification.NotificationAssistantService;
+import android.util.AttributeSet;
+import android.util.Slog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.android.settings.R;
+import com.android.settings.notification.ManagedServiceSettings;
+
+public class DefaultNotificationAssistantPreference extends AppListPreference {
+    private static final String TAG = "DefaultNotiAssist";
+
+    private PackageManager mPm;
+    private final ManagedServiceSettings.Config mConfig;
+    private final Context mContext;
+
+    public DefaultNotificationAssistantPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        mContext = context;
+        mPm = context.getPackageManager();
+        mConfig = getConfig();
+        setShowItemNone(true);
+        updateList(getServices());
+    }
+
+    @Override
+    protected boolean persistString(String value) {
+        Settings.Secure.putString(mContext.getContentResolver(), mConfig.setting, value);
+        setSummary(getEntry());
+        return true;
+    }
+
+    private void updateList(List<ServiceInfo> services) {
+        final ComponentName[] assistants = new ComponentName[services.size()];
+        for (int i = 0; i < services.size(); i++) {
+            assistants[i] = new ComponentName(services.get(i).packageName, services.get(i).name);
+        }
+        final String assistant =
+                Settings.Secure.getString(mContext.getContentResolver(), mConfig.setting);
+        setComponentNames(assistants, assistant == null ? null
+                : ComponentName.unflattenFromString(assistant));
+    }
+
+    private List<ServiceInfo> getServices() {
+        List<ServiceInfo> services = new ArrayList<>();
+        final int user = ActivityManager.getCurrentUser();
+
+        List<ResolveInfo> installedServices = mPm.queryIntentServicesAsUser(
+                new Intent(mConfig.intentAction),
+                PackageManager.GET_SERVICES | PackageManager.GET_META_DATA,
+                user);
+
+        for (int i = 0, count = installedServices.size(); i < count; i++) {
+            ResolveInfo resolveInfo = installedServices.get(i);
+            ServiceInfo info = resolveInfo.serviceInfo;
+
+            if (!mConfig.permission.equals(info.permission)) {
+                Slog.w(mConfig.tag, "Skipping " + mConfig.noun + " service "
+                        + info.packageName + "/" + info.name
+                        + ": it does not require the permission "
+                        + mConfig.permission);
+                continue;
+            }
+            services.add(info);
+        }
+        return services;
+    }
+
+    private ManagedServiceSettings.Config getConfig() {
+        final ManagedServiceSettings.Config c = new ManagedServiceSettings.Config();
+        c.tag = TAG;
+        c.setting = Settings.Secure.ENABLED_NOTIFICATION_ASSISTANT;
+        c.intentAction = NotificationAssistantService.SERVICE_INTERFACE;
+        c.permission = android.Manifest.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE;
+        c.noun = "notification assistant";
+        c.warningDialogTitle = R.string.notification_listener_security_warning_title;
+        c.warningDialogSummary = R.string.notification_listener_security_warning_summary;
+        c.emptyText = R.string.no_notification_listeners;
+        return c;
+    }
+}
index 401e650..56c7b69 100644 (file)
@@ -169,14 +169,14 @@ public abstract class ManagedServiceSettings extends EmptyTextSettings {
         }
     }
 
-    protected static class Config {
-        String tag;
-        String setting;
-        String intentAction;
-        String permission;
-        String noun;
-        int warningDialogTitle;
-        int warningDialogSummary;
-        int emptyText;
+    public static class Config {
+        public String tag;
+        public String setting;
+        public String intentAction;
+        public String permission;
+        public String noun;
+        public int warningDialogTitle;
+        public int warningDialogSummary;
+        public int emptyText;
     }
 }