diff options
author | Walter Jang <wjang@google.com> | 2016-11-07 09:24:43 -0800 |
---|---|---|
committer | Abhisek Devkota <ciwrl@lineageos.org> | 2017-02-03 23:15:43 +0000 |
commit | f2ee7f03f49ee28823a1665d9ee111b05214c7e4 (patch) | |
tree | 2b22b87394abf6fb7021e0447e49554ac572cb25 /src | |
parent | 086f5bc849d2406d3686fe8f006c0247bb8b96dd (diff) | |
download | android_packages_apps_ContactsCommon-f2ee7f03f49ee28823a1665d9ee111b05214c7e4.tar.gz android_packages_apps_ContactsCommon-f2ee7f03f49ee28823a1665d9ee111b05214c7e4.tar.bz2 android_packages_apps_ContactsCommon-f2ee7f03f49ee28823a1665d9ee111b05214c7e4.zip |
resolve merge conflicts of 9f523b4 to nyc-dev
Bug: 32219099
Merged-In: Ib141ad682488aeabf6d90e8d169d5fff6df7a8dd
Change-Id: I895b1f9f8ade2dcfa47d1c17e0aaac2edeb75a74
(cherry picked from commit b7eecdd9a1276b721bb9644a0762dfd969e52709)
(cherry picked from commit d47661ad82d402c1e0c90eb83970687d784add1b)
# Conflicts:
# src/com/android/contacts/common/activity/RequestPermissionsActivity.java
# src/com/android/contacts/common/activity/RequestPermissionsActivityBase.java
# src/com/android/contacts/common/util/AccountSelectionUtil.java
# src/com/android/contacts/common/vcard/ImportVCardActivity.java
mh0rst: Backport from android-7.1.1_r9
Diffstat (limited to 'src')
6 files changed, 168 insertions, 31 deletions
diff --git a/src/com/android/contacts/common/activity/RequestImportVCardPermissionsActivity.java b/src/com/android/contacts/common/activity/RequestImportVCardPermissionsActivity.java index f3baf0ba..dc779314 100644 --- a/src/com/android/contacts/common/activity/RequestImportVCardPermissionsActivity.java +++ b/src/com/android/contacts/common/activity/RequestImportVCardPermissionsActivity.java @@ -46,9 +46,11 @@ public class RequestImportVCardPermissionsActivity extends RequestPermissionsAct * to prompt the user for these permissions. Moreover, finish the current activity. * * This is designed to be called inside {@link android.app.Activity#onCreate} + * + * @param isCallerSelf whether the vcard import was started from the contacts app itself. */ - public static boolean startPermissionActivity(Activity activity) { - return startPermissionActivity(activity, REQUIRED_PERMISSIONS, + public static boolean startPermissionActivity(Activity activity, boolean isCallerSelf) { + return startPermissionActivity(activity, REQUIRED_PERMISSIONS, isCallerSelf, RequestImportVCardPermissionsActivity.class); } -}
\ No newline at end of file +} diff --git a/src/com/android/contacts/common/activity/RequestPermissionsActivityBase.java b/src/com/android/contacts/common/activity/RequestPermissionsActivityBase.java index 5f78ec79..a692ab96 100644 --- a/src/com/android/contacts/common/activity/RequestPermissionsActivityBase.java +++ b/src/com/android/contacts/common/activity/RequestPermissionsActivityBase.java @@ -39,6 +39,9 @@ import java.util.Arrays; */ public abstract class RequestPermissionsActivityBase extends Activity { public static final String PREVIOUS_ACTIVITY_INTENT = "previous_intent"; + + protected static final String EXTRA_IS_CALLER_SELF = "is_caller_self"; + private static final int PERMISSIONS_REQUEST_ALL_PERMISSIONS = 1; /** @@ -55,10 +58,14 @@ public abstract class RequestPermissionsActivityBase extends Activity { private Intent mPreviousActivityIntent; + /** If true then start the target activity "for result" after permissions are granted. */ + protected boolean mIsCallerSelf; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mPreviousActivityIntent = (Intent) getIntent().getExtras().get(PREVIOUS_ACTIVITY_INTENT); + mIsCallerSelf = getIntent().getBooleanExtra(EXTRA_IS_CALLER_SELF, false); // Only start a requestPermissions() flow when first starting this activity the first time. // The process is likely to be restarted during the permission flow (necessary to enable @@ -76,9 +83,16 @@ public abstract class RequestPermissionsActivityBase extends Activity { */ protected static boolean startPermissionActivity(Activity activity, String[] requiredPermissions, Class<?> newActivityClass) { + return startPermissionActivity(activity, requiredPermissions, /* isCallerSelf */ false, + newActivityClass); + } + + protected static boolean startPermissionActivity(Activity activity, + String[] requiredPermissions, boolean isCallerSelf, Class<?> newActivityClass) { if (!RequestPermissionsActivity.hasPermissions(activity, requiredPermissions)) { final Intent intent = new Intent(activity, newActivityClass); intent.putExtra(PREVIOUS_ACTIVITY_INTENT, activity.getIntent()); + intent.putExtra(EXTRA_IS_CALLER_SELF, isCallerSelf); activity.startActivity(intent); activity.finish(); return true; @@ -99,7 +113,11 @@ public abstract class RequestPermissionsActivityBase extends Activity { if (permissions != null && permissions.length > 0 && isAllGranted(permissions, grantResults)) { mPreviousActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); - startActivity(mPreviousActivityIntent); + if (mIsCallerSelf) { + startActivityForResult(mPreviousActivityIntent, 0); + } else { + startActivity(mPreviousActivityIntent); + } finish(); overridePendingTransition(0, 0); } else { diff --git a/src/com/android/contacts/common/util/AccountSelectionUtil.java b/src/com/android/contacts/common/util/AccountSelectionUtil.java index 7d1d2f4f..219bb215 100644 --- a/src/com/android/contacts/common/util/AccountSelectionUtil.java +++ b/src/com/android/contacts/common/util/AccountSelectionUtil.java @@ -16,6 +16,7 @@ package com.android.contacts.common.util; +import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.Context; @@ -59,33 +60,33 @@ public class AccountSelectionUtil { public static class AccountSelectedListener implements DialogInterface.OnClickListener { - final private Context mContext; + final private Activity mActivity; final private int mResId; final private int mSubscriptionId; protected List<AccountWithDataSet> mAccountList; - public AccountSelectedListener(Context context, List<AccountWithDataSet> accountList, + public AccountSelectedListener(Activity activity, List<AccountWithDataSet> accountList, int resId, int subscriptionId) { if (accountList == null || accountList.size() == 0) { Log.e(LOG_TAG, "The size of Account list is 0."); } - mContext = context; + mActivity = activity; mAccountList = accountList; mResId = resId; mSubscriptionId = subscriptionId; } - public AccountSelectedListener(Context context, List<AccountWithDataSet> accountList, + public AccountSelectedListener(Activity activity, List<AccountWithDataSet> accountList, int resId) { // Subscription id is only needed for importing from SIM card. We can safely ignore // its value for SD card importing. - this(context, accountList, resId, /* subscriptionId = */ -1); + this(activity, accountList, resId, /* subscriptionId = */ -1); } public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); - doImport(mContext, mResId, mAccountList.get(which)); + doImport(mActivity, mResId, mAccountList.get(which)); } /** * Reset the account list for this listener, to make sure the selected @@ -102,19 +103,19 @@ public class AccountSelectionUtil { mImportSub = subscription; } - public static Dialog getSelectAccountDialog(Context context, int resId) { - return getSelectAccountDialog(context, resId, null, null); + public static Dialog getSelectAccountDialog(Activity activity, int resId) { + return getSelectAccountDialog(activity, resId, null, null); } - public static Dialog getSelectAccountDialog(Context context, int resId, + public static Dialog getSelectAccountDialog(Activity activity, int resId, DialogInterface.OnClickListener onClickListener) { - return getSelectAccountDialog(context, resId, onClickListener, null); + return getSelectAccountDialog(activity, resId, onClickListener, null); } - public static Dialog getSelectAccountDialog(Context context, int resId, + public static Dialog getSelectAccountDialog(Activity activity, int resId, DialogInterface.OnClickListener onClickListener, DialogInterface.OnCancelListener onCancelListener) { - return getSelectAccountDialog(context, resId, onClickListener, + return getSelectAccountDialog(activity, resId, onClickListener, onCancelListener, true); } @@ -122,10 +123,10 @@ public class AccountSelectionUtil { * When OnClickListener or OnCancelListener is null, uses a default listener. * The default OnCancelListener just closes itself with {@link Dialog#dismiss()}. */ - public static Dialog getSelectAccountDialog(Context context, int resId, + public static Dialog getSelectAccountDialog(Activity activity, int resId, DialogInterface.OnClickListener onClickListener, DialogInterface.OnCancelListener onCancelListener, boolean includeSIM) { - final AccountTypeManager accountTypes = AccountTypeManager.getInstance(context); + final AccountTypeManager accountTypes = AccountTypeManager.getInstance(activity); List<AccountWithDataSet> writableAccountList; if (includeSIM) { writableAccountList = accountTypes.getAccounts(true); @@ -140,11 +141,11 @@ public class AccountSelectionUtil { // Wrap our context to inflate list items using correct theme final Context dialogContext = new ContextThemeWrapper( - context, android.R.style.Theme_Light); + activity, android.R.style.Theme_Light); final LayoutInflater dialogInflater = (LayoutInflater)dialogContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); final ArrayAdapter<AccountWithDataSet> accountAdapter = - new ArrayAdapter<AccountWithDataSet>(context, android.R.layout.simple_list_item_2, + new ArrayAdapter<AccountWithDataSet>(activity, android.R.layout.simple_list_item_2, writableAccountList) { @Override @@ -175,7 +176,7 @@ public class AccountSelectionUtil { if (onClickListener == null) { AccountSelectedListener accountSelectedListener = - new AccountSelectedListener(context, writableAccountList, resId); + new AccountSelectedListener(activity, writableAccountList, resId); onClickListener = accountSelectedListener; } else if (onClickListener instanceof AccountSelectedListener) { // Because the writableAccountList is different if includeSIM or not, so @@ -192,22 +193,22 @@ public class AccountSelectionUtil { } }; } - return new AlertDialog.Builder(context) + return new AlertDialog.Builder(activity) .setTitle(R.string.dialog_new_contact_account) .setSingleChoiceItems(accountAdapter, 0, onClickListener) .setOnCancelListener(onCancelListener) .create(); } - public static void doImport(Context context, int resId, + public static void doImport(Activity activity, int resId, AccountWithDataSet account) { switch (resId) { case R.string.import_from_sim: { - doImportFromSim(context, account); + doImportFromSim(activity, account); break; } case R.string.import_from_vcf_file: { - doImportFromVcfFile(context, account); + doImportFromVcfFile(activity, account); break; } } @@ -228,8 +229,8 @@ public class AccountSelectionUtil { context.startActivity(importIntent); } - public static void doImportFromVcfFile(Context context, AccountWithDataSet account) { - Intent importIntent = new Intent(context, ImportVCardActivity.class); + public static void doImportFromVcfFile(Activity activity, AccountWithDataSet account) { + Intent importIntent = new Intent(activity, ImportVCardActivity.class); if (account != null) { importIntent.putExtra("account_name", account.name); importIntent.putExtra("account_type", account.type); @@ -242,6 +243,6 @@ public class AccountSelectionUtil { } mVCardShare = false; mPath = null; - context.startActivity(importIntent); + activity.startActivityForResult(importIntent, 0); } } diff --git a/src/com/android/contacts/common/vcard/ExportVCardActivity.java b/src/com/android/contacts/common/vcard/ExportVCardActivity.java index b976e12e..9c11e1d5 100644 --- a/src/com/android/contacts/common/vcard/ExportVCardActivity.java +++ b/src/com/android/contacts/common/vcard/ExportVCardActivity.java @@ -73,7 +73,8 @@ public class ExportVCardActivity extends Activity implements ServiceConnection, protected void onCreate(Bundle bundle) { super.onCreate(bundle); - if (RequestImportVCardPermissionsActivity.startPermissionActivity(this)) { + if (RequestImportVCardPermissionsActivity.startPermissionActivity(this, + /* isCallerSelf */ false)) { return; } diff --git a/src/com/android/contacts/common/vcard/ImportVCardActivity.java b/src/com/android/contacts/common/vcard/ImportVCardActivity.java index 642c3da1..2a1ab123 100644 --- a/src/com/android/contacts/common/vcard/ImportVCardActivity.java +++ b/src/com/android/contacts/common/vcard/ImportVCardActivity.java @@ -75,7 +75,7 @@ import java.util.List; * 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 ImportVCardDialogFragment.Listener { private static final String LOG_TAG = "VCardImport"; private static final int SELECT_ACCOUNT = 0; @@ -509,7 +509,8 @@ public class ImportVCardActivity extends Activity { protected void onCreate(Bundle bundle) { super.onCreate(bundle); - if (RequestImportVCardPermissionsActivity.startPermissionActivity(this)) { + if (RequestImportVCardPermissionsActivity.startPermissionActivity(this, + isCallerSelf(this))) { return; } @@ -541,10 +542,44 @@ public class ImportVCardActivity extends Activity { } } + if (isCallerSelf(this)) { + startImport(); + } else { + ImportVCardDialogFragment.show(this); + } + } + + private static boolean isCallerSelf(Activity activity) { + // {@link Activity#getCallingActivity()} is a safer alternative to + // {@link Activity#getCallingPackage()} that works around a + // framework bug where getCallingPackage() can sometimes return null even when the + // current activity *was* in fact launched via a startActivityForResult() call. + // + // (The bug happens if the task stack needs to be re-created by the framework after + // having been killed due to memory pressure or by the "Don't keep activities" + // developer option; see bug 7494866 for the full details.) + // + // Turns out that {@link Activity#getCallingActivity()} *does* return correct info + // even in the case where getCallingPackage() is broken, so the workaround is simply + // to get the package name from getCallingActivity().getPackageName() instead. + final ComponentName callingActivity = activity.getCallingActivity(); + if (callingActivity == null) return false; + final String packageName = callingActivity.getPackageName(); + if (packageName == null) return false; + return packageName.equals(activity.getApplicationContext().getPackageName()); + } + + @Override + public void onImportVCardConfirmed() { startImport(); } @Override + public void onImportVCardDenied() { + finish(); + } + + @Override public void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == SELECT_ACCOUNT) { if (resultCode == Activity.RESULT_OK) { diff --git a/src/com/android/contacts/common/vcard/ImportVCardDialogFragment.java b/src/com/android/contacts/common/vcard/ImportVCardDialogFragment.java new file mode 100644 index 00000000..d54cd86a --- /dev/null +++ b/src/com/android/contacts/common/vcard/ImportVCardDialogFragment.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2016 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.common.vcard; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.DialogFragment; +import android.content.DialogInterface; +import android.net.Uri; +import android.os.Bundle; + +import com.android.contacts.common.R; + +/** Asks for confirmation before importing contacts from a vcard. */ +public class ImportVCardDialogFragment extends DialogFragment { + + static final String TAG = "importVCardDialog"; + + /** Callbacks for hosts of the {@link ImportVCardDialogFragment}. */ + public interface Listener { + + /** Invoked after the user has confirmed that contacts should be imported. */ + void onImportVCardConfirmed(); + + /** Invoked after the user has rejected importing contacts. */ + void onImportVCardDenied(); + } + + /** Displays the dialog asking for confirmation before importing contacts. */ + public static void show(Activity activity) { + if (!(activity instanceof Listener)) { + throw new IllegalArgumentException( + "Activity must implement " + Listener.class.getName()); + } + + final ImportVCardDialogFragment dialog = new ImportVCardDialogFragment(); + dialog.show(activity.getFragmentManager(), TAG); + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + + return new AlertDialog.Builder(getActivity()) + .setIconAttribute(android.R.attr.alertDialogIcon) + .setMessage(R.string.import_from_vcf_file_confirmation_message) + .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int whichButton) { + final Listener listener = (Listener) getActivity(); + if (listener != null) { + listener.onImportVCardConfirmed(); + } + } + }) + .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int whichButton) { + final Listener listener = (Listener) getActivity(); + if (listener != null) { + listener.onImportVCardDenied(); + } + } + }) + .create(); + } +} |