diff options
| author | Roman Birg <roman@cyngn.com> | 2014-11-13 16:32:40 -0800 |
|---|---|---|
| committer | Roman Birg <roman@cyngn.com> | 2014-11-13 16:54:58 -0800 |
| commit | 23cbeecd6e226fe295e9943d0c18e78bccd10f33 (patch) | |
| tree | 7e4d6cf424a3e34123104b38e862945474f092ef | |
| parent | 430baf7f2c94010c77be9893c1371d7858899e34 (diff) | |
| download | packages_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>
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(); } } |
