• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.notification;
18 
19 import android.content.ComponentName;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.pm.PackageManager;
23 import android.content.pm.ResolveInfo;
24 import android.os.UserHandle;
25 import android.os.UserManager;
26 import android.provider.Settings;
27 import android.service.notification.NotificationAssistantService;
28 
29 import androidx.fragment.app.Fragment;
30 import androidx.preference.Preference;
31 
32 import com.android.settings.R;
33 import com.android.settings.core.TogglePreferenceController;
34 import com.android.settingslib.PrimarySwitchPreference;
35 
36 import com.google.common.annotations.VisibleForTesting;
37 
38 import java.util.List;
39 
40 public class NotificationAssistantPreferenceController extends TogglePreferenceController {
41     private static final String TAG = "NASPreferenceController";
42     static final String KEY_NAS = "notification_assistant";
43 
44     private static final int AVAILABLE = 1;
45     private final UserManager mUserManager;
46     private final PackageManager mPackageManager;
47     private Fragment mFragment;
48     private int mUserId = UserHandle.myUserId();
49 
50     @VisibleForTesting
51     protected NotificationBackend mNotificationBackend;
52     private ComponentName mDefaultNASComponent;
53     private Intent mNASSettingIntent;
54 
NotificationAssistantPreferenceController(Context context)55     public NotificationAssistantPreferenceController(Context context) {
56         super(context, KEY_NAS);
57         mUserManager = UserManager.get(context);
58         mNotificationBackend = new NotificationBackend();
59         mPackageManager = context.getPackageManager();
60         getDefaultNASIntent();
61     }
62 
63 
64     @Override
getAvailabilityStatus()65     public int getAvailabilityStatus() {
66         return AVAILABLE;
67     }
68 
69     @Override
isChecked()70     public boolean isChecked() {
71         ComponentName acn = mNotificationBackend.getAllowedNotificationAssistant();
72         return (acn != null && acn.equals(mDefaultNASComponent));
73     }
74 
75     @Override
setChecked(boolean isChecked)76     public boolean setChecked(boolean isChecked) {
77         ComponentName cn = isChecked
78                 ? mDefaultNASComponent : null;
79         if (isChecked) {
80             if (mFragment == null) {
81                 throw new IllegalStateException("No fragment to start activity");
82             }
83             showDialog(cn);
84             return false;
85         } else {
86             setNotificationAssistantGranted(null);
87             return true;
88         }
89     }
90 
91     @Override
getSliceHighlightMenuRes()92     public int getSliceHighlightMenuRes() {
93         return R.string.menu_key_notifications;
94     }
95 
setNotificationAssistantGranted(ComponentName cn)96     protected void setNotificationAssistantGranted(ComponentName cn) {
97         if (Settings.Secure.getIntForUser(mContext.getContentResolver(),
98                 Settings.Secure.NAS_SETTINGS_UPDATED, 0, mUserId) == 0) {
99             mNotificationBackend.setNASMigrationDoneAndResetDefault(mUserId, cn != null);
100         }
101         mNotificationBackend.setNotificationAssistantGranted(cn);
102     }
103 
showDialog(ComponentName cn)104     protected void showDialog(ComponentName cn) {
105         NotificationAssistantDialogFragment dialogFragment =
106                 NotificationAssistantDialogFragment.newInstance(mFragment, cn);
107         dialogFragment.show(mFragment.getFragmentManager(), TAG);
108     }
109 
setFragment(Fragment fragment)110     public void setFragment(Fragment fragment) {
111         mFragment = fragment;
112     }
113 
114     @VisibleForTesting
setBackend(NotificationBackend backend)115     void setBackend(NotificationBackend backend) {
116         mNotificationBackend = backend;
117     }
118 
119     @VisibleForTesting
getDefaultNASIntent()120     void getDefaultNASIntent() {
121         mDefaultNASComponent = mNotificationBackend.getDefaultNotificationAssistant();
122         if (mDefaultNASComponent != null) {
123             mNASSettingIntent = new Intent(
124                     NotificationAssistantService.ACTION_NOTIFICATION_ASSISTANT_DETAIL_SETTINGS);
125             mNASSettingIntent.setPackage(mDefaultNASComponent.getPackageName());
126             mNASSettingIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
127         }
128     }
129 
130     @Override
isSliceable()131     public boolean isSliceable() {
132         return (mFragment != null && mFragment instanceof ConfigureNotificationSettings);
133     }
134 
isNASSettingActivityAvailable()135     private boolean isNASSettingActivityAvailable() {
136         final List<ResolveInfo> resolved = mPackageManager.queryIntentActivities(mNASSettingIntent,
137                 PackageManager.ResolveInfoFlags.of(PackageManager.MATCH_ALL));
138         return (resolved != null && !resolved.isEmpty());
139     }
140 
141     @Override
updateState(Preference preference)142     public void updateState(Preference preference) {
143         super.updateState(preference);
144         if (mDefaultNASComponent == null) {
145             preference.setEnabled(false);
146             ((PrimarySwitchPreference) preference).setSwitchEnabled(false);
147         } else if (isNASSettingActivityAvailable()) {
148             preference.setIntent(mNASSettingIntent);
149         } else {
150             // Cannot find settings activity from the default NAS app
151             preference.setIntent(null);
152             preference.setOnPreferenceClickListener(
153                     preference1 -> {
154                         onPreferenceChange(preference1, !isChecked());
155                         ((PrimarySwitchPreference) preference1).setChecked(isChecked());
156                         return true;
157                     }
158             );
159         }
160     }
161 }
162