Merge "revert the stripping of System Group: from the names of google system groups" into froyo
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index 3aa5098..6fd03f7 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -3287,8 +3287,6 @@
foundContactsText.setText(text);
}
- mPhotoLoader.clear();
-
super.changeCursor(cursor);
// Update the indexer for the fast scroll widget
updateIndexer(cursor);
diff --git a/src/com/android/contacts/ImportVCardActivity.java b/src/com/android/contacts/ImportVCardActivity.java
index a8b3f1e..4dcf5d5 100644
--- a/src/com/android/contacts/ImportVCardActivity.java
+++ b/src/com/android/contacts/ImportVCardActivity.java
@@ -31,6 +31,7 @@
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
+import android.os.FileUtils;
import android.os.Handler;
import android.os.PowerManager;
import android.pim.vcard.VCardConfig;
@@ -53,9 +54,12 @@
import android.text.style.RelativeSizeSpan;
import android.util.Log;
+import java.io.BufferedOutputStream;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.io.OutputStream;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
@@ -153,6 +157,7 @@
private boolean mCanceled;
private PowerManager.WakeLock mWakeLock;
private Uri mUri;
+ private File mTempFile;
private List<VCardFile> mSelectedVCardFileList;
private List<String> mErrorFileNameList;
@@ -190,11 +195,18 @@
boolean shouldCallFinish = true;
mWakeLock.acquire();
Uri createdUri = null;
+ mTempFile = null;
// Some malicious vCard data may make this thread broken
// (e.g. OutOfMemoryError).
// Even in such cases, some should be done.
try {
if (mUri != null) { // Read one vCard expressed by mUri
+ final Uri uri = getReopenableUri(mUri);
+ if (uri == null) {
+ shouldCallFinish = false;
+ return;
+ }
+
mProgressDialogForReadVCard.setProgressNumberFormat("");
mProgressDialogForReadVCard.setProgress(0);
@@ -208,16 +220,15 @@
VCardSourceDetector detector = new VCardSourceDetector();
VCardInterpreterCollection builderCollection = new VCardInterpreterCollection(
Arrays.asList(counter, detector));
-
boolean result;
try {
- result = readOneVCardFile(mUri,
+ result = readOneVCardFile(uri,
VCardConfig.DEFAULT_CHARSET, builderCollection, null, true, null);
} catch (VCardNestedException e) {
try {
// Assume that VCardSourceDetector was able to detect the source.
// Try again with the detector.
- result = readOneVCardFile(mUri,
+ result = readOneVCardFile(uri,
VCardConfig.DEFAULT_CHARSET, counter, detector, false, null);
} catch (VCardNestedException e2) {
result = false;
@@ -239,7 +250,7 @@
mProgressDialogForReadVCard.setIndeterminate(false);
mProgressDialogForReadVCard.setMax(counter.getCount());
String charset = detector.getEstimatedCharset();
- createdUri = doActuallyReadOneVCard(mUri, null, charset, true, detector,
+ createdUri = doActuallyReadOneVCard(uri, null, charset, true, detector,
mErrorFileNameList);
} else { // Read multiple files.
mProgressDialogForReadVCard.setProgressNumberFormat(
@@ -251,7 +262,13 @@
if (mCanceled) {
return;
}
- final Uri uri = Uri.parse("file://" + vcardFile.getCanonicalPath());
+ // TODO: detect scheme!
+ final Uri uri = getReopenableUri(
+ Uri.parse("file://" + vcardFile.getCanonicalPath()));
+ if (uri == null) {
+ shouldCallFinish = false;
+ return;
+ }
VCardSourceDetector detector = new VCardSourceDetector();
try {
@@ -271,6 +288,12 @@
} finally {
mWakeLock.release();
mProgressDialogForReadVCard.dismiss();
+ if (mTempFile != null) {
+ if (!mTempFile.delete()) {
+ Log.w(LOG_TAG, "Failed to delete a cache file.");
+ }
+ mTempFile = null;
+ }
// finish() is called via mCancelListener, which is used in DialogDisplayer.
if (shouldCallFinish && !isFinishing()) {
if (mErrorFileNameList == null || mErrorFileNameList.isEmpty()) {
@@ -310,6 +333,49 @@
}
}
+ private Uri getReopenableUri(final Uri uri) {
+ if ("file".equals(uri.getScheme())) {
+ return uri;
+ } else {
+ // We may not be able to scan a given uri more than once when it does not
+ // point to a local file, while it is necessary to scan it more than once
+ // because of vCard limitation. We rely on a local temporary file instead.
+ //
+ // e.g. Email app's AttachmentProvider is able to give us a content Uri
+ // with an attachment file, but we cannot "sometimes" (not always) scan
+ // the Uri more than once because of permission revocation.
+ InputStream is = null;
+ OutputStream os = null;
+ Uri reopenableUri = null;
+ try {
+ is = mResolver.openInputStream(uri);
+ File dir = getDir("tmp", MODE_PRIVATE);
+ mTempFile = dir.createTempFile("vcf", null, dir);
+ FileUtils.copyToFile(is, mTempFile);
+ reopenableUri = Uri.parse("file://" + mTempFile.getCanonicalPath());
+ } catch (IOException e) {
+ mHandler.post(new DialogDisplayer(
+ getString(R.string.fail_reason_io_error) +
+ ": " + e.getLocalizedMessage()));
+ return null;
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ }
+ }
+ if (os != null) {
+ try {
+ os.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ return reopenableUri;
+ }
+ }
+
private Uri doActuallyReadOneVCard(Uri uri, Account account,
String charset, boolean showEntryParseProgress,
VCardSourceDetector detector, List<String> errorFileNameList) {
diff --git a/src/com/android/contacts/ViewContactActivity.java b/src/com/android/contacts/ViewContactActivity.java
index 2b2a8f7..ead6a4a 100644
--- a/src/com/android/contacts/ViewContactActivity.java
+++ b/src/com/android/contacts/ViewContactActivity.java
@@ -402,7 +402,7 @@
// Contains an Id.
final long uriContactId = Long.parseLong(segments.get(3));
- final String uriLookupKey = segments.get(2);
+ final String uriLookupKey = Uri.encode(segments.get(2));
final Uri dataUri = Uri.withAppendedPath(
ContentUris.withAppendedId(Contacts.CONTENT_URI, uriContactId),
Contacts.Data.CONTENT_DIRECTORY);
diff --git a/src/com/android/contacts/ui/EditContactActivity.java b/src/com/android/contacts/ui/EditContactActivity.java
index 25132fb..c70cff6 100644
--- a/src/com/android/contacts/ui/EditContactActivity.java
+++ b/src/com/android/contacts/ui/EditContactActivity.java
@@ -67,7 +67,6 @@
import android.provider.ContactsContract.RawContacts;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts.Data;
import android.util.Log;
import android.view.ContextThemeWrapper;
@@ -111,6 +110,9 @@
private static final String KEY_EDIT_STATE = "state";
private static final String KEY_RAW_CONTACT_ID_REQUESTING_PHOTO = "photorequester";
private static final String KEY_VIEW_ID_GENERATOR = "viewidgenerator";
+ private static final String KEY_CURRENT_PHOTO_FILE = "currentphotofile";
+ private static final String KEY_QUERY_SELECTION = "queryselection";
+ private static final String KEY_CONTACT_ID_FOR_JOIN = "contactidforjoin";
/** The result code when view activity should close after edit returns */
public static final int RESULT_CLOSE_VIEW_ACTIVITY = 777;
@@ -265,6 +267,11 @@
outState.putLong(KEY_RAW_CONTACT_ID_REQUESTING_PHOTO, mRawContactIdRequestingPhoto);
outState.putParcelable(KEY_VIEW_ID_GENERATOR, mViewIdGenerator);
+ if (mCurrentPhotoFile != null) {
+ outState.putString(KEY_CURRENT_PHOTO_FILE, mCurrentPhotoFile.toString());
+ }
+ outState.putString(KEY_QUERY_SELECTION, mQuerySelection);
+ outState.putLong(KEY_CONTACT_ID_FOR_JOIN, mContactIdForJoin);
super.onSaveInstanceState(outState);
}
@@ -275,6 +282,13 @@
mRawContactIdRequestingPhoto = savedInstanceState.getLong(
KEY_RAW_CONTACT_ID_REQUESTING_PHOTO);
mViewIdGenerator = savedInstanceState.getParcelable(KEY_VIEW_ID_GENERATOR);
+ String fileName = savedInstanceState.getString(KEY_CURRENT_PHOTO_FILE);
+ if (fileName != null) {
+ mCurrentPhotoFile = new File(fileName);
+ }
+ mQuerySelection = savedInstanceState.getString(KEY_QUERY_SELECTION);
+ mContactIdForJoin = savedInstanceState.getLong(KEY_CONTACT_ID_FOR_JOIN);
+
bindEditors();
super.onRestoreInstanceState(savedInstanceState);
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 593d6cc..7af1a54 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -31,6 +31,11 @@
android:targetPackage="com.android.contacts"
android:label="Contacts launch performance">
</instrumentation>
-
+
+
+ <instrumentation android:name="com.android.contacts.DialerLaunchPerformance"
+ android:targetPackage="com.android.contacts"
+ android:label="Dialer launch performance">
+ </instrumentation>
</manifest>
diff --git a/tests/src/com/android/contacts/ContactsLaunchPerformance.java b/tests/src/com/android/contacts/ContactsLaunchPerformance.java
index bd60e70..9177457 100644
--- a/tests/src/com/android/contacts/ContactsLaunchPerformance.java
+++ b/tests/src/com/android/contacts/ContactsLaunchPerformance.java
@@ -17,25 +17,22 @@
package com.android.contacts;
import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
import android.test.LaunchPerformanceBase;
import android.os.Bundle;
-import java.util.Map;
-
/**
* Instrumentation class for Address Book launch performance testing.
*/
public class ContactsLaunchPerformance extends LaunchPerformanceBase {
- public static final String LOG_TAG = "ContactsLaunchPerformance";
-
- public ContactsLaunchPerformance() {
- super();
- }
-
@Override
public void onCreate(Bundle arguments) {
- mIntent.setClassName(getTargetContext(), "com.android.contacts.ContactsListActivity");
+ mIntent.setAction(Intent.ACTION_MAIN);
+ mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ mIntent.setComponent(new ComponentName("com.android.contacts",
+ "com.android.contacts.DialtactsContactsEntryActivity"));
start();
}
diff --git a/tests/src/com/android/contacts/DialerLaunchPerformance.java b/tests/src/com/android/contacts/DialerLaunchPerformance.java
new file mode 100644
index 0000000..ae78082
--- /dev/null
+++ b/tests/src/com/android/contacts/DialerLaunchPerformance.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2007 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;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.os.Bundle;
+import android.test.LaunchPerformanceBase;
+
+/**
+ * Instrumentation class for Address Book launch performance testing.
+ */
+public class DialerLaunchPerformance extends LaunchPerformanceBase {
+
+ @Override
+ public void onCreate(Bundle arguments) {
+ mIntent.setAction(Intent.ACTION_MAIN);
+ mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+ mIntent.setComponent(new ComponentName("com.android.contacts",
+ "com.android.contacts.DialtactsActivity"));
+
+ start();
+ }
+
+ /**
+ * Calls LaunchApp and finish.
+ */
+ @Override
+ public void onStart() {
+ super.onStart();
+ LaunchApp();
+ finish(Activity.RESULT_OK, mResults);
+ }
+}
diff --git a/tests/src/com/android/contacts/EntityDeltaTests.java b/tests/src/com/android/contacts/EntityDeltaTests.java
index 70a506b..fa716c7 100644
--- a/tests/src/com/android/contacts/EntityDeltaTests.java
+++ b/tests/src/com/android/contacts/EntityDeltaTests.java
@@ -367,7 +367,7 @@
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
source.buildAssert(diff);
source.buildDiff(diff);
- assertEquals("Unexpected operations", 1, diff.size());
+ assertEquals("Unexpected operations", 2, diff.size());
{
final ContentProviderOperation oper = diff.get(0);
assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
@@ -395,7 +395,7 @@
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
source.buildAssert(diff);
source.buildDiff(diff);
- assertEquals("Unexpected operations", 2, diff.size());
+ assertEquals("Unexpected operations", 3, diff.size());
{
final ContentProviderOperation oper = diff.get(0);
assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
diff --git a/tests/src/com/android/contacts/EntityModifierTests.java b/tests/src/com/android/contacts/EntityModifierTests.java
index 4bc4622..18877a3 100644
--- a/tests/src/com/android/contacts/EntityModifierTests.java
+++ b/tests/src/com/android/contacts/EntityModifierTests.java
@@ -512,7 +512,7 @@
// Build diff, expecting single insert
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
state.buildDiff(diff);
- assertEquals("Unexpected operations", 1, diff.size());
+ assertEquals("Unexpected operations", 2, diff.size());
{
final ContentProviderOperation oper = diff.get(0);
assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
@@ -540,7 +540,7 @@
// Build diff, expecting two insert operations
final ArrayList<ContentProviderOperation> diff = Lists.newArrayList();
state.buildDiff(diff);
- assertEquals("Unexpected operations", 2, diff.size());
+ assertEquals("Unexpected operations", 3, diff.size());
{
final ContentProviderOperation oper = diff.get(0);
assertEquals("Incorrect type", TYPE_INSERT, oper.getType());
diff --git a/tests/src/com/android/contacts/EntitySetTests.java b/tests/src/com/android/contacts/EntitySetTests.java
index c9fc3fa..edfca6d 100644
--- a/tests/src/com/android/contacts/EntitySetTests.java
+++ b/tests/src/com/android/contacts/EntitySetTests.java
@@ -486,6 +486,7 @@
buildAssertVersion(VER_FIRST),
buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, joeContactInsert),
buildOper(Data.CONTENT_URI, TYPE_INSERT, joePhoneInsert),
+ buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT),
buildUpdateAggregationKeepTogether(CONTACT_BOB));
// Merge in the second version, verify that our insert remains
@@ -495,6 +496,7 @@
buildAssertVersion(VER_SECOND),
buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, joeContactInsert),
buildOper(Data.CONTENT_URI, TYPE_INSERT, joePhoneInsert),
+ buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT),
buildUpdateAggregationKeepTogether(CONTACT_BOB));
}
@@ -545,6 +547,7 @@
buildAssertVersion(VER_SECOND),
buildOper(RawContacts.CONTENT_URI, TYPE_INSERT, contactInsert),
buildOper(Data.CONTENT_URI, TYPE_INSERT, phoneInsert),
+ buildAggregationModeUpdate(RawContacts.AGGREGATION_MODE_DEFAULT),
buildUpdateAggregationKeepTogether(CONTACT_BOB));
}