1 /* 2 * Copyright (C) 2011 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.dialer.app.calllog; 18 19 import android.app.IntentService; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.net.Uri; 23 import android.os.Handler; 24 import android.os.Looper; 25 import android.support.annotation.Nullable; 26 import com.android.dialer.common.LogUtil; 27 import com.android.dialer.telecom.TelecomUtil; 28 import com.android.dialer.util.PermissionsUtil; 29 30 /** 31 * Provides operations for managing call-related notifications. 32 * 33 * <p>It handles the following actions: 34 * 35 * <ul> 36 * <li>Updating voicemail notifications 37 * <li>Marking new voicemails as old 38 * <li>Updating missed call notifications 39 * <li>Marking new missed calls as old 40 * <li>Calling back from a missed call 41 * <li>Sending an SMS from a missed call 42 * </ul> 43 */ 44 public class CallLogNotificationsService extends IntentService { 45 46 /** Action to mark all the new voicemails as old. */ 47 public static final String ACTION_MARK_NEW_VOICEMAILS_AS_OLD = 48 "com.android.dialer.calllog.ACTION_MARK_NEW_VOICEMAILS_AS_OLD"; 49 50 /** Action to mark all the new missed calls as old. */ 51 public static final String ACTION_MARK_NEW_MISSED_CALLS_AS_OLD = 52 "com.android.dialer.calllog.ACTION_MARK_NEW_MISSED_CALLS_AS_OLD"; 53 54 /** Action to update missed call notifications with a post call note. */ 55 public static final String ACTION_INCOMING_POST_CALL = 56 "com.android.dialer.calllog.INCOMING_POST_CALL"; 57 58 /** Action to call back a missed call. */ 59 public static final String ACTION_CALL_BACK_FROM_MISSED_CALL_NOTIFICATION = 60 "com.android.dialer.calllog.CALL_BACK_FROM_MISSED_CALL_NOTIFICATION"; 61 62 /** 63 * Extra to be included with {@link #ACTION_INCOMING_POST_CALL} to represent a post call note. 64 * 65 * <p>It must be a {@link String} 66 */ 67 public static final String EXTRA_POST_CALL_NOTE = "POST_CALL_NOTE"; 68 69 /** 70 * Extra to be included with {@link #ACTION_INCOMING_POST_CALL} to represent the phone number the 71 * post call note came from. 72 * 73 * <p>It must be a {@link String} 74 */ 75 public static final String EXTRA_POST_CALL_NUMBER = "POST_CALL_NUMBER"; 76 77 public static final int UNKNOWN_MISSED_CALL_COUNT = -1; 78 private VoicemailQueryHandler mVoicemailQueryHandler; 79 80 public CallLogNotificationsService() { 81 super("CallLogNotificationsService"); 82 } 83 84 public static void insertPostCallNote(Context context, String number, String postCallNote) { 85 Intent serviceIntent = new Intent(context, CallLogNotificationsService.class); 86 serviceIntent.setAction(ACTION_INCOMING_POST_CALL); 87 serviceIntent.putExtra(EXTRA_POST_CALL_NUMBER, number); 88 serviceIntent.putExtra(EXTRA_POST_CALL_NOTE, postCallNote); 89 context.startService(serviceIntent); 90 } 91 92 public static void markNewVoicemailsAsOld(Context context, @Nullable Uri voicemailUri) { 93 Intent serviceIntent = new Intent(context, CallLogNotificationsService.class); 94 serviceIntent.setAction(CallLogNotificationsService.ACTION_MARK_NEW_VOICEMAILS_AS_OLD); 95 serviceIntent.setData(voicemailUri); 96 context.startService(serviceIntent); 97 } 98 99 public static void markNewMissedCallsAsOld(Context context, @Nullable Uri callUri) { 100 Intent serviceIntent = new Intent(context, CallLogNotificationsService.class); 101 serviceIntent.setAction(ACTION_MARK_NEW_MISSED_CALLS_AS_OLD); 102 serviceIntent.setData(callUri); 103 context.startService(serviceIntent); 104 } 105 106 @Override 107 protected void onHandleIntent(Intent intent) { 108 if (intent == null) { 109 LogUtil.d("CallLogNotificationsService.onHandleIntent", "could not handle null intent"); 110 return; 111 } 112 113 if (!PermissionsUtil.hasPermission(this, android.Manifest.permission.READ_CALL_LOG)) { 114 return; 115 } 116 117 String action = intent.getAction(); 118 switch (action) { 119 case ACTION_MARK_NEW_VOICEMAILS_AS_OLD: 120 // VoicemailQueryHandler cannot be created on the IntentService worker thread. The completed 121 // callback might happen when the thread is dead. 122 Handler handler = new Handler(Looper.getMainLooper()); 123 handler.post( 124 () -> { 125 if (mVoicemailQueryHandler == null) { 126 mVoicemailQueryHandler = new VoicemailQueryHandler(this, getContentResolver()); 127 } 128 mVoicemailQueryHandler.markNewVoicemailsAsOld(intent.getData()); 129 }); 130 break; 131 case ACTION_INCOMING_POST_CALL: 132 String note = intent.getStringExtra(EXTRA_POST_CALL_NOTE); 133 String phoneNumber = intent.getStringExtra(EXTRA_POST_CALL_NUMBER); 134 MissedCallNotifier.getIstance(this).insertPostCallNotification(phoneNumber, note); 135 break; 136 case ACTION_MARK_NEW_MISSED_CALLS_AS_OLD: 137 CallLogNotificationsQueryHelper.removeMissedCallNotifications(this, intent.getData()); 138 TelecomUtil.cancelMissedCallsNotification(this); 139 break; 140 case ACTION_CALL_BACK_FROM_MISSED_CALL_NOTIFICATION: 141 MissedCallNotifier.getIstance(this) 142 .callBackFromMissedCall( 143 intent.getStringExtra( 144 MissedCallNotificationReceiver.EXTRA_NOTIFICATION_PHONE_NUMBER), 145 intent.getData()); 146 break; 147 default: 148 LogUtil.d("CallLogNotificationsService.onHandleIntent", "could not handle: " + intent); 149 break; 150 } 151 } 152 } 153