Merge "Check voicemail capability when "1" is longpressed"
diff --git a/src/com/android/contacts/CallDetailActivity.java b/src/com/android/contacts/CallDetailActivity.java
index 8d7561a..113a18b 100644
--- a/src/com/android/contacts/CallDetailActivity.java
+++ b/src/com/android/contacts/CallDetailActivity.java
@@ -96,6 +96,7 @@
private PhoneNumberHelper mPhoneNumberHelper;
private PhoneCallDetailsHelper mPhoneCallDetailsHelper;
private TextView mHeaderTextView;
+ private View mHeaderOverlayView;
private ImageView mMainActionView;
private ImageButton mMainActionPushLayerView;
private ImageView mContactBackgroundView;
@@ -240,6 +241,7 @@
mVoicemailStatusHelper = new VoicemailStatusHelperImpl();
mAsyncQueryHandler = new CallDetailActivityQueryHandler(this);
mHeaderTextView = (TextView) findViewById(R.id.header_text);
+ mHeaderOverlayView = findViewById(R.id.photo_text_bar);
mStatusMessageView = findViewById(R.id.voicemail_status);
mStatusMessageText = (TextView) findViewById(R.id.voicemail_status_message);
mStatusMessageAction = (TextView) findViewById(R.id.voicemail_status_action);
@@ -454,6 +456,8 @@
if (mainActionIntent == null) {
mMainActionView.setVisibility(View.INVISIBLE);
mMainActionPushLayerView.setVisibility(View.GONE);
+ mHeaderTextView.setVisibility(View.INVISIBLE);
+ mHeaderOverlayView.setVisibility(View.INVISIBLE);
} else {
mMainActionView.setVisibility(View.VISIBLE);
mMainActionView.setImageResource(mainActionIcon);
@@ -465,6 +469,8 @@
}
});
mMainActionPushLayerView.setContentDescription(mainActionDescription);
+ mHeaderTextView.setVisibility(View.VISIBLE);
+ mHeaderOverlayView.setVisibility(View.VISIBLE);
}
// This action allows to call the number that places the call.
@@ -511,19 +517,27 @@
findViewById(R.id.controls)));
BackScrollManager.bind(
new ScrollableHeader() {
- private View controls = findViewById(R.id.controls);
- private View photo = findViewById(R.id.contact_background_sizer);
- private View nameHeader = findViewById(R.id.photo_text_bar);
+ private View mControls = findViewById(R.id.controls);
+ private View mPhoto = findViewById(R.id.contact_background_sizer);
+ private View mHeader = findViewById(R.id.photo_text_bar);
+ private View mSeparator = findViewById(R.id.blue_separator);
@Override
public void setOffset(int offset) {
- controls.setY(-offset);
+ mControls.setY(-offset);
}
@Override
public int getMaximumScrollableHeaderOffset() {
- // We can scroll the photo out, but we should keep the header.
- return photo.getHeight() - nameHeader.getHeight();
+ // We can scroll the photo out, but we should keep the header if
+ // present.
+ if (mHeader.getVisibility() == View.VISIBLE) {
+ return mPhoto.getHeight() - mHeader.getHeight();
+ } else {
+ // If the header is not present, we should also scroll out the
+ // separator line.
+ return mPhoto.getHeight() + mSeparator.getHeight();
+ }
}
},
historyList);
@@ -720,7 +734,6 @@
private StatusMessage getStatusMessage(Cursor statusCursor) {
List<StatusMessage> messages = mVoicemailStatusHelper.getStatusMessages(statusCursor);
- Log.d(TAG, "Num status messages: " + messages.size());
if (messages.size() == 0) {
return null;
}
diff --git a/src/com/android/contacts/ContactLoader.java b/src/com/android/contacts/ContactLoader.java
index 57defcf..007c1e0 100644
--- a/src/com/android/contacts/ContactLoader.java
+++ b/src/com/android/contacts/ContactLoader.java
@@ -73,8 +73,8 @@
public class ContactLoader extends Loader<ContactLoader.Result> {
private static final String TAG = "ContactLoader";
- private Uri mLookupUri;
private final Uri mRequestedUri;
+ private Uri mLookupUri;
private boolean mLoadGroupMetaData;
private boolean mLoadStreamItems;
private final boolean mLoadInvitableAccountTypes;
@@ -91,10 +91,14 @@
* The result of a load operation. Contains all data necessary to display the contact.
*/
public static final class Result {
- /**
- * Singleton instance that represents "No Contact Found"
- */
- public static final Result NOT_FOUND = new Result((Exception) null);
+ private enum Status {
+ /** Contact is successfully loaded */
+ LOADED,
+ /** There was an error loading the contact */
+ ERROR,
+ /** Contact is not found */
+ NOT_FOUND,
+ }
private final Uri mRequestedUri;
private final Uri mLookupUri;
@@ -130,13 +134,19 @@
private final String mCustomRingtone;
private final boolean mIsUserProfile;
+ private final Status mStatus;
private final Exception mException;
/**
* Constructor for special results, namely "no contact found" and "error".
*/
- private Result(Exception exception) {
- mRequestedUri = null;
+ private Result(Uri requestedUri, Status status, Exception exception) {
+ if (status == Status.ERROR && exception == null) {
+ throw new IllegalArgumentException("ERROR result must have exception");
+ }
+ mStatus = status;
+ mException = exception;
+ mRequestedUri = requestedUri;
mLookupUri = null;
mUri = null;
mDirectoryId = -1;
@@ -158,11 +168,14 @@
mSendToVoicemail = false;
mCustomRingtone = null;
mIsUserProfile = false;
- mException = exception;
}
- private static Result forError(Exception exception) {
- return new Result(exception);
+ private static Result forError(Uri requestedUri, Exception exception) {
+ return new Result(requestedUri, Status.ERROR, exception);
+ }
+
+ private static Result forNotFound(Uri requestedUri) {
+ return new Result(requestedUri, Status.NOT_FOUND, null);
}
/**
@@ -173,6 +186,7 @@
String photoUri, String displayName, String altDisplayName, String phoneticName,
boolean starred, Integer presence, boolean sendToVoicemail, String customRingtone,
boolean isUserProfile) {
+ mStatus = Status.LOADED;
mException = null;
mRequestedUri = requestedUri;
mLookupUri = lookupUri;
@@ -199,6 +213,7 @@
}
private Result(Result from) {
+ mStatus = from.mStatus;
mException = from.mException;
mRequestedUri = from.mRequestedUri;
mLookupUri = from.mLookupUri;
@@ -293,15 +308,36 @@
/**
* @return true when an exception happened during loading, in which case
* {@link #getException} returns the actual exception object.
+ * Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
+ * {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
+ * and vice versa.
*/
public boolean isError() {
- return mException != null;
+ return mStatus == Status.ERROR;
}
public Exception getException() {
return mException;
}
+ /**
+ * @return true when the specified contact is not found.
+ * Note {@link #isNotFound()} and {@link #isError()} are mutually exclusive; If
+ * {@link #isError()} is {@code true}, {@link #isNotFound()} is always {@code false},
+ * and vice versa.
+ */
+ public boolean isNotFound() {
+ return mStatus == Status.NOT_FOUND;
+ }
+
+ /**
+ * @return true if the specified contact is successfully loaded.
+ * i.e. neither {@link #isError()} nor {@link #isNotFound()}.
+ */
+ public boolean isLoaded() {
+ return mStatus == Status.LOADED;
+ }
+
public long getNameRawContactId() {
return mNameRawContactId;
}
@@ -647,7 +683,7 @@
final ContentResolver resolver = getContext().getContentResolver();
final Uri uriCurrentFormat = ensureIsContactUri(resolver, mLookupUri);
Result result = loadContactEntity(resolver, uriCurrentFormat);
- if (result != Result.NOT_FOUND) {
+ if (!result.isNotFound()) {
if (result.isDirectoryEntry()) {
loadDirectoryMetaData(result);
} else if (mLoadGroupMetaData) {
@@ -666,7 +702,7 @@
return result;
} catch (Exception e) {
Log.e(TAG, "Error loading the contact: " + mLookupUri, e);
- return Result.forError(e);
+ return Result.forError(mRequestedUri, e);
}
}
@@ -717,13 +753,13 @@
Contacts.Entity.RAW_CONTACT_ID);
if (cursor == null) {
Log.e(TAG, "No cursor returned in loadContactEntity");
- return Result.NOT_FOUND;
+ return Result.forNotFound(mRequestedUri);
}
try {
if (!cursor.moveToFirst()) {
cursor.close();
- return Result.NOT_FOUND;
+ return Result.forNotFound(mRequestedUri);
}
long currentRawContactId = -1;
@@ -1143,7 +1179,7 @@
mContact = result;
- if (!result.isError() && result != Result.NOT_FOUND) {
+ if (result.isLoaded()) {
mLookupUri = result.getLookupUri();
if (!result.isDirectoryEntry()) {
diff --git a/src/com/android/contacts/calllog/CallLogFragment.java b/src/com/android/contacts/calllog/CallLogFragment.java
index 0628db4..c9a4b5b 100644
--- a/src/com/android/contacts/calllog/CallLogFragment.java
+++ b/src/com/android/contacts/calllog/CallLogFragment.java
@@ -121,7 +121,6 @@
updateVoicemailStatusMessage(statusCursor);
int activeSources = mVoicemailStatusHelper.getNumberActivityVoicemailSources(statusCursor);
- Log.d(TAG, "Num active sources: " + activeSources);
setVoicemailSourcesAvailable(activeSources != 0);
MoreCloseables.closeQuietly(statusCursor);
}
diff --git a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
index f795a9c..c4fb36c 100644
--- a/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
+++ b/src/com/android/contacts/calllog/DefaultVoicemailNotifier.java
@@ -161,14 +161,12 @@
final Intent contentIntent;
if (newCalls.length == 1) {
// Open the voicemail directly.
- Log.d(TAG, "Opening voicemail directly on select");
contentIntent = new Intent(mContext, CallDetailActivity.class);
contentIntent.setData(newCalls[0].callsUri);
contentIntent.putExtra(CallDetailActivity.EXTRA_VOICEMAIL_URI,
newCalls[0].voicemailUri);
} else {
// Open the call log.
- Log.d(TAG, "Opening call log on select");
contentIntent = new Intent(Intent.ACTION_VIEW, Calls.CONTENT_URI);
}
notification.contentIntent = PendingIntent.getActivity(mContext, 0, contentIntent, 0);
@@ -250,7 +248,6 @@
while (cursor.moveToNext()) {
newCalls[cursor.getPosition()] = createNewCallsFromCursor(cursor);
}
- Log.d(TAG, "DefaultNewCallsQuery: " + newCalls.length + " new calls");
return newCalls;
} finally {
MoreCloseables.closeQuietly(cursor);
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index f3f8e8a..767d366 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -39,6 +39,7 @@
import com.android.contacts.util.Constants;
import com.android.contacts.util.DataStatus;
import com.android.contacts.util.DateUtils;
+import com.android.contacts.util.StructuredPostalUtils;
import com.android.contacts.util.PhoneCapabilityTester;
import com.android.contacts.widget.TransitionAnimationView;
import com.android.internal.telephony.ITelephony;
@@ -634,8 +635,7 @@
} else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
// Build postal entries
entry.maxLines = POSTAL_ADDRESS_MAX_LINES;
- entry.intent = new Intent(
- Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=" + Uri.encode(entry.data)));
+ entry.intent = StructuredPostalUtils.getViewPostalAddressIntent(entry.data);
mPostalEntries.add(entry);
} else if (Im.CONTENT_ITEM_TYPE.equals(mimeType) && hasData) {
// Build IM entries
diff --git a/src/com/android/contacts/detail/ContactLoaderFragment.java b/src/com/android/contacts/detail/ContactLoaderFragment.java
index 9417ee7..692c2ea 100644
--- a/src/com/android/contacts/detail/ContactLoaderFragment.java
+++ b/src/com/android/contacts/detail/ContactLoaderFragment.java
@@ -191,7 +191,7 @@
// This shouldn't ever happen, so throw an exception. The {@link ContactLoader}
// should log the actual exception.
throw new IllegalStateException("Failed to load contact", data.getException());
- } else if (data == ContactLoader.Result.NOT_FOUND) {
+ } else if (data.isNotFound()) {
Log.i(TAG, "No contact found: " + ((ContactLoader)loader).getLookupUri());
mContactData = null;
} else {
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index f7e0c23..844f892 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -1710,7 +1710,7 @@
public void onLoadFinished(Loader<ContactLoader.Result> loader, ContactLoader.Result data) {
final long loaderCurrentTime = SystemClock.elapsedRealtime();
Log.v(TAG, "Time needed for loading: " + (loaderCurrentTime-mLoaderStartTime));
- if (data == ContactLoader.Result.NOT_FOUND || data.isError()) {
+ if (!data.isLoaded()) {
// Item has been deleted
Log.i(TAG, "No contact found. Closing activity");
if (mListener != null) mListener.onContactNotFound();
diff --git a/src/com/android/contacts/quickcontact/DataAction.java b/src/com/android/contacts/quickcontact/DataAction.java
index 88b3843..84a34bd 100644
--- a/src/com/android/contacts/quickcontact/DataAction.java
+++ b/src/com/android/contacts/quickcontact/DataAction.java
@@ -21,6 +21,7 @@
import com.android.contacts.model.AccountType.EditType;
import com.android.contacts.model.DataKind;
import com.android.contacts.util.Constants;
+import com.android.contacts.util.StructuredPostalUtils;
import com.android.contacts.util.PhoneCapabilityTester;
import android.content.ContentUris;
@@ -35,6 +36,7 @@
import android.provider.ContactsContract.CommonDataKinds.Im;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
+import android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.provider.ContactsContract.Data;
import android.text.TextUtils;
@@ -202,6 +204,11 @@
}
}
}
+ } else if (StructuredPostal.CONTENT_ITEM_TYPE.equals(mimeType)) {
+ final String postalAddress = getAsString(cursor, StructuredPostal.FORMATTED_ADDRESS);
+ if (!TextUtils.isEmpty(postalAddress)) {
+ mIntent = StructuredPostalUtils.getViewPostalAddressIntent(postalAddress);
+ }
}
if (mIntent == null) {
diff --git a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
index 9f7e18f..2ce15ff 100644
--- a/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
+++ b/src/com/android/contacts/socialwidget/SocialWidgetProvider.java
@@ -133,7 +133,7 @@
final RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.social_widget);
- if (contactData.isError() || contactData == ContactLoader.Result.NOT_FOUND) {
+ if (!contactData.isLoaded()) {
setDisplayNameAndSnippet(context, views,
context.getString(R.string.invalidContactMessage), null, null, null);
setPhoto(views, ContactBadgeUtil.loadDefaultAvatarPhoto(context, false, false));
diff --git a/src/com/android/contacts/util/StructuredPostalUtils.java b/src/com/android/contacts/util/StructuredPostalUtils.java
new file mode 100644
index 0000000..59d38ea
--- /dev/null
+++ b/src/com/android/contacts/util/StructuredPostalUtils.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.util;
+
+import android.content.Intent;
+import android.net.Uri;
+
+public class StructuredPostalUtils {
+ private StructuredPostalUtils() {
+ }
+
+ public static Intent getViewPostalAddressIntent(String postalAddress) {
+ return new Intent(Intent.ACTION_VIEW, getPostalAddressUri(postalAddress));
+ }
+
+ public static Uri getPostalAddressUri(String postalAddress) {
+ return Uri.parse("geo:0,0?q=" + Uri.encode(postalAddress));
+ }
+}