| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 1 | /* | 
|  | 2 | * Copyright (C) 2009 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.phone; | 
|  | 18 |  | 
|  | 19 | import android.app.Notification; | 
|  | 20 | import android.app.NotificationManager; | 
|  | 21 | import android.app.PendingIntent; | 
|  | 22 | import android.app.Service; | 
|  | 23 | import android.content.BroadcastReceiver; | 
|  | 24 | import android.content.Context; | 
|  | 25 | import android.content.Intent; | 
|  | 26 | import android.content.IntentFilter; | 
|  | 27 | import android.content.res.Resources; | 
|  | 28 | import android.os.AsyncResult; | 
|  | 29 | import android.os.Binder; | 
|  | 30 | import android.os.CountDownTimer; | 
|  | 31 | import android.os.Handler; | 
|  | 32 | import android.os.IBinder; | 
|  | 33 | import android.os.Message; | 
|  | 34 | import android.os.SystemProperties; | 
|  | 35 | import android.util.Log; | 
|  | 36 |  | 
|  | 37 | import com.android.internal.telephony.cdma.CDMAPhone; | 
|  | 38 | import com.android.internal.telephony.Phone; | 
|  | 39 | import com.android.internal.telephony.PhoneConstants; | 
|  | 40 | import com.android.internal.telephony.PhoneFactory; | 
|  | 41 | import com.android.internal.telephony.TelephonyIntents; | 
|  | 42 | import com.android.internal.telephony.TelephonyProperties; | 
|  | 43 |  | 
|  | 44 | /** | 
|  | 45 | * Application service that inserts/removes Emergency Callback Mode notification and | 
|  | 46 | * updates Emergency Callback Mode countdown clock in the notification | 
|  | 47 | * | 
|  | 48 | * @see EmergencyCallbackModeExitDialog | 
|  | 49 | */ | 
|  | 50 | public class EmergencyCallbackModeService extends Service { | 
|  | 51 |  | 
|  | 52 | // Default Emergency Callback Mode timeout value | 
|  | 53 | private static final int DEFAULT_ECM_EXIT_TIMER_VALUE = 300000; | 
|  | 54 | private static final String LOG_TAG = "EmergencyCallbackModeService"; | 
|  | 55 |  | 
|  | 56 | private NotificationManager mNotificationManager = null; | 
|  | 57 | private CountDownTimer mTimer = null; | 
|  | 58 | private long mTimeLeft = 0; | 
|  | 59 | private Phone mPhone = null; | 
|  | 60 | private boolean mInEmergencyCall = false; | 
|  | 61 |  | 
|  | 62 | private static final int ECM_TIMER_RESET = 1; | 
|  | 63 |  | 
|  | 64 | private Handler mHandler = new Handler () { | 
|  | 65 | public void handleMessage(Message msg) { | 
|  | 66 | switch (msg.what) { | 
|  | 67 | case ECM_TIMER_RESET: | 
|  | 68 | resetEcmTimer((AsyncResult) msg.obj); | 
|  | 69 | break; | 
|  | 70 | } | 
|  | 71 | } | 
|  | 72 | }; | 
|  | 73 |  | 
|  | 74 | @Override | 
|  | 75 | public void onCreate() { | 
|  | 76 | // Check if it is CDMA phone | 
| Uma Maheswari Ramalingam | f16de20 | 2014-07-31 16:15:27 -0700 | [diff] [blame] | 77 | if ((PhoneFactory.getDefaultPhone().getPhoneType() != PhoneConstants.PHONE_TYPE_CDMA) | 
|  | 78 | && (PhoneFactory.getDefaultPhone().getImsPhone() == null)) { | 
| Santos Cordon | 7d4ddf6 | 2013-07-10 11:58:08 -0700 | [diff] [blame] | 79 | Log.e(LOG_TAG, "Error! Emergency Callback Mode not supported for " + | 
|  | 80 | PhoneFactory.getDefaultPhone().getPhoneName() + " phones"); | 
|  | 81 | stopSelf(); | 
|  | 82 | } | 
|  | 83 |  | 
|  | 84 | // Register receiver for intents | 
|  | 85 | IntentFilter filter = new IntentFilter(); | 
|  | 86 | filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); | 
|  | 87 | filter.addAction(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS); | 
|  | 88 | registerReceiver(mEcmReceiver, filter); | 
|  | 89 |  | 
|  | 90 | mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); | 
|  | 91 |  | 
|  | 92 | // Register ECM timer reset notfication | 
|  | 93 | mPhone = PhoneFactory.getDefaultPhone(); | 
|  | 94 | mPhone.registerForEcmTimerReset(mHandler, ECM_TIMER_RESET, null); | 
|  | 95 |  | 
|  | 96 | startTimerNotification(); | 
|  | 97 | } | 
|  | 98 |  | 
|  | 99 | @Override | 
|  | 100 | public void onDestroy() { | 
|  | 101 | // Unregister receiver | 
|  | 102 | unregisterReceiver(mEcmReceiver); | 
|  | 103 | // Unregister ECM timer reset notification | 
|  | 104 | mPhone.unregisterForEcmTimerReset(mHandler); | 
|  | 105 |  | 
|  | 106 | // Cancel the notification and timer | 
|  | 107 | mNotificationManager.cancel(R.string.phone_in_ecm_notification_title); | 
|  | 108 | mTimer.cancel(); | 
|  | 109 | } | 
|  | 110 |  | 
|  | 111 | /** | 
|  | 112 | * Listens for Emergency Callback Mode intents | 
|  | 113 | */ | 
|  | 114 | private BroadcastReceiver mEcmReceiver = new BroadcastReceiver() { | 
|  | 115 | @Override | 
|  | 116 | public void onReceive(Context context, Intent intent) { | 
|  | 117 | // Stop the service when phone exits Emergency Callback Mode | 
|  | 118 | if (intent.getAction().equals( | 
|  | 119 | TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) { | 
|  | 120 | if (intent.getBooleanExtra("phoneinECMState", false) == false) { | 
|  | 121 | stopSelf(); | 
|  | 122 | } | 
|  | 123 | } | 
|  | 124 | // Show dialog box | 
|  | 125 | else if (intent.getAction().equals( | 
|  | 126 | TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS)) { | 
|  | 127 | context.startActivity( | 
|  | 128 | new Intent(TelephonyIntents.ACTION_SHOW_NOTICE_ECM_BLOCK_OTHERS) | 
|  | 129 | .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); | 
|  | 130 | } | 
|  | 131 | } | 
|  | 132 | }; | 
|  | 133 |  | 
|  | 134 | /** | 
|  | 135 | * Start timer notification for Emergency Callback Mode | 
|  | 136 | */ | 
|  | 137 | private void startTimerNotification() { | 
|  | 138 | // Get Emergency Callback Mode timeout value | 
|  | 139 | long ecmTimeout = SystemProperties.getLong( | 
|  | 140 | TelephonyProperties.PROPERTY_ECM_EXIT_TIMER, DEFAULT_ECM_EXIT_TIMER_VALUE); | 
|  | 141 |  | 
|  | 142 | // Show the notification | 
|  | 143 | showNotification(ecmTimeout); | 
|  | 144 |  | 
|  | 145 | // Start countdown timer for the notification updates | 
|  | 146 | mTimer = new CountDownTimer(ecmTimeout, 1000) { | 
|  | 147 |  | 
|  | 148 | @Override | 
|  | 149 | public void onTick(long millisUntilFinished) { | 
|  | 150 | mTimeLeft = millisUntilFinished; | 
|  | 151 | EmergencyCallbackModeService.this.showNotification(millisUntilFinished); | 
|  | 152 | } | 
|  | 153 |  | 
|  | 154 | @Override | 
|  | 155 | public void onFinish() { | 
|  | 156 | //Do nothing | 
|  | 157 | } | 
|  | 158 |  | 
|  | 159 | }.start(); | 
|  | 160 | } | 
|  | 161 |  | 
|  | 162 | /** | 
|  | 163 | * Shows notification for Emergency Callback Mode | 
|  | 164 | */ | 
|  | 165 | private void showNotification(long millisUntilFinished) { | 
|  | 166 |  | 
|  | 167 | // Set the icon and text | 
|  | 168 | Notification notification = new Notification( | 
|  | 169 | R.drawable.picture_emergency25x25, | 
|  | 170 | getText(R.string.phone_entered_ecm_text), 0); | 
|  | 171 |  | 
|  | 172 | // PendingIntent to launch Emergency Callback Mode Exit activity if the user selects | 
|  | 173 | // this notification | 
|  | 174 | PendingIntent contentIntent = PendingIntent.getActivity(this, 0, | 
|  | 175 | new Intent(EmergencyCallbackModeExitDialog.ACTION_SHOW_ECM_EXIT_DIALOG), 0); | 
|  | 176 |  | 
|  | 177 | // Format notification string | 
|  | 178 | String text = null; | 
|  | 179 | if(mInEmergencyCall) { | 
|  | 180 | text = getText(R.string.phone_in_ecm_call_notification_text).toString(); | 
|  | 181 | } else { | 
|  | 182 | int minutes = (int)(millisUntilFinished / 60000); | 
|  | 183 | String time = String.format("%d:%02d", minutes, (millisUntilFinished % 60000) / 1000); | 
|  | 184 | text = String.format(getResources().getQuantityText( | 
|  | 185 | R.plurals.phone_in_ecm_notification_time, minutes).toString(), time); | 
|  | 186 | } | 
|  | 187 | // Set the info in the notification | 
|  | 188 | notification.setLatestEventInfo(this, getText(R.string.phone_in_ecm_notification_title), | 
|  | 189 | text, contentIntent); | 
|  | 190 |  | 
|  | 191 | notification.flags = Notification.FLAG_ONGOING_EVENT; | 
|  | 192 |  | 
|  | 193 | // Show notification | 
|  | 194 | mNotificationManager.notify(R.string.phone_in_ecm_notification_title, notification); | 
|  | 195 | } | 
|  | 196 |  | 
|  | 197 | /** | 
|  | 198 | * Handle ECM_TIMER_RESET notification | 
|  | 199 | */ | 
|  | 200 | private void resetEcmTimer(AsyncResult r) { | 
|  | 201 | boolean isTimerCanceled = ((Boolean)r.result).booleanValue(); | 
|  | 202 |  | 
|  | 203 | if (isTimerCanceled) { | 
|  | 204 | mInEmergencyCall = true; | 
|  | 205 | mTimer.cancel(); | 
|  | 206 | showNotification(0); | 
|  | 207 | } else { | 
|  | 208 | mInEmergencyCall = false; | 
|  | 209 | startTimerNotification(); | 
|  | 210 | } | 
|  | 211 | } | 
|  | 212 |  | 
|  | 213 | @Override | 
|  | 214 | public IBinder onBind(Intent intent) { | 
|  | 215 | return mBinder; | 
|  | 216 | } | 
|  | 217 |  | 
|  | 218 | // This is the object that receives interactions from clients. | 
|  | 219 | private final IBinder mBinder = new LocalBinder(); | 
|  | 220 |  | 
|  | 221 | /** | 
|  | 222 | * Class for clients to access | 
|  | 223 | */ | 
|  | 224 | public class LocalBinder extends Binder { | 
|  | 225 | EmergencyCallbackModeService getService() { | 
|  | 226 | return EmergencyCallbackModeService.this; | 
|  | 227 | } | 
|  | 228 | } | 
|  | 229 |  | 
|  | 230 | /** | 
|  | 231 | * Returns Emergency Callback Mode timeout value | 
|  | 232 | */ | 
|  | 233 | public long getEmergencyCallbackModeTimeout() { | 
|  | 234 | return mTimeLeft; | 
|  | 235 | } | 
|  | 236 |  | 
|  | 237 | /** | 
|  | 238 | * Returns Emergency Callback Mode call state | 
|  | 239 | */ | 
|  | 240 | public boolean getEmergencyCallbackModeCallState() { | 
|  | 241 | return mInEmergencyCall; | 
|  | 242 | } | 
|  | 243 | } |