summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Birg <roman@cyngn.com>2014-11-13 16:32:40 -0800
committerRoman Birg <roman@cyngn.com>2014-11-13 16:54:58 -0800
commit23cbeecd6e226fe295e9943d0c18e78bccd10f33 (patch)
tree7e4d6cf424a3e34123104b38e862945474f092ef
parent430baf7f2c94010c77be9893c1371d7858899e34 (diff)
downloadpackages_apps_ContactsCommon-23cbeecd6e226fe295e9943d0c18e78bccd10f33.tar.gz
packages_apps_ContactsCommon-23cbeecd6e226fe295e9943d0c18e78bccd10f33.tar.bz2
packages_apps_ContactsCommon-23cbeecd6e226fe295e9943d0c18e78bccd10f33.zip
ContactsCommon: fix import vcard memory leak
Spawining a bunch of imports at the same time will result in a SystemUI crash due to hold on to Activity context beyond its lifecycle. Change-Id: Id6e9a386bb19a1eb79377472b1bd1696c53d8bbf Signed-off-by: Roman Birg <roman@cyngn.com>
-rw-r--r--src/com/android/contacts/common/editor/SelectAccountDialogFragment.java33
-rw-r--r--src/com/android/contacts/common/vcard/ImportVCardActivity.java54
-rw-r--r--src/com/android/contacts/common/vcard/NotificationImportExportListener.java11
3 files changed, 58 insertions, 40 deletions
diff --git a/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java b/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java
index 26fc7712..bf27cc12 100644
--- a/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java
+++ b/src/com/android/contacts/common/editor/SelectAccountDialogFragment.java
@@ -40,6 +40,8 @@ public final class SelectAccountDialogFragment extends DialogFragment {
private static final String KEY_LIST_FILTER = "list_filter";
private static final String KEY_EXTRA_ARGS = "extra_args";
+ Listener mListener = null;
+
public SelectAccountDialogFragment() { // All fragments must have a public default constructor.
}
@@ -68,6 +70,35 @@ public final class SelectAccountDialogFragment extends DialogFragment {
instance.show(fragmentManager, SelectAccountDialogFragment.TAG);
}
+ /**
+ * Show the dialog.
+ *
+ * @param fragmentManager {@link FragmentManager}.
+ * @param targetFragment {@link Fragment} that implements {@link Listener}.
+ * @param titleResourceId resource ID to use as the title.
+ * @param accountListFilter account filter.
+ * @param extraArgs Extra arguments, which will later be passed to
+ * {@link Listener#onAccountChosen}. {@code null} will be converted to
+ * {@link Bundle#EMPTY}.
+ */
+ public static <F extends Listener> void show(FragmentManager fragmentManager,
+ F targetFragment, int titleResourceId,
+ AccountListFilter accountListFilter, Bundle extraArgs) {
+ final Bundle args = new Bundle();
+ args.putInt(KEY_TITLE_RES_ID, titleResourceId);
+ args.putSerializable(KEY_LIST_FILTER, accountListFilter);
+ args.putBundle(KEY_EXTRA_ARGS, (extraArgs == null) ? Bundle.EMPTY : extraArgs);
+
+ final SelectAccountDialogFragment instance = new SelectAccountDialogFragment();
+ instance.setArguments(args);
+ instance.setTargetListener(targetFragment);
+ instance.show(fragmentManager, SelectAccountDialogFragment.TAG);
+ }
+
+ public void setTargetListener(Listener listener) {
+ mListener = listener;
+ }
+
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
@@ -111,6 +142,8 @@ public final class SelectAccountDialogFragment extends DialogFragment {
if (targetFragment != null && targetFragment instanceof Listener) {
final Listener target = (Listener) targetFragment;
target.onAccountChosen(account, getArguments().getBundle(KEY_EXTRA_ARGS));
+ } else if (mListener != null) {
+ mListener.onAccountChosen(account, getArguments().getBundle(KEY_EXTRA_ARGS));
}
}
diff --git a/src/com/android/contacts/common/vcard/ImportVCardActivity.java b/src/com/android/contacts/common/vcard/ImportVCardActivity.java
index 8e444ad7..c15d5df0 100644
--- a/src/com/android/contacts/common/vcard/ImportVCardActivity.java
+++ b/src/com/android/contacts/common/vcard/ImportVCardActivity.java
@@ -47,10 +47,12 @@ import android.util.Log;
import android.widget.Toast;
import com.android.contacts.common.R;
+import com.android.contacts.common.editor.SelectAccountDialogFragment;
import com.android.contacts.common.model.AccountTypeManager;
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.MoreContactUtils;
import com.android.contacts.common.util.AccountSelectionUtil;
+import com.android.contacts.common.util.AccountsListAdapter;
import com.android.vcard.VCardEntryCounter;
import com.android.vcard.VCardParser;
import com.android.vcard.VCardParser_V21;
@@ -90,11 +92,9 @@ import java.util.regex.Pattern;
* any Dialog in the instance. So this code is careless about the management around managed
* dialogs stuffs (like how onCreateDialog() is used).
*/
-public class ImportVCardActivity extends Activity {
+public class ImportVCardActivity extends Activity implements SelectAccountDialogFragment.Listener {
private static final String LOG_TAG = "VCardImport";
- private static final int SELECT_ACCOUNT = 0;
-
/* package */ static final String VCARD_URI_ARRAY = "vcard_uri";
/* package */ static final String ESTIMATED_VCARD_TYPE_ARRAY = "estimated_vcard_type";
/* package */ static final String ESTIMATED_CHARSET_ARRAY = "estimated_charset";
@@ -124,8 +124,6 @@ public class ImportVCardActivity extends Activity {
// Connect status,default value is STATUS_DEFAULT.
private int mConnectStatus = STATUS_DEFAULT;
- private AccountSelectionUtil.AccountSelectedListener mAccountSelectionListener;
-
private AccountWithDataSet mAccount;
private ProgressDialog mProgressDialogForScanVCard;
@@ -143,6 +141,17 @@ public class ImportVCardActivity extends Activity {
private Handler mHandler = new Handler();
+ @Override
+ public void onAccountChosen(AccountWithDataSet account, Bundle extraArgs) {
+ mAccount = account;
+ startImport();
+ }
+
+ @Override
+ public void onAccountSelectorCancelled() {
+ finish();
+ }
+
private static class VCardFile {
private final String mName;
private final String mCanonicalPath;
@@ -803,7 +812,7 @@ public class ImportVCardActivity extends Activity {
public void run() {
if (!isFinishing()) {
mVCardCacheThread = new VCardCacheThread(uris);
- mListener = new NotificationImportExportListener(ImportVCardActivity.this);
+ mListener = new NotificationImportExportListener(ImportVCardActivity.this.getApplication());
showDialog(R.id.dialog_cache_vcard);
}
}
@@ -891,8 +900,11 @@ public class ImportVCardActivity extends Activity {
} else if (accountList.size() == 1) {
mAccount = accountList.get(0);
} else {
- startActivityForResult(new Intent(this, SelectAccountActivity.class),
- SELECT_ACCOUNT);
+ SelectAccountDialogFragment.show(
+ getFragmentManager(), this,
+ R.string.dialog_new_contact_account,
+ AccountsListAdapter.AccountListFilter.ACCOUNTS_CONTACT_WRITABLE_WITHOUT_SIM,
+ null);
return;
}
}
@@ -900,24 +912,6 @@ public class ImportVCardActivity extends Activity {
startImport();
}
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent intent) {
- if (requestCode == SELECT_ACCOUNT) {
- if (resultCode == Activity.RESULT_OK) {
- mAccount = new AccountWithDataSet(
- intent.getStringExtra(SelectAccountActivity.ACCOUNT_NAME),
- intent.getStringExtra(SelectAccountActivity.ACCOUNT_TYPE),
- intent.getStringExtra(SelectAccountActivity.DATA_SET));
- startImport();
- } else {
- if (resultCode != Activity.RESULT_CANCELED) {
- Log.w(LOG_TAG, "Result code was not OK nor CANCELED: " + resultCode);
- }
- finish();
- }
- }
- }
-
private void startImport() {
Intent intent = getIntent();
// Handle inbound files
@@ -975,14 +969,6 @@ public class ImportVCardActivity extends Activity {
@Override
protected Dialog onCreateDialog(int resId, Bundle bundle) {
switch (resId) {
- case R.string.import_from_sdcard: {
- if (mAccountSelectionListener == null) {
- throw new NullPointerException(
- "mAccountSelectionListener must not be null.");
- }
- return AccountSelectionUtil.getSelectAccountDialog(this, resId,
- mAccountSelectionListener, mCancelListener);
- }
case R.id.dialog_searching_vcard: {
if (mProgressDialogForScanVCard == null) {
String message = getString(R.string.searching_vcard_message);
diff --git a/src/com/android/contacts/common/vcard/NotificationImportExportListener.java b/src/com/android/contacts/common/vcard/NotificationImportExportListener.java
index 7117f9f5..42876b58 100644
--- a/src/com/android/contacts/common/vcard/NotificationImportExportListener.java
+++ b/src/com/android/contacts/common/vcard/NotificationImportExportListener.java
@@ -45,12 +45,12 @@ public class NotificationImportExportListener implements VCardImportExportListen
/* package */ static final String FAILURE_NOTIFICATION_TAG = "VCardServiceFailure";
private final NotificationManager mNotificationManager;
- private final Activity mContext;
+ private final Context mContext;
private final Handler mHandler;
- public NotificationImportExportListener(Activity activity) {
- mContext = activity;
- mNotificationManager = (NotificationManager) activity.getSystemService(
+ public NotificationImportExportListener(Context context) {
+ mContext = context;
+ mNotificationManager = (NotificationManager) context.getSystemService(
Context.NOTIFICATION_SERVICE);
mHandler = new Handler(this);
}
@@ -215,7 +215,7 @@ public class NotificationImportExportListener implements VCardImportExportListen
final Notification.Builder builder = new Notification.Builder(context);
builder.setOngoing(true)
- .setProgress(totalCount, currentCount, totalCount == - 1)
+ .setProgress(totalCount, currentCount, totalCount == -1)
.setTicker(tickerText)
.setContentTitle(description)
.setSmallIcon(type == VCardService.TYPE_IMPORT
@@ -286,6 +286,5 @@ public class NotificationImportExportListener implements VCardImportExportListen
@Override
public void onComplete() {
- mContext.finish();
}
}