diff options
author | blunden <blunden2@gmail.com> | 2018-03-18 14:02:30 +0100 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2020-12-12 01:23:35 +0200 |
commit | 399647dde74e8fbf152c98b36657944fd5369eea (patch) | |
tree | fa8b303475f1e0259e48a6282e47ea50d8c01379 | |
parent | 25237ec70323d72c299dd984117031de432b8e42 (diff) |
Add setting to enable Do Not Disturb during calls
Android N and earlier enabled Do Not Disturb mode while in a call.
Reimplement this behavior to prevent incoming notifications from
vibrating or playing sounds.
Change-Id: Ic38ac775c6e353898190e1571b6d6e521c0e5aa1
6 files changed, 137 insertions, 0 deletions
diff --git a/java/com/android/dialer/app/res/values/cm_strings.xml b/java/com/android/dialer/app/res/values/cm_strings.xml index ba15b469d..0ba0d500a 100644 --- a/java/com/android/dialer/app/res/values/cm_strings.xml +++ b/java/com/android/dialer/app/res/values/cm_strings.xml @@ -18,6 +18,7 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="incall_category_key" translatable="false">dialer_general_incall_category_key</string> <string name="incall_category_title">In-call</string> + <string name="incall_enable_dnd_title">Enable Do Not Disturb during calls</string> <string name="incall_vibrate_outgoing_key" translatable="false">incall_vibrate_outgoing</string> <string name="incall_vibrate_outgoing_title">Vibrate on answer</string> <string name="incall_vibrate_call_waiting_key" translatable="false">incall_vibrate_call_waiting</string> @@ -27,4 +28,7 @@ <string name="incall_vibrate_45_key" translatable="false">incall_vibrate_45secs</string> <string name="incall_vibrate_45_title">Vibrate every minute</string> <string name="incall_vibrate_45_summary">Vibrates at the 45 second mark of every minute during outgoing calls</string> + <string name="incall_dnd_dialog_message">In order to enable Do Not Disturb, the Phone app needs to be granted the permission to control the Do Not Disturb status.\nPlease allow it.</string> + <string name="allow">Allow</string> + <string name="deny">Deny</string> </resources> diff --git a/java/com/android/dialer/app/res/xml/sound_settings.xml b/java/com/android/dialer/app/res/xml/sound_settings.xml index e26e51aad..4da5c1514 100644 --- a/java/com/android/dialer/app/res/xml/sound_settings.xml +++ b/java/com/android/dialer/app/res/xml/sound_settings.xml @@ -48,6 +48,11 @@ android:title="@string/incall_category_title"> <SwitchPreference + android:defaultValue="false" + android:key="incall_enable_dnd" + android:title="@string/incall_enable_dnd_title"/> + + <SwitchPreference android:key="@string/incall_vibrate_outgoing_key" android:title="@string/incall_vibrate_outgoing_title" /> diff --git a/java/com/android/dialer/app/settings/SoundSettingsFragment.java b/java/com/android/dialer/app/settings/SoundSettingsFragment.java index 3c254cc4b..d9f24ab7e 100644 --- a/java/com/android/dialer/app/settings/SoundSettingsFragment.java +++ b/java/com/android/dialer/app/settings/SoundSettingsFragment.java @@ -16,7 +16,11 @@ package com.android.dialer.app.settings; +import android.app.AlertDialog; +import android.app.NotificationManager; import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; import android.media.RingtoneManager; import android.os.Build; import android.os.Bundle; @@ -70,6 +74,9 @@ public class SoundSettingsFragment extends PreferenceFragment private SwitchPreference vibrateWhenRinging; private SwitchPreference playDtmfTone; private ListPreference dtmfToneLength; + private SwitchPreference enableDndInCall; + + private NotificationManager notificationManager; @Override public Context getContext() { @@ -92,6 +99,7 @@ public class SoundSettingsFragment extends PreferenceFragment dtmfToneLength = (ListPreference) findPreference(context.getString(R.string.dtmf_tone_length_preference_key)); + enableDndInCall = (SwitchPreference) findPreference("incall_enable_dnd"); if (hasVibrator()) { vibrateWhenRinging.setOnPreferenceChangeListener(this); @@ -116,6 +124,8 @@ public class SoundSettingsFragment extends PreferenceFragment playDtmfTone.setOnPreferenceChangeListener(this); playDtmfTone.setChecked(shouldPlayDtmfTone()); + enableDndInCall.setOnPreferenceChangeListener(this); + TelephonyManager telephonyManager = (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE); if (telephonyManager.canChangeDtmfToneLength() @@ -130,6 +140,7 @@ public class SoundSettingsFragment extends PreferenceFragment getPreferenceScreen().removePreference(dtmfToneLength); dtmfToneLength = null; } + notificationManager = context.getSystemService(NotificationManager.class); } @Override @@ -178,6 +189,30 @@ public class SoundSettingsFragment extends PreferenceFragment int index = dtmfToneLength.findIndexOfValue((String) objValue); Settings.System.putInt( getActivity().getContentResolver(), Settings.System.DTMF_TONE_TYPE_WHEN_DIALING, index); + } else if (preference == enableDndInCall) { + boolean newValue = (Boolean) objValue; + if (newValue && !notificationManager.isNotificationPolicyAccessGranted()) { + new AlertDialog.Builder(getContext()) + .setMessage(R.string.incall_dnd_dialog_message) + .setPositiveButton(R.string.allow, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS); + startActivity(intent); + } + }) + .setNegativeButton(R.string.deny, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + dialog.dismiss(); + } + }) + .show(); + + // At this time, it is unknown whether the user granted the permission + return false; + } } return true; } diff --git a/java/com/android/incallui/AndroidManifest.xml b/java/com/android/incallui/AndroidManifest.xml index 4cb600190..8e69c0dd9 100644 --- a/java/com/android/incallui/AndroidManifest.xml +++ b/java/com/android/incallui/AndroidManifest.xml @@ -46,6 +46,9 @@ <!-- Set audio selector window type TYPE_APPLICATION_OVERLAY --> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> + <!-- Required when the "Enable Do Not Disturb during call" setting is enabled --> + <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" /> + <!-- Set android:taskAffinity="com.android.incallui" for all activities to ensure proper navigation. Otherwise system could bring up MainActivity instead, e.g. when user unmerge a call. diff --git a/java/com/android/incallui/InCallDndHandler.java b/java/com/android/incallui/InCallDndHandler.java new file mode 100644 index 000000000..4ab3e840a --- /dev/null +++ b/java/com/android/incallui/InCallDndHandler.java @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2018 The LineageOS 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.incallui; + +import android.app.NotificationManager; +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; + +import com.android.incallui.call.CallList; +import com.android.incallui.call.DialerCall; +import com.android.incallui.call.state.DialerCallState; +import com.android.incallui.InCallPresenter.InCallState; + +public class InCallDndHandler implements InCallPresenter.InCallStateListener { + + private static final String KEY_ENABLE_DND = "incall_enable_dnd"; + + private SharedPreferences prefs; + private DialerCall activeCall; + private NotificationManager notificationManager; + private int userSelectedDndMode; + + public InCallDndHandler(Context context) { + prefs = PreferenceManager.getDefaultSharedPreferences(context); + notificationManager = context.getSystemService(NotificationManager.class); + + // Save the user's Do Not Disturb mode so that it can be restored when the call ends + userSelectedDndMode = notificationManager.getCurrentInterruptionFilter(); + } + + @Override + public void onStateChange(InCallState oldState, InCallState newState, CallList callList) { + DialerCall activeCall = callList.getActiveCall(); + + if (activeCall != null && this.activeCall == null) { + Log.d(this, "Transition to active call " + activeCall); + handleDndState(activeCall); + this.activeCall = activeCall; + } else if (activeCall == null && this.activeCall != null) { + Log.d(this, "Transition from active call " + this.activeCall); + handleDndState(this.activeCall); + this.activeCall = null; + } + } + + private void handleDndState(DialerCall call) { + if (!prefs.getBoolean(KEY_ENABLE_DND, false)) { + return; + } + if (DialerCallState.isConnectingOrConnected(call.getState())) { + Log.d(this, "Enabling Do Not Disturb mode"); + setDoNotDisturbMode(NotificationManager.INTERRUPTION_FILTER_NONE); + } else { + Log.d(this, "Restoring previous Do Not Disturb mode"); + setDoNotDisturbMode(userSelectedDndMode); + } + } + + private void setDoNotDisturbMode(int newMode) { + if (notificationManager.isNotificationPolicyAccessGranted()) { + notificationManager.setInterruptionFilter(newMode); + } else { + Log.e(this, "Failed to set Do Not Disturb mode " + newMode + " due to lack of permissions"); + } + } +} diff --git a/java/com/android/incallui/InCallPresenter.java b/java/com/android/incallui/InCallPresenter.java index 1bb606ea0..8881029cc 100644 --- a/java/com/android/incallui/InCallPresenter.java +++ b/java/com/android/incallui/InCallPresenter.java @@ -128,6 +128,7 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud private StatusBarNotifier statusBarNotifier; private ExternalCallNotifier externalCallNotifier; private InCallVibrationHandler vibrationHandler; + private InCallDndHandler dndHandler; private ContactInfoCache contactInfoCache; private Context context; private final OnCheckBlockedListener onCheckBlockedListener = @@ -368,6 +369,9 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud vibrationHandler = new InCallVibrationHandler(context); addListener(vibrationHandler); + dndHandler = new InCallDndHandler(context); + addListener(dndHandler); + this.proximitySensor = proximitySensor; addListener(this.proximitySensor); @@ -1662,6 +1666,11 @@ public class InCallPresenter implements CallList.Listener, AudioModeProvider.Aud } vibrationHandler = null; + if (dndHandler != null) { + removeListener(dndHandler); + } + dndHandler = null; + if (callList != null) { callList.removeListener(this); callList.removeListener(spamCallListListener); |