1 /* 2 * Copyright (C) 2015 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 com.android.settings.SettingsActivity.EXTRA_FRAGMENT_ARG_KEY; 20 21 import android.app.Activity; 22 import android.app.Application; 23 import android.app.settings.SettingsEnums; 24 import android.app.usage.IUsageStatsManager; 25 import android.content.Context; 26 import android.content.Intent; 27 import android.os.Bundle; 28 import android.os.ServiceManager; 29 import android.os.UserHandle; 30 import android.os.UserManager; 31 import android.provider.SearchIndexableResource; 32 import android.text.TextUtils; 33 34 import androidx.annotation.VisibleForTesting; 35 import androidx.fragment.app.Fragment; 36 import androidx.preference.Preference; 37 import androidx.preference.PreferenceCategory; 38 import androidx.preference.PreferenceScreen; 39 40 import com.android.settings.R; 41 import com.android.settings.RingtonePreference; 42 import com.android.settings.core.OnActivityResultListener; 43 import com.android.settings.dashboard.DashboardFragment; 44 import com.android.settings.dashboard.SummaryLoader; 45 import com.android.settings.search.BaseSearchIndexProvider; 46 import com.android.settings.search.Indexable; 47 import com.android.settingslib.core.AbstractPreferenceController; 48 import com.android.settingslib.core.lifecycle.Lifecycle; 49 import com.android.settingslib.search.SearchIndexable; 50 51 import java.util.ArrayList; 52 import java.util.Arrays; 53 import java.util.List; 54 55 @SearchIndexable 56 public class ConfigureNotificationSettings extends DashboardFragment implements 57 OnActivityResultListener { 58 private static final String TAG = "ConfigNotiSettings"; 59 60 @VisibleForTesting 61 static final String KEY_SWIPE_DOWN = "gesture_swipe_down_fingerprint_notifications"; 62 static final String KEY_LOCKSCREEN = "lock_screen_notifications"; 63 64 private static final String KEY_NOTI_DEFAULT_RINGTONE = "notification_default_ringtone"; 65 private static final int REQUEST_CODE = 200; 66 private static final String SELECTED_PREFERENCE_KEY = "selected_preference"; 67 private static final String KEY_ADVANCED_CATEGORY = "configure_notifications_advanced"; 68 69 private RingtonePreference mRequestPreference; 70 71 @Override getMetricsCategory()72 public int getMetricsCategory() { 73 return SettingsEnums.CONFIGURE_NOTIFICATION; 74 } 75 76 @Override getLogTag()77 protected String getLogTag() { 78 return TAG; 79 } 80 81 @Override getPreferenceScreenResId()82 protected int getPreferenceScreenResId() { 83 return R.xml.configure_notification_settings; 84 } 85 86 @Override createPreferenceControllers(Context context)87 protected List<AbstractPreferenceController> createPreferenceControllers(Context context) { 88 final Activity activity = getActivity(); 89 final Application app; 90 if (activity != null) { 91 app = activity.getApplication(); 92 } else { 93 app = null; 94 } 95 return buildPreferenceControllers(context, app, this); 96 } 97 buildPreferenceControllers(Context context, Application app, Fragment host)98 private static List<AbstractPreferenceController> buildPreferenceControllers(Context context, 99 Application app, Fragment host) { 100 final List<AbstractPreferenceController> controllers = new ArrayList<>(); 101 controllers.add(new RecentNotifyingAppsPreferenceController( 102 context, new NotificationBackend(), IUsageStatsManager.Stub.asInterface( 103 ServiceManager.getService(Context.USAGE_STATS_SERVICE)), 104 context.getSystemService(UserManager.class), app, host)); 105 controllers.add(new ShowOnLockScreenNotificationPreferenceController( 106 context, KEY_LOCKSCREEN)); 107 controllers.add(new NotificationRingtonePreferenceController(context) { 108 @Override 109 public String getPreferenceKey() { 110 return KEY_NOTI_DEFAULT_RINGTONE; 111 } 112 113 }); 114 return controllers; 115 } 116 117 @Override onCreate(Bundle icicle)118 public void onCreate(Bundle icicle) { 119 super.onCreate(icicle); 120 final PreferenceScreen screen = getPreferenceScreen(); 121 final Bundle arguments = getArguments(); 122 123 if (screen == null) { 124 return; 125 } 126 if (arguments != null) { 127 final String highlightKey = arguments.getString(EXTRA_FRAGMENT_ARG_KEY); 128 if (!TextUtils.isEmpty(highlightKey)) { 129 final PreferenceCategory advancedCategory = 130 screen.findPreference(KEY_ADVANCED_CATEGORY); 131 // Has highlight row - expand everything 132 advancedCategory.setInitialExpandedChildrenCount(Integer.MAX_VALUE); 133 scrollToPreference(advancedCategory); 134 } 135 } 136 } 137 138 @Override onPreferenceTreeClick(Preference preference)139 public boolean onPreferenceTreeClick(Preference preference) { 140 if (preference instanceof RingtonePreference) { 141 mRequestPreference = (RingtonePreference) preference; 142 mRequestPreference.onPrepareRingtonePickerIntent(mRequestPreference.getIntent()); 143 getActivity().startActivityForResultAsUser( 144 mRequestPreference.getIntent(), 145 REQUEST_CODE, 146 null, 147 UserHandle.of(mRequestPreference.getUserId())); 148 return true; 149 } 150 return super.onPreferenceTreeClick(preference); 151 } 152 153 @Override onActivityResult(int requestCode, int resultCode, Intent data)154 public void onActivityResult(int requestCode, int resultCode, Intent data) { 155 if (mRequestPreference != null) { 156 mRequestPreference.onActivityResult(requestCode, resultCode, data); 157 mRequestPreference = null; 158 } 159 } 160 161 @Override onSaveInstanceState(Bundle outState)162 public void onSaveInstanceState(Bundle outState) { 163 super.onSaveInstanceState(outState); 164 if (mRequestPreference != null) { 165 outState.putString(SELECTED_PREFERENCE_KEY, mRequestPreference.getKey()); 166 } 167 } 168 169 /** 170 * For summary 171 */ 172 static class SummaryProvider implements SummaryLoader.SummaryProvider { 173 174 private final Context mContext; 175 private final SummaryLoader mSummaryLoader; 176 private NotificationBackend mBackend; 177 SummaryProvider(Context context, SummaryLoader summaryLoader)178 public SummaryProvider(Context context, SummaryLoader summaryLoader) { 179 mContext = context; 180 mSummaryLoader = summaryLoader; 181 mBackend = new NotificationBackend(); 182 } 183 184 @VisibleForTesting setBackend(NotificationBackend backend)185 protected void setBackend(NotificationBackend backend) { 186 mBackend = backend; 187 } 188 189 @Override setListening(boolean listening)190 public void setListening(boolean listening) { 191 if (!listening) { 192 return; 193 } 194 int blockedAppCount = mBackend.getBlockedAppCount(); 195 if (blockedAppCount == 0) { 196 mSummaryLoader.setSummary(this, 197 mContext.getText(R.string.app_notification_listing_summary_zero)); 198 } else { 199 mSummaryLoader.setSummary(this, 200 mContext.getResources().getQuantityString( 201 R.plurals.app_notification_listing_summary_others, 202 blockedAppCount, blockedAppCount)); 203 } 204 } 205 } 206 207 public static final SummaryLoader.SummaryProviderFactory SUMMARY_PROVIDER_FACTORY = 208 new SummaryLoader.SummaryProviderFactory() { 209 @Override 210 public SummaryLoader.SummaryProvider createSummaryProvider(Activity activity, 211 SummaryLoader summaryLoader) { 212 return new ConfigureNotificationSettings.SummaryProvider( 213 activity, summaryLoader); 214 } 215 }; 216 217 /** 218 * For Search. 219 */ 220 public static final Indexable.SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = 221 new BaseSearchIndexProvider() { 222 @Override 223 public List<SearchIndexableResource> getXmlResourcesToIndex( 224 Context context, boolean enabled) { 225 final SearchIndexableResource sir = new SearchIndexableResource(context); 226 sir.xmlResId = R.xml.configure_notification_settings; 227 return Arrays.asList(sir); 228 } 229 230 @Override 231 public List<AbstractPreferenceController> createPreferenceControllers( 232 Context context) { 233 return buildPreferenceControllers(context, null, null); 234 } 235 236 @Override 237 public List<String> getNonIndexableKeys(Context context) { 238 final List<String> keys = super.getNonIndexableKeys(context); 239 keys.add(KEY_SWIPE_DOWN); 240 return keys; 241 } 242 }; 243 } 244