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.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.util.Log;
24 
25 import com.android.contacts.common.util.PermissionsUtil;
26 import com.android.dialer.util.TelecomUtil;
27 
28 /**
29  * Provides operations for managing call-related notifications.
30  * <p>
31  * It handles the following actions:
32  * <ul>
33  * <li>Updating voicemail notifications</li>
34  * <li>Marking new voicemails as old</li>
35  * <li>Updating missed call notifications</li>
36  * <li>Marking new missed calls as old</li>
37  * <li>Calling back from a missed call</li>
38  * <li>Sending an SMS from a missed call</li>
39  * </ul>
40  */
41 public class CallLogNotificationsService extends IntentService {
42     private static final String TAG = "CallLogNotificationsService";
43 
44     /** Action to mark all the new voicemails as old. */
45     public static final String ACTION_MARK_NEW_VOICEMAILS_AS_OLD =
46             "com.android.dialer.calllog.ACTION_MARK_NEW_VOICEMAILS_AS_OLD";
47 
48     /**
49      * Action to update voicemail notifications.
50      * <p>
51      * May include an optional extra {@link #EXTRA_NEW_VOICEMAIL_URI}.
52      */
53     public static final String ACTION_UPDATE_VOICEMAIL_NOTIFICATIONS =
54             "com.android.dialer.calllog.UPDATE_VOICEMAIL_NOTIFICATIONS";
55 
56     /**
57      * Extra to included with {@link #ACTION_UPDATE_VOICEMAIL_NOTIFICATIONS} to identify the new
58      * voicemail that triggered an update.
59      * <p>
60      * It must be a {@link Uri}.
61      */
62     public static final String EXTRA_NEW_VOICEMAIL_URI = "NEW_VOICEMAIL_URI";
63 
64     /**
65      * Action to update the missed call notifications.
66      * <p>
67      * Includes optional extras {@link #EXTRA_MISSED_CALL_NUMBER} and
68      * {@link #EXTRA_MISSED_CALL_COUNT}.
69      */
70     public static final String ACTION_UPDATE_MISSED_CALL_NOTIFICATIONS =
71             "com.android.dialer.calllog.UPDATE_MISSED_CALL_NOTIFICATIONS";
72 
73     /** Action to mark all the new missed calls as old. */
74     public static final String ACTION_MARK_NEW_MISSED_CALLS_AS_OLD =
75             "com.android.dialer.calllog.ACTION_MARK_NEW_MISSED_CALLS_AS_OLD";
76 
77     /** Action to call back a missed call. */
78     public static final String ACTION_CALL_BACK_FROM_MISSED_CALL_NOTIFICATION =
79             "com.android.dialer.calllog.CALL_BACK_FROM_MISSED_CALL_NOTIFICATION";
80 
81     public static final String ACTION_SEND_SMS_FROM_MISSED_CALL_NOTIFICATION =
82             "com.android.dialer.calllog.SEND_SMS_FROM_MISSED_CALL_NOTIFICATION";
83 
84     /**
85      * Extra to be included with {@link #ACTION_UPDATE_MISSED_CALL_NOTIFICATIONS},
86      * {@link #ACTION_SEND_SMS_FROM_MISSED_CALL_NOTIFICATION} and
87      * {@link #ACTION_CALL_BACK_FROM_MISSED_CALL_NOTIFICATION} to identify the number to display,
88      * call or text back.
89      * <p>
90      * It must be a {@link String}.
91      */
92     public static final String EXTRA_MISSED_CALL_NUMBER = "MISSED_CALL_NUMBER";
93 
94     /**
95      * Extra to be included with {@link #ACTION_UPDATE_MISSED_CALL_NOTIFICATIONS} to represent the
96      * number of missed calls.
97      * <p>
98      * It must be a {@link Integer}
99      */
100     public static final String EXTRA_MISSED_CALL_COUNT =
101             "MISSED_CALL_COUNT";
102 
103     public static final int UNKNOWN_MISSED_CALL_COUNT = -1;
104 
105     private VoicemailQueryHandler mVoicemailQueryHandler;
106 
CallLogNotificationsService()107     public CallLogNotificationsService() {
108         super("CallLogNotificationsService");
109     }
110 
111     @Override
onHandleIntent(Intent intent)112     protected void onHandleIntent(Intent intent) {
113         if (intent == null) {
114             Log.d(TAG, "onHandleIntent: could not handle null intent");
115             return;
116         }
117 
118         if (!PermissionsUtil.hasPermission(this, android.Manifest.permission.READ_CALL_LOG)) {
119             return;
120         }
121 
122         String action = intent.getAction();
123         switch (action) {
124             case ACTION_MARK_NEW_VOICEMAILS_AS_OLD:
125                 if (mVoicemailQueryHandler == null) {
126                     mVoicemailQueryHandler = new VoicemailQueryHandler(this, getContentResolver());
127                 }
128                 mVoicemailQueryHandler.markNewVoicemailsAsOld();
129                 break;
130             case ACTION_UPDATE_VOICEMAIL_NOTIFICATIONS:
131                 Uri voicemailUri = (Uri) intent.getParcelableExtra(EXTRA_NEW_VOICEMAIL_URI);
132                 DefaultVoicemailNotifier.getInstance(this).updateNotification(voicemailUri);
133                 break;
134             case ACTION_UPDATE_MISSED_CALL_NOTIFICATIONS:
135                 int count = intent.getIntExtra(EXTRA_MISSED_CALL_COUNT,
136                         UNKNOWN_MISSED_CALL_COUNT);
137                 String number = intent.getStringExtra(EXTRA_MISSED_CALL_NUMBER);
138                 MissedCallNotifier.getInstance(this).updateMissedCallNotification(count, number);
139                 break;
140             case ACTION_MARK_NEW_MISSED_CALLS_AS_OLD:
141                 CallLogNotificationsHelper.removeMissedCallNotifications(this);
142                 break;
143             case ACTION_CALL_BACK_FROM_MISSED_CALL_NOTIFICATION:
144                 MissedCallNotifier.getInstance(this).callBackFromMissedCall(
145                         intent.getStringExtra(EXTRA_MISSED_CALL_NUMBER));
146                 break;
147             case ACTION_SEND_SMS_FROM_MISSED_CALL_NOTIFICATION:
148                 MissedCallNotifier.getInstance(this).sendSmsFromMissedCall(
149                         intent.getStringExtra(EXTRA_MISSED_CALL_NUMBER));
150                 break;
151             default:
152                 Log.d(TAG, "onHandleIntent: could not handle: " + intent);
153                 break;
154         }
155     }
156 
157     /**
158      * Updates notifications for any new voicemails.
159      *
160      * @param context a valid context.
161      * @param voicemailUri The uri pointing to the voicemail to update the notification for. If
162      *         {@code null}, then notifications for all new voicemails will be updated.
163      */
updateVoicemailNotifications(Context context, Uri voicemailUri)164     public static void updateVoicemailNotifications(Context context, Uri voicemailUri) {
165         if (TelecomUtil.hasReadWriteVoicemailPermissions(context)) {
166             Intent serviceIntent = new Intent(context, CallLogNotificationsService.class);
167             serviceIntent.setAction(
168                     CallLogNotificationsService.ACTION_UPDATE_VOICEMAIL_NOTIFICATIONS);
169             // If voicemailUri is null, then notifications for all voicemails will be updated.
170             if (voicemailUri != null) {
171                 serviceIntent.putExtra(
172                         CallLogNotificationsService.EXTRA_NEW_VOICEMAIL_URI, voicemailUri);
173             }
174             context.startService(serviceIntent);
175         }
176     }
177 
178     /**
179      * Updates notifications for any new missed calls.
180      *
181      * @param context A valid context.
182      * @param count The number of new missed calls.
183      * @param number The phone number of the newest missed call.
184      */
updateMissedCallNotifications(Context context, int count, String number)185     public static void updateMissedCallNotifications(Context context, int count,
186             String number) {
187         Intent serviceIntent = new Intent(context, CallLogNotificationsService.class);
188         serviceIntent.setAction(
189                 CallLogNotificationsService.ACTION_UPDATE_MISSED_CALL_NOTIFICATIONS);
190         serviceIntent.putExtra(EXTRA_MISSED_CALL_COUNT, count);
191         serviceIntent.putExtra(EXTRA_MISSED_CALL_NUMBER, number);
192         context.startService(serviceIntent);
193     }
194 }
195