Merge "Show separate pressed effect for primary/secondary actions"
diff --git a/src/com/android/contacts/activities/DialpadActivity.java b/src/com/android/contacts/activities/DialpadActivity.java
index cfe17f3..1221068 100644
--- a/src/com/android/contacts/activities/DialpadActivity.java
+++ b/src/com/android/contacts/activities/DialpadActivity.java
@@ -64,7 +64,7 @@
@Override
protected void onNewIntent(Intent newIntent) {
setIntent(newIntent);
- mFragment.resolveIntent(newIntent);
+ mFragment.configureScreenFromIntent(newIntent);
}
public DialpadFragment getFragment() {
diff --git a/src/com/android/contacts/activities/DialtactsActivity.java b/src/com/android/contacts/activities/DialtactsActivity.java
index 01212f5..2040f8d 100644
--- a/src/com/android/contacts/activities/DialtactsActivity.java
+++ b/src/com/android/contacts/activities/DialtactsActivity.java
@@ -481,12 +481,18 @@
final String action = newIntent.getAction();
if (UI.FILTER_CONTACTS_ACTION.equals(action)) {
setupFilterText(newIntent);
- } else if (isDialIntent(newIntent)) {
- setupDialUri(newIntent);
}
if (mInSearchUi || mSearchFragment.isVisible()) {
exitSearchUi();
}
+
+ if (mViewPager.getCurrentItem() == TAB_INDEX_DIALER) {
+ if (mDialpadFragment != null) {
+ mDialpadFragment.configureScreenFromIntent(newIntent);
+ } else {
+ Log.e(TAG, "DialpadFragment isn't ready yet when the tab is already selected.");
+ }
+ }
}
/** Returns true if the given intent contains a phone number to populate the dialer with */
@@ -535,33 +541,6 @@
}
}
- /**
- * Retrieves the uri stored in {@link #setupDialUri(Intent)}. This uri
- * originally came from a dial intent received by this activity. The stored
- * uri will then be cleared after after this method returns.
- *
- * @return The stored uri
- */
- public Uri getAndClearDialUri() {
- Uri dialUri = mDialUri;
- mDialUri = null;
- return dialUri;
- }
-
- /**
- * Stores the uri associated with a dial intent. This is so child activities can
- * check if they are supposed to display new dial info.
- *
- * @param intent The intent received in {@link #onNewIntent(Intent)}
- */
- private void setupDialUri(Intent intent) {
- // If the intent was relaunched from history, don't reapply the intent.
- if ((intent.getFlags() & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
- return;
- }
- mDialUri = intent.getData();
- }
-
@Override
public void onBackPressed() {
if (mInSearchUi) {
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();
diff --git a/src/com/android/contacts/dialpad/DialpadFragment.java b/src/com/android/contacts/dialpad/DialpadFragment.java
index add6b80..a5db5ce 100644
--- a/src/com/android/contacts/dialpad/DialpadFragment.java
+++ b/src/com/android/contacts/dialpad/DialpadFragment.java
@@ -143,9 +143,6 @@
static final String EXTRA_SEND_EMPTY_FLASH
= "com.android.phone.extra.SEND_EMPTY_FLASH";
- /** Indicates if we are opening this dialer to add a call from the InCallScreen. */
- private boolean mIsAddCallMode;
-
private String mCurrentCountryIso;
/**
@@ -313,7 +310,7 @@
mDialpadChooser = (ListView) fragmentView.findViewById(R.id.dialpadChooser);
mDialpadChooser.setOnItemClickListener(this);
- resolveIntent(getActivity().getIntent());
+ configureScreenFromIntent(getActivity().getIntent());
return fragmentView;
}
@@ -323,38 +320,18 @@
}
/**
- * Handles the intent that launched us.
- *
- * We can be launched either with ACTION_DIAL or ACTION_VIEW (which
- * may include a phone number to pre-load), or ACTION_MAIN (which just
- * brings up a blank dialpad).
- *
- * @return true IFF the current intent has the DialtactsActivity.EXTRA_IGNORE_STATE
- * extra set to true, which indicates (to our container) that we should ignore
- * any possible saved state, and instead reset our state based on the parent's
- * intent.
+ * @return true when {@link #mDigits} is actually filled by the Intent.
*/
- public boolean resolveIntent(Intent intent) {
- boolean ignoreState = false;
-
- // by default we are not adding a call.
- mIsAddCallMode = false;
-
- // By default we don't show the "dialpad chooser" UI.
- boolean needToShowDialpadChooser = false;
-
- // Resolve the intent
+ private boolean fillDigitsIfNecessary(Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
- // see if we are "adding a call" from the InCallScreen; false by default.
- mIsAddCallMode = intent.getBooleanExtra(ADD_CALL_MODE_KEY, false);
-
Uri uri = intent.getData();
if (uri != null) {
if ("tel".equals(uri.getScheme())) {
// Put the requested number into the input area
String data = uri.getSchemeSpecificPart();
setFormattedDigits(data, null);
+ return true;
} else {
String type = intent.getType();
if (People.CONTENT_ITEM_TYPE.equals(type)
@@ -364,22 +341,42 @@
new String[] {PhonesColumns.NUMBER, PhonesColumns.NUMBER_KEY},
null, null, null);
if (c != null) {
- if (c.moveToFirst()) {
- // Put the number into the input area
- setFormattedDigits(c.getString(0), c.getString(1));
+ try {
+ if (c.moveToFirst()) {
+ // Put the number into the input area
+ setFormattedDigits(c.getString(0), c.getString(1));
+ return true;
+ }
+ } finally {
+ c.close();
}
- c.close();
}
}
}
- } else {
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @see #showDialpadChooser(boolean)
+ */
+ private static boolean needToShowDialpadChooser(Intent intent, boolean isAddCallMode) {
+ final String action = intent.getAction();
+
+ boolean needToShowDialpadChooser = false;
+
+ if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
+ Uri uri = intent.getData();
+ if (uri == null) {
// ACTION_DIAL or ACTION_VIEW with no data.
// This behaves basically like ACTION_MAIN: If there's
// already an active call, bring up an intermediate UI to
// make the user confirm what they really want to do.
// Be sure *not* to show the dialpad chooser if this is an
// explicit "Add call" action, though.
- if (!mIsAddCallMode && phoneIsInUse()) {
+ if (!isAddCallMode && phoneIsInUse()) {
needToShowDialpadChooser = true;
}
}
@@ -399,11 +396,34 @@
}
}
- // Bring up the "dialpad chooser" IFF we need to make the user
- // confirm which dialpad they really want.
- showDialpadChooser(needToShowDialpadChooser);
+ return needToShowDialpadChooser;
+ }
- return ignoreState;
+ private static boolean isAddCallMode(Intent intent) {
+ final String action = intent.getAction();
+ if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
+ // see if we are "adding a call" from the InCallScreen; false by default.
+ return intent.getBooleanExtra(ADD_CALL_MODE_KEY, false);
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Checks the given Intent and changes dialpad's UI state. For example, if the Intent requires
+ * the screen to enter "Add Call" mode, this method will show correct UI for the mode.
+ */
+ public void configureScreenFromIntent(Intent intent) {
+ boolean needToShowDialpadChooser = false;
+
+ final boolean isAddCallMode = isAddCallMode(intent);
+ if (!isAddCallMode) {
+ final boolean digitsFilled = fillDigitsIfNecessary(intent);
+ if (!digitsFilled) {
+ needToShowDialpadChooser = needToShowDialpadChooser(intent, isAddCallMode);
+ }
+ }
+ showDialpadChooser(needToShowDialpadChooser);
}
private void setFormattedDigits(String data, String normalizedNumber) {
@@ -476,13 +496,10 @@
}
Activity parent = getActivity();
- // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
- // digits in the dialer field.
if (parent instanceof DialtactsActivity) {
- Uri dialUri = ((DialtactsActivity) parent).getAndClearDialUri();
- if (dialUri != null) {
- resolveIntent(parent.getIntent());
- }
+ // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
+ // digits in the dialer field.
+ fillDigitsIfNecessary(parent.getIntent());
}
// While we're in the foreground, listen for phone state changes,
@@ -904,8 +921,8 @@
// ListView. We do this only once.
if (mDialpadChooserAdapter == null) {
mDialpadChooserAdapter = new DialpadChooserAdapter(getActivity());
- mDialpadChooser.setAdapter(mDialpadChooserAdapter);
}
+ mDialpadChooser.setAdapter(mDialpadChooserAdapter);
} else {
// Log.i(TAG, "Displaying normal Dialer UI.");
mDigits.setVisibility(View.VISIBLE);