Move notification generation to a service.
Generating notifications requires looking up the list of calls to
include and the name of the callers.
Instead of doing this on the onReceive, move this to a service. By using
IntentService this will be done on a worker thread.
Bug: 5036195
Change-Id: Idb6e80c802e40398888bb76f52ad7c5457aea945
diff --git a/src/com/android/contacts/calllog/CallLogNotificationsService.java b/src/com/android/contacts/calllog/CallLogNotificationsService.java
index eda11d6..6dd24aa 100644
--- a/src/com/android/contacts/calllog/CallLogNotificationsService.java
+++ b/src/com/android/contacts/calllog/CallLogNotificationsService.java
@@ -18,25 +18,55 @@
import android.app.IntentService;
import android.content.Intent;
+import android.net.Uri;
import android.util.Log;
/**
* Provides operations for managing notifications.
* <p>
- * At the moment, it only handle {@link #ACTION_MARK_NEW_CALLS_AS_OLD}, which marks all the new
- * items in the call log as old; this is called when a notification is dismissed.
+ * It handles the following actions:
+ * <ul>
+ * <li>{@link #ACTION_MARK_NEW_CALLS_AS_OLD}: marks all the new items in the call log as old; this
+ * is called when a notification is dismissed.</li>
+ * <li>{@link #ACTION_UPDATE_NOTIFICATIONS}: updates the content of the new items notification; it
+ * may include an optional extra {@link #EXTRA_NEW_VOICEMAIL_URI}, containing the URI of the new
+ * voicemail that has triggered this update (if any).</li>
+ * </ul>
*/
public class CallLogNotificationsService extends IntentService {
private static final String TAG = "CallLogNotificationsService";
- // Action to mark all the new calls as old. Invoked when the notifications need to be cleared.
+ /**
+ * Action to mark all the new calls as old.
+ */
public static final String ACTION_MARK_NEW_CALLS_AS_OLD =
- "com.android.contacts.ACTION_MARK_NEW_CALLS_AS_OLD";
+ "com.android.contacts.calllog.MARK_NEW_CALLS_AS_OLD";
+
+ /**
+ * Action to update the notifications.
+ * <p>
+ * May include an optional extra {@link #EXTRA_NEW_VOICEMAIL_URI}.
+ */
+ public static final String ACTION_UPDATE_NOTIFICATIONS =
+ "com.android.contacts.calllog.UPDATE_NOTIFICATIONS";
+
+ /**
+ * Extra to included with {@link #ACTION_UPDATE_NOTIFICATIONS} to identify the new voicemail
+ * that triggered an update.
+ * <p>
+ * It must be a {@link Uri}.
+ */
+ public static final String EXTRA_NEW_VOICEMAIL_URI = "NEW_VOICEMAIL_URI";
private CallLogQueryHandler mCallLogQueryHandler;
public CallLogNotificationsService() {
super("CallLogNotificationsService");
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
mCallLogQueryHandler = new CallLogQueryHandler(getContentResolver(), null /*listener*/);
}
@@ -44,10 +74,11 @@
protected void onHandleIntent(Intent intent) {
if (ACTION_MARK_NEW_CALLS_AS_OLD.equals(intent.getAction())) {
mCallLogQueryHandler.markNewCallsAsOld();
- return;
+ } else if (ACTION_UPDATE_NOTIFICATIONS.equals(intent.getAction())) {
+ Uri voicemailUri = (Uri) intent.getParcelableExtra(EXTRA_NEW_VOICEMAIL_URI);
+ DefaultVoicemailNotifier.getInstance(this).updateNotification(voicemailUri);
} else {
Log.d(TAG, "onHandleIntent: could not handle: " + intent);
}
}
-
}
diff --git a/src/com/android/contacts/calllog/CallLogReceiver.java b/src/com/android/contacts/calllog/CallLogReceiver.java
index a3ff1f2..14bfa64 100644
--- a/src/com/android/contacts/calllog/CallLogReceiver.java
+++ b/src/com/android/contacts/calllog/CallLogReceiver.java
@@ -16,9 +16,7 @@
package com.android.contacts.calllog;
-import android.app.NotificationManager;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.provider.VoicemailContract;
@@ -33,29 +31,20 @@
public class CallLogReceiver extends BroadcastReceiver {
private static final String TAG = "CallLogReceiver";
- private VoicemailNotifier mNotifier;
-
@Override
public void onReceive(Context context, Intent intent) {
- if (mNotifier == null) {
- mNotifier = getNotifier(context);
- }
if (VoicemailContract.ACTION_NEW_VOICEMAIL.equals(intent.getAction())) {
- mNotifier.notifyNewVoicemail(intent.getData());
+ Intent serviceIntent = new Intent(context, CallLogNotificationsService.class);
+ serviceIntent.setAction(CallLogNotificationsService.ACTION_UPDATE_NOTIFICATIONS);
+ serviceIntent.putExtra(
+ CallLogNotificationsService.EXTRA_NEW_VOICEMAIL_URI, intent.getData());
+ context.startService(serviceIntent);
} else if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
- mNotifier.updateNotification();
+ Intent serviceIntent = new Intent(context, CallLogNotificationsService.class);
+ serviceIntent.setAction(CallLogNotificationsService.ACTION_UPDATE_NOTIFICATIONS);
+ context.startService(serviceIntent);
} else {
- Log.d(TAG, "onReceive: could not handle: " + intent);
+ Log.w(TAG, "onReceive: could not handle: " + intent);
}
}
-
- private VoicemailNotifier getNotifier(Context context) {
- NotificationManager notificationManager =
- (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
- ContentResolver contentResolver = context.getContentResolver();
- return new DefaultVoicemailNotifier(context, notificationManager,
- DefaultVoicemailNotifier.createNewCallsQuery(contentResolver),
- DefaultVoicemailNotifier.createNameLookupQuery(contentResolver),
- DefaultVoicemailNotifier.createPhoneNumberHelper(context));
- }
}
diff --git a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
index bb0b0f3..1cf67c1 100644
--- a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
+++ b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
@@ -51,13 +51,30 @@
/** The identifier of the notification of new voicemails. */
private static final int NOTIFICATION_ID = 1;
+ /** The singleton instance of {@link DefaultVoicemailNotifier}. */
+ private static DefaultVoicemailNotifier sInstance;
+
private final Context mContext;
private final NotificationManager mNotificationManager;
private final NewCallsQuery mNewCallsQuery;
private final NameLookupQuery mNameLookupQuery;
private final PhoneNumberHelper mPhoneNumberHelper;
- public DefaultVoicemailNotifier(Context context,
+ /** Returns the singleton instance of the {@link DefaultVoicemailNotifier}. */
+ public static synchronized DefaultVoicemailNotifier getInstance(Context context) {
+ if (sInstance == null) {
+ NotificationManager notificationManager =
+ (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
+ ContentResolver contentResolver = context.getContentResolver();
+ sInstance = new DefaultVoicemailNotifier(context, notificationManager,
+ createNewCallsQuery(contentResolver),
+ createNameLookupQuery(contentResolver),
+ createPhoneNumberHelper(context));
+ }
+ return sInstance;
+ }
+
+ private DefaultVoicemailNotifier(Context context,
NotificationManager notificationManager, NewCallsQuery newCallsQuery,
NameLookupQuery nameLookupQuery, PhoneNumberHelper phoneNumberHelper) {
mContext = context;
@@ -67,20 +84,9 @@
mPhoneNumberHelper = phoneNumberHelper;
}
- @Override
- public void notifyNewVoicemail(Uri newVoicemailUri) {
- Log.d(TAG, "notifyNewVoicemail: " + newVoicemailUri);
- updateNotification(newVoicemailUri);
- }
-
- @Override
- public void updateNotification() {
- Log.d(TAG, "updateNotification");
- updateNotification(null);
- }
-
/** Updates the notification and notifies of the call with the given URI. */
- private void updateNotification(Uri newCallUri) {
+ @Override
+ public void updateNotification(Uri newCallUri) {
// Lookup the list of new voicemails to include in the notification.
// TODO: Move this into a service, to avoid holding the receiver up.
final NewCall[] newCalls = mNewCallsQuery.query();
diff --git a/src/com/android/contacts/calllog/VoicemailNotifier.java b/src/com/android/contacts/calllog/VoicemailNotifier.java
index 1ac949d..8d45486 100644
--- a/src/com/android/contacts/calllog/VoicemailNotifier.java
+++ b/src/com/android/contacts/calllog/VoicemailNotifier.java
@@ -23,17 +23,15 @@
*/
public interface VoicemailNotifier {
/**
- * Notifies the user of a new voicemail.
+ * Updates the notification and clears it if there are no new voicemails.
+ * <p>
+ * If the given URI corresponds to a new voicemail, also notifies about it.
+ * <p>
+ * It is not safe to call this method from the main thread.
*
- * @param newVoicemailUri URI of the new voicemail record just inserted
+ * @param newCallUri URI of the new call, may be null
*/
- public void notifyNewVoicemail(Uri newVoicemailUri);
-
- /**
- * Updates the notification and clears it if there are no new voicemails. Called when the phone
- * just rebooted to put back notifications for anything the user has not acknowledged.
- */
- public void updateNotification();
+ public void updateNotification(Uri newCallUri);
/** Clears the new voicemail notification. */
public void clearNotification();