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.server.telecom;
18 
19 import android.content.ContentResolver;
20 import android.provider.DeviceConfig;
21 import android.provider.Settings;
22 import android.telecom.CallDiagnosticService;
23 import android.telecom.CallRedirectionService;
24 import android.telecom.CallDiagnostics;
25 import android.telephony.ims.ImsReasonInfo;
26 
27 import java.util.concurrent.TimeUnit;
28 
29 /**
30  * A helper class which serves only to make it easier to lookup timeout values. This class should
31  * never be instantiated, and only accessed through the {@link #get(String, long)} method.
32  *
33  * These methods are safe to call from any thread, including the UI thread.
34  */
35 public final class Timeouts {
36     public static class Adapter {
37         public Adapter() {
38         }
39 
40         public long getCallScreeningTimeoutMillis(ContentResolver cr) {
41             return Timeouts.getCallScreeningTimeoutMillis(cr);
42         }
43 
44         public long getCallRemoveUnbindInCallServicesDelay(ContentResolver cr) {
45             return Timeouts.getCallRemoveUnbindInCallServicesDelay(cr);
46         }
47 
48         public long getRetryBluetoothConnectAudioBackoffMillis(ContentResolver cr) {
49             return Timeouts.getRetryBluetoothConnectAudioBackoffMillis(cr);
50         }
51 
52         public long getBluetoothPendingTimeoutMillis(ContentResolver cr) {
53             return Timeouts.getBluetoothPendingTimeoutMillis(cr);
54         }
55 
56         public long getEmergencyCallbackWindowMillis(ContentResolver cr) {
57             return Timeouts.getEmergencyCallbackWindowMillis(cr);
58         }
59 
60         public long getUserDefinedCallRedirectionTimeoutMillis(ContentResolver cr) {
61             return Timeouts.getUserDefinedCallRedirectionTimeoutMillis(cr);
62         }
63 
64         public long getCarrierCallRedirectionTimeoutMillis(ContentResolver cr) {
65             return Timeouts.getCarrierCallRedirectionTimeoutMillis(cr);
66         }
67 
68         public long getPhoneAccountSuggestionServiceTimeout(ContentResolver cr) {
69             return Timeouts.getPhoneAccountSuggestionServiceTimeout(cr);
70         }
71 
72         public long getCallRecordingToneRepeatIntervalMillis(ContentResolver cr) {
73             return Timeouts.getCallRecordingToneRepeatIntervalMillis(cr);
74         }
75 
76         public long getCallDiagnosticServiceTimeoutMillis(ContentResolver cr) {
77             return Timeouts.getCallDiagnosticServiceTimeoutMillis(cr);
78         }
79 
80         public long getCallStartAppOpDebounceIntervalMillis() {
81             return  Timeouts.getCallStartAppOpDebounceIntervalMillis();
82         }
83     }
84 
85     /** A prefix to use for all keys so to not clobber the global namespace. */
86     private static final String PREFIX = "telecom.";
87 
88     private Timeouts() {
89     }
90 
91     /**
92      * Returns the timeout value from Settings or the default value if it hasn't been changed. This
93      * method is safe to call from any thread, including the UI thread.
94      *
95      * @param contentResolver The content resolved.
96      * @param key             Settings key to retrieve.
97      * @param defaultValue    Default value, in milliseconds.
98      * @return The timeout value from Settings or the default value if it hasn't been changed.
99      */
100     private static long get(ContentResolver contentResolver, String key, long defaultValue) {
101         return Settings.Secure.getLongForUser(contentResolver, PREFIX + key, defaultValue,
102                         contentResolver.getUserId());
103     }
104 
105     /**
106      * Returns the amount of time to wait before disconnecting a call that was canceled via
107      * NEW_OUTGOING_CALL broadcast. This timeout allows apps which repost the call using a gateway
108      * to reuse the existing call, preventing the call from causing a start->end->start jank in the
109      * in-call UI.
110      */
111     public static long getNewOutgoingCallCancelMillis(ContentResolver contentResolver) {
112         return get(contentResolver, "new_outgoing_call_cancel_ms", 500L);
113     }
114 
115     /**
116      * Returns the maximum amount of time to wait before disconnecting a call that was canceled via
117      * NEW_OUTGOING_CALL broadcast. This prevents malicious or poorly configured apps from
118      * forever tying up the Telecom stack.
119      */
120     public static long getMaxNewOutgoingCallCancelMillis(ContentResolver contentResolver) {
121         return get(contentResolver, "max_new_outgoing_call_cancel_ms", 10000L);
122     }
123 
124     /**
125      * Returns the amount of time to play each DTMF tone after post dial continue.
126      * This timeout allows the current tone to play for a certain amount of time before either being
127      * interrupted by the next tone or terminated.
128      */
129     public static long getDelayBetweenDtmfTonesMillis(ContentResolver contentResolver) {
130         return get(contentResolver, "delay_between_dtmf_tones_ms", 300L);
131     }
132 
133     /**
134      * Returns the amount of time to wait for an emergency call to be placed before routing to
135      * a different call service. A value of 0 or less means no timeout should be used.
136      */
137     public static long getEmergencyCallTimeoutMillis(ContentResolver contentResolver) {
138         return get(contentResolver, "emergency_call_timeout_millis", 25000L /* 25 seconds */);
139     }
140 
141     /**
142      * Returns the amount of time to wait for an emergency call to be placed before routing to
143      * a different call service. This timeout is used only when the radio is powered off (for
144      * example in airplane mode). A value of 0 or less means no timeout should be used.
145      */
146     public static long getEmergencyCallTimeoutRadioOffMillis(ContentResolver contentResolver) {
147         return get(contentResolver, "emergency_call_timeout_radio_off_millis",
148                 60000L /* 1 minute */);
149     }
150 
151     /**
152      * Returns the amount of delay before unbinding the in-call services after all the calls
153      * are removed.
154      */
155     public static long getCallRemoveUnbindInCallServicesDelay(ContentResolver contentResolver) {
156         return get(contentResolver, "call_remove_unbind_in_call_services_delay",
157                 2000L /* 2 seconds */);
158     }
159 
160     /**
161      * Returns the amount of time for which bluetooth is considered connected after requesting
162      * connection. This compensates for the amount of time it takes for the audio route to
163      * actually change to bluetooth.
164      */
165     public static long getBluetoothPendingTimeoutMillis(ContentResolver contentResolver) {
166         return get(contentResolver, "bluetooth_pending_timeout_millis", 5000L);
167     }
168 
169     /**
170      * Returns the amount of time to wait before retrying the connectAudio call. This is
171      * necessary to account for the HeadsetStateMachine sometimes not being ready when we want to
172      * connect to bluetooth audio immediately after a device connects.
173      */
174     public static long getRetryBluetoothConnectAudioBackoffMillis(ContentResolver contentResolver) {
175         return get(contentResolver, "retry_bluetooth_connect_audio_backoff_millis", 500L);
176     }
177 
178     /**
179      * Returns the amount of time to wait for the phone account suggestion service to reply.
180      */
181     public static long getPhoneAccountSuggestionServiceTimeout(ContentResolver contentResolver) {
182         return get(contentResolver, "phone_account_suggestion_service_timeout",
183                 5000L /* 5 seconds */);
184     }
185 
186     /**
187      * Returns the amount of time to wait for the call screening service to allow or disallow a
188      * call.
189      */
190     public static long getCallScreeningTimeoutMillis(ContentResolver contentResolver) {
191         return get(contentResolver, "call_screening_timeout", 5000L /* 5 seconds */);
192     }
193 
194     /**
195      * Returns the amount of time after an emergency call that incoming calls should be treated
196      * as potential emergency callbacks.
197      */
198     public static long getEmergencyCallbackWindowMillis(ContentResolver contentResolver) {
199         return get(contentResolver, "emergency_callback_window_millis",
200                 TimeUnit.MILLISECONDS.convert(5, TimeUnit.MINUTES));
201     }
202 
203     /**
204      * Returns the amount of time for an user-defined {@link CallRedirectionService}.
205      *
206      * @param contentResolver The content resolver.
207      */
208     public static long getUserDefinedCallRedirectionTimeoutMillis(ContentResolver contentResolver) {
209         return get(contentResolver, "user_defined_call_redirection_timeout",
210                 5000L /* 5 seconds */);
211     }
212 
213     /**
214      * Returns the amount of time for a carrier {@link CallRedirectionService}.
215      *
216      * @param contentResolver The content resolver.
217      */
218     public static long getCarrierCallRedirectionTimeoutMillis(ContentResolver contentResolver) {
219         return get(contentResolver, "carrier_call_redirection_timeout", 5000L /* 5 seconds */);
220     }
221 
222     /**
223      * Returns the number of milliseconds between two plays of the call recording tone.
224      */
225     public static long getCallRecordingToneRepeatIntervalMillis(ContentResolver contentResolver) {
226         return get(contentResolver, "call_recording_tone_repeat_interval", 15000L /* 15 seconds */);
227     }
228 
229     /**
230      * Returns the maximum amount of time a {@link CallDiagnosticService} is permitted to take to
231      * return back from {@link CallDiagnostics#onCallDisconnected(ImsReasonInfo)} and
232      * {@link CallDiagnostics#onCallDisconnected(int, int)}.
233      * @param contentResolver The resolver for the config option.
234      * @return The timeout in millis.
235      */
236     public static long getCallDiagnosticServiceTimeoutMillis(ContentResolver contentResolver) {
237         return get(contentResolver, "call_diagnostic_service_timeout", 2000L /* 2 sec */);
238     }
239 
240     public static long getCallStartAppOpDebounceIntervalMillis() {
241         return DeviceConfig.getLong(DeviceConfig.NAMESPACE_PRIVACY, "app_op_debounce_time", 250L);
242     }
243 
244     /**
245      * Returns the number of milliseconds for which the system should exempt the default dialer from
246      * power save restrictions due to the dialer needing to handle a missed call notification
247      * (update call log, check VVM, etc...).
248      */
249     public static long getDialerMissedCallPowerSaveExemptionTimeMillis(
250             ContentResolver contentResolver) {
251         return get(contentResolver, "dialer_missed_call_power_save_exemption_time_millis",
252                 30000L /*30 seconds*/);
253     }
254 }
255