OSDN Git Service

Do not allow draw on top for App notification settings
[android-x86/packages-apps-Settings.git] / src / com / android / settings / notification / AppNotificationSettings.java
1 /*
2  * Copyright (C) 2014 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 static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
20
21 import android.app.NotificationChannel;
22 import android.app.NotificationChannelGroup;
23 import android.content.Context;
24 import android.os.AsyncTask;
25 import android.os.Bundle;
26 import android.support.v14.preference.SwitchPreference;
27 import android.support.v7.preference.Preference;
28 import android.support.v7.preference.PreferenceCategory;
29 import android.support.v7.preference.PreferenceGroup;
30 import android.support.v7.preference.PreferenceScreen;
31 import android.text.TextUtils;
32 import android.util.Log;
33 import android.view.Window;
34 import android.view.WindowManager;
35
36 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
37 import com.android.internal.widget.LockPatternUtils;
38 import com.android.settings.R;
39 import com.android.settings.widget.MasterCheckBoxPreference;
40 import com.android.settingslib.RestrictedSwitchPreference;
41 import com.android.settingslib.core.AbstractPreferenceController;
42
43 import java.util.ArrayList;
44 import java.util.Collections;
45 import java.util.Comparator;
46 import java.util.List;
47
48 /** These settings are per app, so should not be returned in global search results. */
49 public class AppNotificationSettings extends NotificationSettingsBase {
50     private static final String TAG = "AppNotificationSettings";
51     private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
52
53     private static String KEY_GENERAL_CATEGORY = "categories";
54     private static String KEY_ADVANCED_CATEGORY = "app_advanced";
55     private static String KEY_BADGE = "badge";
56     private static String KEY_APP_LINK = "app_link";
57
58     private List<NotificationChannelGroup> mChannelGroupList;
59
60     @Override
61     public int getMetricsCategory() {
62         return MetricsEvent.NOTIFICATION_APP_NOTIFICATION;
63     }
64
65     @Override
66     public void onCreate(Bundle savedInstanceState) {
67         super.onCreate(savedInstanceState);
68         final PreferenceScreen screen = getPreferenceScreen();
69         if (mShowLegacyChannelConfig && screen != null) {
70             // if showing legacy settings, pull advanced settings out of the advanced category
71             Preference badge = findPreference(KEY_BADGE);
72             Preference appLink = findPreference(KEY_APP_LINK);
73             removePreference(KEY_ADVANCED_CATEGORY);
74             if (badge != null) {
75                 screen.addPreference(badge);
76
77             }
78             if (appLink != null) {
79                 screen.addPreference(appLink);
80             }
81         }
82     }
83
84     @Override
85     public void onResume() {
86         super.onResume();
87
88         getActivity().getWindow().addPrivateFlags(PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS);
89         android.util.EventLog.writeEvent(0x534e4554, "119115683", -1, "");
90
91         if (mUid < 0 || TextUtils.isEmpty(mPkg) || mPkgInfo == null) {
92             Log.w(TAG, "Missing package or uid or packageinfo");
93             finish();
94             return;
95         }
96
97         if (!mShowLegacyChannelConfig) {
98             // Load channel settings
99             new AsyncTask<Void, Void, Void>() {
100                 @Override
101                 protected Void doInBackground(Void... unused) {
102                     mChannelGroupList = mBackend.getGroups(mPkg, mUid).getList();
103                     Collections.sort(mChannelGroupList, mChannelGroupComparator);
104                     return null;
105                 }
106
107                 @Override
108                 protected void onPostExecute(Void unused) {
109                     if (getHost() == null) {
110                         return;
111                     }
112                     populateList();
113                 }
114             }.execute();
115         }
116
117         for (NotificationPreferenceController controller : mControllers) {
118             controller.onResume(mAppRow, mChannel, mChannelGroup, mSuspendedAppsAdmin);
119             controller.displayPreference(getPreferenceScreen());
120         }
121         updatePreferenceStates();
122     }
123
124     @Override
125     public void onPause() {
126         super.onPause();
127         final Window window = getActivity().getWindow();
128         final WindowManager.LayoutParams attrs = window.getAttributes();
129         attrs.privateFlags &= ~PRIVATE_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
130         window.setAttributes(attrs);
131     }
132
133     @Override
134     protected String getLogTag() {
135         return TAG;
136     }
137
138     @Override
139     protected int getPreferenceScreenResId() {
140         return R.xml.app_notification_settings;
141     }
142
143     @Override
144     protected List<AbstractPreferenceController> createPreferenceControllers(Context context) {
145         mControllers = new ArrayList<>();
146         mControllers.add(new HeaderPreferenceController(context, this));
147         mControllers.add(new BlockPreferenceController(context, mImportanceListener, mBackend));
148         mControllers.add(new BadgePreferenceController(context, mBackend));
149         mControllers.add(new AllowSoundPreferenceController(
150                 context, mImportanceListener, mBackend));
151         mControllers.add(new ImportancePreferenceController(
152                 context, mImportanceListener, mBackend));
153         mControllers.add(new SoundPreferenceController(context, this,
154                 mImportanceListener, mBackend));
155         mControllers.add(new LightsPreferenceController(context, mBackend));
156         mControllers.add(new VibrationPreferenceController(context, mBackend));
157         mControllers.add(new VisibilityPreferenceController(context, new LockPatternUtils(context),
158                 mBackend));
159         mControllers.add(new DndPreferenceController(context, mBackend));
160         mControllers.add(new AppLinkPreferenceController(context));
161         mControllers.add(new DescriptionPreferenceController(context));
162         mControllers.add(new NotificationsOffPreferenceController(context));
163         mControllers.add(new DeletedChannelsPreferenceController(context, mBackend));
164         return new ArrayList<>(mControllers);
165     }
166
167     private void populateList() {
168         if (!mDynamicPreferences.isEmpty()) {
169             for (Preference p : mDynamicPreferences) {
170                 getPreferenceScreen().removePreference(p);
171             }
172             mDynamicPreferences.clear();
173         }
174         if (mChannelGroupList.isEmpty()) {
175             PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
176             groupCategory.setTitle(R.string.notification_channels);
177             groupCategory.setKey(KEY_GENERAL_CATEGORY);
178             getPreferenceScreen().addPreference(groupCategory);
179             mDynamicPreferences.add(groupCategory);
180
181             Preference empty = new Preference(getPrefContext());
182             empty.setTitle(R.string.no_channels);
183             empty.setEnabled(false);
184             groupCategory.addPreference(empty);
185         } else {
186             populateGroupList();
187             mImportanceListener.onImportanceChanged();
188         }
189     }
190
191     private void populateGroupList() {
192         for (NotificationChannelGroup group : mChannelGroupList) {
193             PreferenceCategory groupCategory = new PreferenceCategory(getPrefContext());
194             groupCategory.setOrderingAsAdded(true);
195             getPreferenceScreen().addPreference(groupCategory);
196             mDynamicPreferences.add(groupCategory);
197             if (group.getId() == null) {
198                 if (mChannelGroupList.size() > 1) {
199                     groupCategory.setTitle(R.string.notification_channels_other);
200                 }
201                 groupCategory.setKey(KEY_GENERAL_CATEGORY);
202             } else {
203                 groupCategory.setTitle(group.getName());
204                 groupCategory.setKey(group.getId());
205                 populateGroupToggle(groupCategory, group);
206             }
207             if (!group.isBlocked()) {
208                 final List<NotificationChannel> channels = group.getChannels();
209                 Collections.sort(channels, mChannelComparator);
210                 int N = channels.size();
211                 for (int i = 0; i < N; i++) {
212                     final NotificationChannel channel = channels.get(i);
213                     populateSingleChannelPrefs(groupCategory, channel, group.isBlocked());
214                 }
215             }
216         }
217     }
218
219     protected void populateGroupToggle(final PreferenceGroup parent,
220             NotificationChannelGroup group) {
221         RestrictedSwitchPreference preference = new RestrictedSwitchPreference(getPrefContext());
222         preference.setTitle(R.string.notification_switch_label);
223         preference.setEnabled(mSuspendedAppsAdmin == null
224                 && isChannelGroupBlockable(group));
225         preference.setChecked(!group.isBlocked());
226         preference.setOnPreferenceClickListener(preference1 -> {
227             final boolean allowGroup = ((SwitchPreference) preference1).isChecked();
228             group.setBlocked(!allowGroup);
229             mBackend.updateChannelGroup(mAppRow.pkg, mAppRow.uid, group);
230
231             onGroupBlockStateChanged(group);
232             return true;
233         });
234
235         parent.addPreference(preference);
236     }
237
238     private Comparator<NotificationChannelGroup> mChannelGroupComparator =
239             new Comparator<NotificationChannelGroup>() {
240
241                 @Override
242                 public int compare(NotificationChannelGroup left, NotificationChannelGroup right) {
243                     // Non-grouped channels (in placeholder group with a null id) come last
244                     if (left.getId() == null && right.getId() != null) {
245                         return 1;
246                     } else if (right.getId() == null && left.getId() != null) {
247                         return -1;
248                     }
249                     return left.getId().compareTo(right.getId());
250                 }
251             };
252
253     protected void onGroupBlockStateChanged(NotificationChannelGroup group) {
254         if (group == null) {
255             return;
256         }
257         PreferenceGroup groupGroup = (
258                 PreferenceGroup) getPreferenceScreen().findPreference(group.getId());
259
260         if (groupGroup != null) {
261             if (group.isBlocked()) {
262                 List<Preference> toRemove = new ArrayList<>();
263                 int childCount = groupGroup.getPreferenceCount();
264                 for (int i = 0; i < childCount; i++) {
265                     Preference pref = groupGroup.getPreference(i);
266                     if (pref instanceof MasterCheckBoxPreference) {
267                         toRemove.add(pref);
268                     }
269                 }
270                 for (Preference pref : toRemove) {
271                     groupGroup.removePreference(pref);
272                 }
273             } else {
274                 final List<NotificationChannel> channels = group.getChannels();
275                 Collections.sort(channels, mChannelComparator);
276                 int N = channels.size();
277                 for (int i = 0; i < N; i++) {
278                     final NotificationChannel channel = channels.get(i);
279                     populateSingleChannelPrefs(groupGroup, channel, group.isBlocked());
280                 }
281             }
282         }
283     }
284
285 }