ZenModeAutomationSettings.java revision 39b467482d1bf256a111c757e9b7621c6f523271
1d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock/* 2d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * Copyright (C) 2015 The Android Open Source Project 3d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * 4d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * Licensed under the Apache License, Version 2.0 (the "License"); 5d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * you may not use this file except in compliance with the License. 6d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * You may obtain a copy of the License at 7d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * 8d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * http://www.apache.org/licenses/LICENSE-2.0 9d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * 10d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * Unless required by applicable law or agreed to in writing, software 11d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * distributed under the License is distributed on an "AS IS" BASIS, 12d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * See the License for the specific language governing permissions and 14d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock * limitations under the License. 15d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock */ 16d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock 17d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlockpackage com.android.settings.notification; 18d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock 19cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynoldsimport android.app.AlertDialog; 207d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynoldsimport android.app.AutomaticZenRule; 217d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynoldsimport android.app.NotificationManager; 22c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlockimport android.content.ComponentName; 23cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynoldsimport android.content.Context; 24cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynoldsimport android.content.DialogInterface; 2545fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlockimport android.content.Intent; 26cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynoldsimport android.content.pm.ApplicationInfo; 27cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynoldsimport android.content.pm.PackageManager; 28c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlockimport android.content.pm.ServiceInfo; 29beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlockimport android.content.res.Resources; 30cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynoldsimport android.graphics.drawable.Drawable; 31cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynoldsimport android.os.AsyncTask; 32d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlockimport android.os.Bundle; 33c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlockimport android.provider.Settings; 34c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlockimport android.service.notification.ConditionProviderService; 35d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlockimport android.service.notification.ZenModeConfig; 3639b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference; 3739b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.Preference.OnPreferenceClickListener; 3839b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceScreen; 3939b467482d1bf256a111c757e9b7621c6f523271Jason Monkimport android.support.v7.preference.PreferenceViewHolder; 40d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlockimport android.util.Log; 41cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynoldsimport android.view.View; 42d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock 43d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlockimport com.android.internal.logging.MetricsLogger; 44d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlockimport com.android.settings.R; 45c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlockimport com.android.settings.notification.ManagedServiceSettings.Config; 46d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock 47cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynoldsimport java.lang.ref.WeakReference; 48f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlockimport java.util.Arrays; 49f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlockimport java.util.Comparator; 50c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlockimport java.util.List; 517d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynoldsimport java.util.Objects; 52d333a7d9f10500ec45377e099955031017d6a158John Spurlock 5345fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlockpublic class ZenModeAutomationSettings extends ZenModeSettingsBase { 54d333a7d9f10500ec45377e099955031017d6a158John Spurlock 55c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock static final Config CONFIG = getConditionProviderConfig(); 56c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock 57cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds private PackageManager mPm; 58c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock private ServiceListing mServiceListing; 59c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock 60d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock @Override 61d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock public void onCreate(Bundle icicle) { 62d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock super.onCreate(icicle); 63d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock addPreferencesFromResource(R.xml.zen_mode_automation_settings); 64c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock mServiceListing = new ServiceListing(mContext, CONFIG); 65c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock mServiceListing.addCallback(mServiceListingCallback); 66c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock mServiceListing.reload(); 67c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock mServiceListing.setListening(true); 68cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds mPm = mContext.getPackageManager(); 6945fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock } 70d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock 71c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock @Override 72c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock public void onDestroy() { 73c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock super.onDestroy(); 74c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock mServiceListing.setListening(false); 75c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock mServiceListing.removeCallback(mServiceListingCallback); 7645fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock } 77d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock 7845fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock @Override 79c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock protected void onZenModeChanged() { 80c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock // don't care 81c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock } 82c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock 83c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock @Override 84c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock protected void onZenModeConfigChanged() { 85c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock updateControls(); 86c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock } 87c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock 88c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock @Override 89c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock public void onResume() { 90c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock super.onResume(); 91c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock updateControls(); 92c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock } 93c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock 9445fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock private void showAddRuleDialog() { 95f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds new ZenRuleSelectionDialog(mContext, mServiceListing) { 96f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds @Override 97f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds public void onSystemRuleSelected(ZenRuleInfo ri) { 98f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds showNameRuleDialog(ri); 99f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds } 100f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds 101f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds @Override 102f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds public void onExternalRuleSelected(ZenRuleInfo ri) { 103f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds Intent intent = new Intent().setComponent(ri.configurationActivity); 104f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds startActivity(intent); 105f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds } 106f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds }.show(); 107f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds } 108f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds 109f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds private void showNameRuleDialog(final ZenRuleInfo ri) { 11025cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds new ZenRuleNameDialog(mContext, null) { 111d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock @Override 112f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds public void onOk(String ruleName) { 1131b6ffba9e69dc1926e3c4cbcb52d1844c6ccaa32Chris Wren MetricsLogger.action(mContext, MetricsLogger.ACTION_ZEN_ADD_RULE_OK); 114f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds AutomaticZenRule rule = new AutomaticZenRule(ruleName, ri.serviceComponent, 115f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds ri.defaultConditionId, NotificationManager.INTERRUPTION_FILTER_PRIORITY, 116f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds true); 11725cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds AutomaticZenRule savedRule = addZenRule(rule); 11825cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds if (savedRule != null) { 11925cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds startActivity(getRuleIntent(ri.settingsAction, null, savedRule.getId())); 120d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock } 121d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock } 12245fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock }.show(); 123d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock } 124d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock 12525cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds private void showDeleteRuleDialog(final String ruleId, final String ruleName) { 126cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds new AlertDialog.Builder(mContext) 127cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds .setMessage(getString(R.string.zen_mode_delete_rule_confirmation, ruleName)) 128cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds .setNegativeButton(R.string.cancel, null) 129cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds .setPositiveButton(R.string.zen_mode_delete_rule_button, 130cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds new DialogInterface.OnClickListener() { 131cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds @Override 132cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds public void onClick(DialogInterface dialog, int which) { 133cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds MetricsLogger.action(mContext, MetricsLogger.ACTION_ZEN_DELETE_RULE_OK); 13425cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds removeZenRule(ruleId); 135cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 136cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds }) 137cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds .show(); 138cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 139cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 140f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds private Intent getRuleIntent(String settingsAction, ComponentName configurationActivity, 14125cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds String ruleId) { 142f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds Intent intent = new Intent() 143c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock .addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 14425cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds .putExtra(ConditionProviderService.EXTRA_RULE_ID, ruleId); 145f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds if (configurationActivity != null) { 146f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds intent.setComponent(configurationActivity); 147f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds } else { 148f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds intent.setAction(settingsAction); 149f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds } 150f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds return intent; 151b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock } 152b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock 1537d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds private AutomaticZenRule[] sortedRules() { 1547d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds final AutomaticZenRule[] rt = mRules.toArray(new AutomaticZenRule[mRules.size()]); 155f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock Arrays.sort(rt, RULE_COMPARATOR); 156f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock return rt; 157f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock } 158f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock 159b47b2c3f6af650441f8069b87d0d82549913f7c5John Spurlock private void updateControls() { 16045fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock final PreferenceScreen root = getPreferenceScreen(); 16145fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock root.removeAll(); 1627d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds if (mRules.size() == 0) return; 1637d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds final AutomaticZenRule[] sortedRules = sortedRules(); 1647d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds for (AutomaticZenRule sortedRule : sortedRules) { 16539b467482d1bf256a111c757e9b7621c6f523271Jason Monk root.addPreference(new ZenRulePreference(getPrefContext(), sortedRule)); 166d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock } 16739b467482d1bf256a111c757e9b7621c6f523271Jason Monk final Preference p = new Preference(getPrefContext()); 168f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock p.setIcon(R.drawable.ic_add); 169f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock p.setTitle(R.string.zen_mode_add_rule); 170f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock p.setPersistent(false); 171f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock p.setOnPreferenceClickListener(new OnPreferenceClickListener() { 172f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock @Override 173f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock public boolean onPreferenceClick(Preference preference) { 1741b6ffba9e69dc1926e3c4cbcb52d1844c6ccaa32Chris Wren MetricsLogger.action(mContext, MetricsLogger.ACTION_ZEN_ADD_RULE); 175f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock showAddRuleDialog(); 176f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock return true; 177f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock } 178f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock }); 179f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock root.addPreference(p); 18045fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock } 181d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock 18245fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock @Override 18345fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock protected int getMetricsCategory() { 18445fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock return MetricsLogger.NOTIFICATION_ZEN_MODE_AUTOMATION; 185d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock } 18645fa140b8c6846b4546fdeabebf989ae9102cebbJohn Spurlock 1877d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds private String computeRuleSummary(AutomaticZenRule rule, boolean isSystemRule, 188cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds CharSequence providerLabel) { 1897d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds final String mode = computeZenModeCaption(getResources(), rule.getInterruptionFilter()); 1907d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds final String ruleState = (rule == null || !rule.isEnabled()) 191cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds ? getString(R.string.switch_off_text) 192cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds : getString(R.string.zen_mode_rule_summary_enabled_combination, mode); 193d333a7d9f10500ec45377e099955031017d6a158John Spurlock 194cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds return isSystemRule ? ruleState 195cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds : getString(R.string.zen_mode_rule_summary_provider_combination, 196cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds providerLabel, ruleState); 197d333a7d9f10500ec45377e099955031017d6a158John Spurlock } 198d333a7d9f10500ec45377e099955031017d6a158John Spurlock 199c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock private static Config getConditionProviderConfig() { 200c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock final Config c = new Config(); 201c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock c.tag = TAG; 202c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock c.setting = Settings.Secure.ENABLED_CONDITION_PROVIDERS; 203c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock c.intentAction = ConditionProviderService.SERVICE_INTERFACE; 204c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock c.permission = android.Manifest.permission.BIND_CONDITION_PROVIDER_SERVICE; 205c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock c.noun = "condition provider"; 206c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock return c; 207c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock } 208c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock 209beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock private static String computeZenModeCaption(Resources res, int zenMode) { 210beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock switch (zenMode) { 2117d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds case NotificationManager.INTERRUPTION_FILTER_ALARMS: 212beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock return res.getString(R.string.zen_mode_option_alarms); 2137d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds case NotificationManager.INTERRUPTION_FILTER_PRIORITY: 214beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock return res.getString(R.string.zen_mode_option_important_interruptions); 2157d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds case NotificationManager.INTERRUPTION_FILTER_NONE: 216beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock return res.getString(R.string.zen_mode_option_no_interruptions); 217beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock default: 218beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock return null; 219beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock } 220beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock } 221beff087b3ac3aae4eb120feef81274d7caeafb58John Spurlock 222c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock private final ServiceListing.Callback mServiceListingCallback = new ServiceListing.Callback() { 223c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock @Override 224c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock public void onServicesReloaded(List<ServiceInfo> services) { 225c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock for (ServiceInfo service : services) { 226f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds final ZenRuleInfo ri = getRuleInfo(service); 227c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock if (ri != null && ri.serviceComponent != null 228f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds && Objects.equals(ri.settingsAction, 229f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS)) { 230c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock if (!mServiceListing.isEnabled(ri.serviceComponent)) { 231c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock Log.i(TAG, "Enabling external condition provider: " + ri.serviceComponent); 232c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock mServiceListing.setEnabled(ri.serviceComponent, true); 233c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock } 234c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock } 235c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock } 236c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock } 237c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock }; 238c96a5dcbfc3f37f71e8b3e8b962f9571b1e7ceafJohn Spurlock 239f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds public static ZenRuleInfo getRuleInfo(ServiceInfo si) { 240f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds if (si == null || si.metaData == null) return null; 241f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds final String ruleType = si.metaData.getString(ConditionProviderService.META_DATA_RULE_TYPE); 24225cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds final ComponentName configurationActivity = getSettingsActivity(si); 24325cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds if (ruleType != null && !ruleType.trim().isEmpty() && configurationActivity != null) { 244f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds final ZenRuleInfo ri = new ZenRuleInfo(); 245f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds ri.settingsAction = Settings.ACTION_ZEN_MODE_EXTERNAL_RULE_SETTINGS; 246f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds ri.title = ruleType; 247f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds ri.packageName = si.packageName; 248f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds ri.configurationActivity = getSettingsActivity(si); 249f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds 250f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds return ri; 251f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds } 252f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds return null; 253f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds } 254f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds 255f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds private static ComponentName getSettingsActivity(ServiceInfo si) { 256f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds if (si == null || si.metaData == null) return null; 257f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds final String configurationActivity = 258f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds si.metaData.getString(ConditionProviderService.META_DATA_CONFIGURATION_ACTIVITY); 259f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds if (configurationActivity != null) { 260f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds return ComponentName.unflattenFromString(configurationActivity); 261f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds } 262f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds return null; 263f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds } 264f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds 265cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds // TODO: Sort by creation date, once that data is available. 2667d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds private static final Comparator<AutomaticZenRule> RULE_COMPARATOR = 2677d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds new Comparator<AutomaticZenRule>() { 268f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock @Override 2697d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds public int compare(AutomaticZenRule lhs, AutomaticZenRule rhs) { 270f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock return key(lhs).compareTo(key(rhs)); 271f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock } 272f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock 2737d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds private String key(AutomaticZenRule rule) { 2747d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds final int type = ZenModeConfig.isValidScheduleConditionId(rule.getConditionId()) ? 1 2757d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds : ZenModeConfig.isValidEventConditionId(rule.getConditionId()) ? 2 276f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock : 3; 2777d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds return type + rule.getName(); 278f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock } 279f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock }; 280f57bad7d5b0f9044231fc52351ed27e14013f491John Spurlock 281cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds private class ZenRulePreference extends Preference { 282cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds final String mName; 28325cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds final String mId; 284cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 2857d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds public ZenRulePreference(Context context, final AutomaticZenRule rule) { 286cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds super(context); 287cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 2887d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds mName = rule.getName(); 28925cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds mId = rule.getId(); 290cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 2917d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds final boolean isSchedule = ZenModeConfig.isValidScheduleConditionId( 2927d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds rule.getConditionId()); 2937d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds final boolean isEvent = ZenModeConfig.isValidEventConditionId(rule.getConditionId()); 294cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds final boolean isSystemRule = isSchedule || isEvent; 295cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 296cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds try { 297f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds ApplicationInfo info = mPm.getApplicationInfo(rule.getOwner().getPackageName(), 0); 298cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds LoadIconTask task = new LoadIconTask(this); 299cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds task.execute(info); 300cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds setSummary(computeRuleSummary(rule, isSystemRule, info.loadLabel(mPm))); 301cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } catch (PackageManager.NameNotFoundException e) { 302cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds setIcon(R.drawable.ic_label); 303cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 304cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 3057d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds setTitle(rule.getName()); 306cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds setPersistent(false); 307f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds 308f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds final String action = isSchedule ? ZenModeScheduleRuleSettings.ACTION 309f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds : isEvent ? ZenModeEventRuleSettings.ACTION : ""; 310f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds ServiceInfo si = mServiceListing.findService(mContext, CONFIG, rule.getOwner()); 311f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds ComponentName settingsActivity = getSettingsActivity(si); 31225cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds setIntent(getRuleIntent(action, settingsActivity, mId)); 313f7748e4ae15e49f9f4a9cc15a372e9a6d3c35c56Julia Reynolds 314cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds setWidgetLayoutResource(R.layout.zen_rule_widget); 315cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 316cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 317cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds @Override 31839b467482d1bf256a111c757e9b7621c6f523271Jason Monk public void onBindViewHolder(PreferenceViewHolder view) { 31939b467482d1bf256a111c757e9b7621c6f523271Jason Monk super.onBindViewHolder(view); 320cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 321cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds View v = view.findViewById(R.id.delete_zen_rule); 3227d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds if (v != null) { 3237d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds v.setOnClickListener(mDeleteListener); 3247d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds } 325cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 326cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 327cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds private final View.OnClickListener mDeleteListener = new View.OnClickListener() { 328cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds @Override 329cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds public void onClick(View v) { 33025cb8f06914538f337be66d9a784834a7373b58aJulia Reynolds showDeleteRuleDialog(mId, mName); 331cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 332cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds }; 333cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 334cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 335cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds private class LoadIconTask extends AsyncTask<ApplicationInfo, Void, Drawable> { 336cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds private final WeakReference<Preference> prefReference; 337cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 338cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds public LoadIconTask(Preference pref) { 3397d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds prefReference = new WeakReference<>(pref); 340cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 341cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 342cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds @Override 343cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds protected Drawable doInBackground(ApplicationInfo... params) { 344cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds return params[0].loadIcon(mPm); 345cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 346cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 347cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds @Override 348cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds protected void onPostExecute(Drawable icon) { 3497d8a9aead53f817c9df14cc5feaae223a8a834e8Julia Reynolds if (icon != null) { 350cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds final Preference pref = prefReference.get(); 351cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds pref.setIcon(icon); 352cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 353cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 354cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds } 355cf92ef10a5821e6cf568da78f2bec7a71effe581Julia Reynolds 356d8b36835707edbeeb9c9fbc30eba855a0b6231c6John Spurlock} 357