Commit 92739742 authored by Evan Stade's avatar Evan Stade Committed by Commit Bot

WebLayer contacts picker: Split Chrome logic out of PickerAdapter

PickerAdapter is split into a base PickerAdapter and a
ChromePickerAdapter. Inheritance is used instead of a delegate object
because ChromePickerAdapter overrides some Adapter methods.

The code that uses the signin component is left in ChromePickerAdapter,
even though it's componentized, as WebLayer doesn't currently use this
component. This code may also be componentized later, but the plan is
for WebLayer to initially skip the special handling for the owner
contact.

After this change, all of the contacts_picker package save
ChromePickerAdapter can be moved to //components.

Bug: 1016938
Change-Id: Iba554c2064e1e302a05455b8875b409a14c3b199
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2324762Reviewed-by: default avatarTed Choc <tedchoc@chromium.org>
Reviewed-by: default avatarFinnur Thorarinsson <finnur@chromium.org>
Commit-Queue: Evan Stade <estade@chromium.org>
Cr-Commit-Position: refs/heads/master@{#799722}
parent 7763a092
...@@ -344,6 +344,7 @@ chrome_java_sources = [ ...@@ -344,6 +344,7 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java", "java/src/org/chromium/chrome/browser/compositor/scene_layer/TabListSceneLayer.java",
"java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java", "java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java",
"java/src/org/chromium/chrome/browser/consent_auditor/ConsentAuditorBridge.java", "java/src/org/chromium/chrome/browser/consent_auditor/ConsentAuditorBridge.java",
"java/src/org/chromium/chrome/browser/contacts_picker/ChromePickerAdapter.java",
"java/src/org/chromium/chrome/browser/contacts_picker/CompressContactIconsWorkerTask.java", "java/src/org/chromium/chrome/browser/contacts_picker/CompressContactIconsWorkerTask.java",
"java/src/org/chromium/chrome/browser/contacts_picker/ContactDetails.java", "java/src/org/chromium/chrome/browser/contacts_picker/ContactDetails.java",
"java/src/org/chromium/chrome/browser/contacts_picker/ContactView.java", "java/src/org/chromium/chrome/browser/contacts_picker/ContactView.java",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.contacts_picker;
import android.accounts.Account;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import androidx.recyclerview.widget.RecyclerView;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.signin.DisplayableProfileData;
import org.chromium.chrome.browser.signin.IdentityServicesProvider;
import org.chromium.chrome.browser.signin.ProfileDataCache;
import org.chromium.components.signin.AccountManagerFacade;
import org.chromium.components.signin.AccountManagerFacadeProvider;
import org.chromium.components.signin.base.CoreAccountInfo;
import org.chromium.components.signin.identitymanager.ConsentLevel;
import org.chromium.components.signin.identitymanager.IdentityManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* A {@link PickerAdapter} with special behavior tailored for Chrome.
*
* Owner email is looked up in the {@link ProfileDataCache}, or, failing that, via the {@link
* AccountManagerFacade}.
*/
public class ChromePickerAdapter extends PickerAdapter implements ProfileDataCache.Observer {
// The profile data cache to consult when figuring out the signed in user.
private ProfileDataCache mProfileDataCache;
// Whether an observer for ProfileDataCache has been registered.
private boolean mObserving;
// Whether owner info is being fetched asynchronously.
private boolean mWaitingOnOwnerInfo;
public ChromePickerAdapter() {}
// Adapter:
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
addProfileDataObserver();
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
removeProfileDataObserver();
}
// ProfileDataCache.Observer:
@Override
public void onProfileDataUpdated(String accountId) {
if (!mWaitingOnOwnerInfo || !TextUtils.equals(accountId, getOwnerEmail())) {
return;
}
// Now that we've received an update for the right accountId, we can stop listening and
// update our records.
mWaitingOnOwnerInfo = false;
removeProfileDataObserver();
// TODO(finnur): crbug.com/1021477 - Maintain an member instance of this.
DisplayableProfileData profileData =
mProfileDataCache.getProfileDataOrDefault(getOwnerEmail());
ContactDetails contact = getAllContacts().get(0);
Drawable icon = profileData.getImage();
contact.setSelfIcon(icon);
update();
}
private void addProfileDataObserver() {
if (!mObserving) {
mObserving = true;
mProfileDataCache.addObserver(this);
}
}
private void removeProfileDataObserver() {
if (mObserving) {
mObserving = false;
mProfileDataCache.removeObserver(this);
}
}
// PickerAdapter:
@Override
public void init(PickerCategoryView categoryView, Context context, String formattedOrigin) {
mProfileDataCache = new ProfileDataCache(context,
context.getResources().getDimensionPixelSize(R.dimen.contact_picker_icon_size));
super.init(categoryView, context, formattedOrigin);
}
/**
* Returns the email for the currently signed-in user. If that is not available, return the
* first Google account associated with this phone instead.
*/
@Override
protected String findOwnerEmail() {
CoreAccountInfo coreAccountInfo = getCoreAccountInfo();
if (coreAccountInfo != null) {
return coreAccountInfo.getEmail();
}
AccountManagerFacade manager = AccountManagerFacadeProvider.getInstance();
List<Account> accounts = manager.tryGetGoogleAccounts();
if (accounts.size() > 0) {
return accounts.get(0).name;
}
return null;
}
@Override
protected void addOwnerInfoToContacts(ArrayList<ContactDetails> contacts) {
// Processing was not complete, finish the rest asynchronously. Flow continues in
// onProfileDataUpdated.
mWaitingOnOwnerInfo = true;
addProfileDataObserver();
mProfileDataCache.update(Collections.singletonList(getOwnerEmail()));
contacts.add(0, constructOwnerInfo(getOwnerEmail()));
}
/**
* Constructs a {@link ContactDetails} record for the currently signed in user. Name is obtained
* via the {@link DisplayableProfileData}, if available, or (alternatively) using the signed in
* information.
* @param ownerEmail The email for the currently signed in user.
* @return The contact info for the currently signed in user.
*/
@SuppressLint("HardwareIds")
private ContactDetails constructOwnerInfo(String ownerEmail) {
DisplayableProfileData profileData = mProfileDataCache.getProfileDataOrDefault(ownerEmail);
String name = profileData.getFullNameOrEmail();
if (TextUtils.isEmpty(name) || TextUtils.equals(name, ownerEmail)) {
name = CoreAccountInfo.getEmailFrom(getCoreAccountInfo());
}
ContactDetails contact = new ContactDetails(ContactDetails.SELF_CONTACT_ID, name,
Collections.singletonList(ownerEmail), /*phoneNumbers=*/null, /*addresses=*/null);
Drawable icon = profileData.getImage();
contact.setIsSelf(true);
contact.setSelfIcon(icon);
return contact;
}
private CoreAccountInfo getCoreAccountInfo() {
// Since this is read-only operation to obtain email address, always using regular profile
// for both regular and off-the-record profile is safe.
IdentityManager identityManager = IdentityServicesProvider.get().getIdentityManager(
Profile.getLastUsedRegularProfile());
return identityManager.getPrimaryAccountInfo(ConsentLevel.SYNC);
}
}
...@@ -24,6 +24,7 @@ public class ContactsPickerDialog ...@@ -24,6 +24,7 @@ public class ContactsPickerDialog
/** /**
* The ContactsPickerDialog constructor. * The ContactsPickerDialog constructor.
* @param windowAndroid The window associated with the main Activity. * @param windowAndroid The window associated with the main Activity.
* @param adapter An uninitialized {@link PickerAdapter} for this dialog.
* @param listener The listener object that gets notified when an action is taken. * @param listener The listener object that gets notified when an action is taken.
* @param allowMultiple Whether the contacts picker should allow multiple items to be selected. * @param allowMultiple Whether the contacts picker should allow multiple items to be selected.
* @param includeNames Whether the contacts data returned should include names. * @param includeNames Whether the contacts data returned should include names.
...@@ -34,14 +35,14 @@ public class ContactsPickerDialog ...@@ -34,14 +35,14 @@ public class ContactsPickerDialog
* @param formattedOrigin The origin the data will be shared with, formatted for display with * @param formattedOrigin The origin the data will be shared with, formatted for display with
* the scheme omitted. * the scheme omitted.
*/ */
public ContactsPickerDialog(WindowAndroid windowAndroid, ContactsPickerListener listener, public ContactsPickerDialog(WindowAndroid windowAndroid, PickerAdapter adapter,
boolean allowMultiple, boolean includeNames, boolean includeEmails, boolean includeTel, ContactsPickerListener listener, boolean allowMultiple, boolean includeNames,
boolean includeAddresses, boolean includeIcons, String formattedOrigin, boolean includeEmails, boolean includeTel, boolean includeAddresses,
VrModeProvider vrModeProvider) { boolean includeIcons, String formattedOrigin, VrModeProvider vrModeProvider) {
super(windowAndroid.getContext().get(), R.style.Theme_Chromium_Fullscreen); super(windowAndroid.getContext().get(), R.style.Theme_Chromium_Fullscreen);
// Initialize the main content view. // Initialize the main content view.
mCategoryView = new PickerCategoryView(windowAndroid, allowMultiple, includeNames, mCategoryView = new PickerCategoryView(windowAndroid, adapter, allowMultiple, includeNames,
includeEmails, includeTel, includeAddresses, includeIcons, formattedOrigin, this, includeEmails, includeTel, includeAddresses, includeIcons, formattedOrigin, this,
vrModeProvider); vrModeProvider);
mCategoryView.initialize(this, listener); mCategoryView.initialize(this, listener);
......
...@@ -4,16 +4,14 @@ ...@@ -4,16 +4,14 @@
package org.chromium.chrome.browser.contacts_picker; package org.chromium.chrome.browser.contacts_picker;
import android.accounts.Account;
import android.annotation.SuppressLint;
import android.content.ContentResolver; import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import androidx.annotation.CallSuper;
import androidx.annotation.IntDef; import androidx.annotation.IntDef;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
...@@ -22,29 +20,22 @@ import androidx.recyclerview.widget.RecyclerView.Adapter; ...@@ -22,29 +20,22 @@ import androidx.recyclerview.widget.RecyclerView.Adapter;
import org.chromium.base.task.AsyncTask; import org.chromium.base.task.AsyncTask;
import org.chromium.chrome.R; import org.chromium.chrome.R;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.signin.DisplayableProfileData;
import org.chromium.chrome.browser.signin.IdentityServicesProvider;
import org.chromium.chrome.browser.signin.ProfileDataCache;
import org.chromium.components.signin.AccountManagerFacade;
import org.chromium.components.signin.AccountManagerFacadeProvider;
import org.chromium.components.signin.base.CoreAccountInfo;
import org.chromium.components.signin.identitymanager.ConsentLevel;
import org.chromium.components.signin.identitymanager.IdentityManager;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
/** /**
* A data adapter for the Contacts Picker. * A data adapter for the Contacts Picker.
*
* This class is abstract and embedders must specialize it to provide access to the active
* user's contact information.
*/ */
public class PickerAdapter extends Adapter<RecyclerView.ViewHolder> public abstract class PickerAdapter extends Adapter<RecyclerView.ViewHolder>
implements ContactsFetcherWorkerTask.ContactsRetrievedCallback, TopView.ChipToggledCallback, implements ContactsFetcherWorkerTask.ContactsRetrievedCallback,
ProfileDataCache.Observer { TopView.ChipToggledCallback {
/** /**
* A ViewHolder for the top-most view in the RecyclerView. The view it contains has a * A ViewHolder for the top-most view in the RecyclerView. The view it contains has a
* checkbox and some multi-line text that goes with it, so clicks on either text line * checkbox and some multi-line text that goes with it, so clicks on either text line
...@@ -100,7 +91,7 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder> ...@@ -100,7 +91,7 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder>
private TopView mTopView; private TopView mTopView;
// The origin the data will be shared with, formatted for display with the scheme omitted. // The origin the data will be shared with, formatted for display with the scheme omitted.
private final String mFormattedOrigin; private String mFormattedOrigin;
// The content resolver to query data from. // The content resolver to query data from.
private ContentResolver mContentResolver; private ContentResolver mContentResolver;
...@@ -115,15 +106,6 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder> ...@@ -115,15 +106,6 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder>
// The async worker task to use for fetching the contact details. // The async worker task to use for fetching the contact details.
private ContactsFetcherWorkerTask mWorkerTask; private ContactsFetcherWorkerTask mWorkerTask;
// The profile data cache to consult when figuring out the signed in user.
private ProfileDataCache mProfileDataCache;
// Whether an observer for ProfileDataCache has been registered.
private boolean mObserving;
// Whether owner info is being fetched asynchronously.
private boolean mWaitingOnOwnerInfo;
// Whether the user has switched to search mode. // Whether the user has switched to search mode.
private boolean mSearchMode; private boolean mSearchMode;
...@@ -157,7 +139,8 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder> ...@@ -157,7 +139,8 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder>
* @param context The current context. * @param context The current context.
* @param formattedOrigin The origin the data will be shared with. * @param formattedOrigin The origin the data will be shared with.
*/ */
public PickerAdapter(PickerCategoryView categoryView, Context context, String formattedOrigin) { @CallSuper
public void init(PickerCategoryView categoryView, Context context, String formattedOrigin) {
mContext = context; mContext = context;
mCategoryView = categoryView; mCategoryView = categoryView;
mContentResolver = context.getContentResolver(); mContentResolver = context.getContentResolver();
...@@ -167,8 +150,6 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder> ...@@ -167,8 +150,6 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder>
sIncludeEmails = true; sIncludeEmails = true;
sIncludeTelephones = true; sIncludeTelephones = true;
sIncludeIcons = true; sIncludeIcons = true;
mProfileDataCache = new ProfileDataCache(context,
mContext.getResources().getDimensionPixelSize(R.dimen.contact_picker_icon_size));
if (getAllContacts() == null && sTestContacts == null) { if (getAllContacts() == null && sTestContacts == null) {
mWorkerTask = new ContactsFetcherWorkerTask(context, this, mCategoryView.includeNames, mWorkerTask = new ContactsFetcherWorkerTask(context, this, mCategoryView.includeNames,
...@@ -224,54 +205,35 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder> ...@@ -224,54 +205,35 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder>
return mContactDetails; return mContactDetails;
} }
// Adapter: protected String getOwnerEmail() {
return mOwnerEmail;
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
addProfileDataObserver();
} }
@Override protected void update() {
public void onDetachedFromRecyclerView(RecyclerView recyclerView) { if (mTopView != null) mTopView.updateContactCount(mContactDetails.size());
super.onDetachedFromRecyclerView(recyclerView); notifyDataSetChanged();
removeProfileDataObserver();
} }
// ContactsFetcherWorkerTask.ContactsRetrievedCallback: // Abstract methods:
@Override /** Returns the email for the current user. */
public void contactsRetrieved(ArrayList<ContactDetails> contacts) { protected abstract String findOwnerEmail();
mContactDetails = contacts;
mOwnerEmail = getOwnerEmail();
if (!processOwnerInfo(contacts) && mOwnerEmail != null) {
// Processing was not complete, finish the rest asynchronously. Flow continues in
// onProfileDataUpdated.
mWaitingOnOwnerInfo = true;
addProfileDataObserver();
mProfileDataCache.update(Collections.singletonList(mOwnerEmail));
mContactDetails.add(0, constructOwnerInfo(mOwnerEmail));
}
update();
}
// ProfileDataCache.Observer /**
* Adds an entry which represents the current user to the given list.
* @param contacts the list which is missing an entry for the active user, and to which such an
* entry should be pre-pended.
*/
protected abstract void addOwnerInfoToContacts(ArrayList<ContactDetails> contacts);
// ContactsFetcherWorkerTask.ContactsRetrievedCallback:
@Override @Override
public void onProfileDataUpdated(String accountId) { public void contactsRetrieved(ArrayList<ContactDetails> contacts) {
if (!mWaitingOnOwnerInfo || !TextUtils.equals(accountId, mOwnerEmail)) { mOwnerEmail = sTestOwnerEmail != null ? sTestOwnerEmail : findOwnerEmail();
return;
}
// Now that we've received an update for the right accountId, we can stop listening and if (!processOwnerInfo(contacts, mOwnerEmail)) addOwnerInfoToContacts(contacts);
// update our records. mContactDetails = contacts;
mWaitingOnOwnerInfo = false;
removeProfileDataObserver();
// TODO(finnur): crbug.com/1021477 - Maintain an member instance of this.
DisplayableProfileData profileData = mProfileDataCache.getProfileDataOrDefault(mOwnerEmail);
ContactDetails contact = mContactDetails.get(0);
Drawable icon = profileData.getImage();
contact.setSelfIcon(icon);
update(); update();
} }
...@@ -417,54 +379,14 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder> ...@@ -417,54 +379,14 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder>
sTestOwnerEmail = ownerEmail; sTestOwnerEmail = ownerEmail;
} }
private void addProfileDataObserver() {
if (!mObserving) {
mObserving = true;
mProfileDataCache.addObserver(this);
}
}
private void removeProfileDataObserver() {
if (mObserving) {
mObserving = false;
mProfileDataCache.removeObserver(this);
}
}
private void update() {
if (mTopView != null) mTopView.updateContactCount(mContactDetails.size());
notifyDataSetChanged();
}
/**
* Returns the email for the currently signed-in user. If that is not available, return the
* first Google account associated with this phone instead.
*/
private String getOwnerEmail() {
if (sTestOwnerEmail != null) return sTestOwnerEmail;
CoreAccountInfo coreAccountInfo = getCoreAccountInfo();
if (coreAccountInfo != null) {
return coreAccountInfo.getEmail();
}
AccountManagerFacade manager = AccountManagerFacadeProvider.getInstance();
List<Account> accounts = manager.tryGetGoogleAccounts();
if (accounts.size() > 0) {
return accounts.get(0).name;
}
return null;
}
/** /**
* Attempts to figure out if the owner of the device is listed in the available contact details. * Attempts to figure out if the owner of the device is listed in the available contact details.
* If so move it to the top of the list. If not found, returns false. * If so move it to the top of the list. If not found, returns false.
* @return Returns true if processing is complete, false if waiting on asynchronous fetching of * @return Returns true if processing is complete, false if waiting on asynchronous fetching of
* missing data for the owner info. * missing data for the owner info.
*/ */
private boolean processOwnerInfo(ArrayList<ContactDetails> contacts) { private static boolean processOwnerInfo(ArrayList<ContactDetails> contacts, String ownerEmail) {
if (mOwnerEmail == null) { if (ownerEmail == null) {
return true; return true;
} }
...@@ -472,7 +394,7 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder> ...@@ -472,7 +394,7 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder>
for (int i = 0; i < contacts.size(); ++i) { for (int i = 0; i < contacts.size(); ++i) {
List<String> emails = contacts.get(i).getEmails(); List<String> emails = contacts.get(i).getEmails();
for (int y = 0; y < emails.size(); ++y) { for (int y = 0; y < emails.size(); ++y) {
if (TextUtils.equals(emails.get(y), mOwnerEmail)) { if (TextUtils.equals(emails.get(y), ownerEmail)) {
matches.add(i); matches.add(i);
break; break;
} }
...@@ -494,38 +416,4 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder> ...@@ -494,38 +416,4 @@ public class PickerAdapter extends Adapter<RecyclerView.ViewHolder>
} }
return true; return true;
} }
/**
* Constructs a {@link ContactDetails} record for the currently signed in user. Name is obtained
* via the {@link DisplayableProfileData}, if available, or (alternatively) using the signed in
* information. Telephone number is obtained via the telephony service, if that permission has
* already been granted, otherwise left blank.
* @param ownerEmail The email for the currently signed in user.
* @return The contact info for the currently signed in user.
*/
@SuppressLint("HardwareIds")
private ContactDetails constructOwnerInfo(String ownerEmail) {
DisplayableProfileData profileData = mProfileDataCache.getProfileDataOrDefault(ownerEmail);
String name = profileData.getFullNameOrEmail();
if (TextUtils.isEmpty(name) || TextUtils.equals(name, ownerEmail)) {
name = CoreAccountInfo.getEmailFrom(getCoreAccountInfo());
}
ArrayList<String> telephones = new ArrayList<>();
ContactDetails contact = new ContactDetails(ContactDetails.SELF_CONTACT_ID, name,
Collections.singletonList(ownerEmail), telephones, /*addresses=*/null);
Drawable icon = profileData.getImage();
contact.setIsSelf(true);
contact.setSelfIcon(icon);
return contact;
}
private CoreAccountInfo getCoreAccountInfo() {
// Since this is read-only operation to obtain email address, always using regular profile
// for both regular and off-the-record profile is safe.
IdentityManager identityManager = IdentityServicesProvider.get().getIdentityManager(
Profile.getLastUsedRegularProfile());
return identityManager.getPrimaryAccountInfo(ConsentLevel.SYNC);
}
} }
...@@ -126,14 +126,27 @@ public class PickerCategoryView extends OptimizedFrameLayout ...@@ -126,14 +126,27 @@ public class PickerCategoryView extends OptimizedFrameLayout
public final boolean includeIcons; public final boolean includeIcons;
/** /**
* @param windowAndroid The Activity window the Contacts Picker is associated with.
* @param adapter An uninitialized PickerAdapter for this dialog, which may contain
* embedder-specific behaviors. The PickerCategoryView will initialized it.
* @param multiSelectionAllowed Whether the contacts picker should allow multiple items to be * @param multiSelectionAllowed Whether the contacts picker should allow multiple items to be
* selected. * selected.
* @param shouldIncludeNames Whether to allow sharing of names of contacts.
* @param shouldIncludeEmails Whether to allow sharing of contact emails.
* @param shouldIncludeTel Whether to allow sharing of contact telephone numbers.
* @param shouldIncludeAddresses Whether to allow sharing of contact (physical) addresses.
* @param shouldIncludeIcons Whether to allow sharing of contact icons.
* @param formattedOrigin The origin receiving the contact details, formatted for display in the
* UI.
* @param delegate A delegate listening for events from the toolbar.
* @param vrModeProvider Provides accessors for VR mode state.
*/ */
@SuppressWarnings("unchecked") // mSelectableListLayout @SuppressWarnings("unchecked") // mSelectableListLayout
public PickerCategoryView(WindowAndroid windowAndroid, boolean multiSelectionAllowed, public PickerCategoryView(WindowAndroid windowAndroid, PickerAdapter adapter,
boolean shouldIncludeNames, boolean shouldIncludeEmails, boolean shouldIncludeTel, boolean multiSelectionAllowed, boolean shouldIncludeNames, boolean shouldIncludeEmails,
boolean shouldIncludeAddresses, boolean shouldIncludeIcons, String formattedOrigin, boolean shouldIncludeTel, boolean shouldIncludeAddresses, boolean shouldIncludeIcons,
ContactsPickerToolbar.ContactsToolbarDelegate delegate, VrModeProvider vrModeProvider) { String formattedOrigin, ContactsPickerToolbar.ContactsToolbarDelegate delegate,
VrModeProvider vrModeProvider) {
super(windowAndroid.getContext().get(), null); super(windowAndroid.getContext().get(), null);
mWindowAndroid = windowAndroid; mWindowAndroid = windowAndroid;
...@@ -162,7 +175,8 @@ public class PickerCategoryView extends OptimizedFrameLayout ...@@ -162,7 +175,8 @@ public class PickerCategoryView extends OptimizedFrameLayout
R.string.contacts_picker_no_contacts_found, R.string.contacts_picker_no_contacts_found,
R.string.contacts_picker_no_contacts_found); R.string.contacts_picker_no_contacts_found);
mPickerAdapter = new PickerAdapter(this, context, formattedOrigin); mPickerAdapter = adapter;
mPickerAdapter.init(this, context, formattedOrigin);
mRecyclerView = mSelectableListLayout.initializeRecyclerView(mPickerAdapter); mRecyclerView = mSelectableListLayout.initializeRecyclerView(mPickerAdapter);
int titleId = multiSelectionAllowed ? R.string.contacts_picker_select_contacts int titleId = multiSelectionAllowed ? R.string.contacts_picker_select_contacts
: R.string.contacts_picker_select_contact; : R.string.contacts_picker_select_contact;
......
...@@ -38,6 +38,7 @@ import org.chromium.chrome.browser.DeferredStartupHandler; ...@@ -38,6 +38,7 @@ import org.chromium.chrome.browser.DeferredStartupHandler;
import org.chromium.chrome.browser.DevToolsServer; import org.chromium.chrome.browser.DevToolsServer;
import org.chromium.chrome.browser.banners.AppBannerManager; import org.chromium.chrome.browser.banners.AppBannerManager;
import org.chromium.chrome.browser.bookmarkswidget.BookmarkWidgetProvider; import org.chromium.chrome.browser.bookmarkswidget.BookmarkWidgetProvider;
import org.chromium.chrome.browser.contacts_picker.ChromePickerAdapter;
import org.chromium.chrome.browser.contacts_picker.ContactsPickerDialog; import org.chromium.chrome.browser.contacts_picker.ContactsPickerDialog;
import org.chromium.chrome.browser.content_capture.ContentCaptureHistoryDeletionObserver; import org.chromium.chrome.browser.content_capture.ContentCaptureHistoryDeletionObserver;
import org.chromium.chrome.browser.crash.CrashUploadCountStore; import org.chromium.chrome.browser.crash.CrashUploadCountStore;
...@@ -248,9 +249,10 @@ public class ProcessInitializationHandler { ...@@ -248,9 +249,10 @@ public class ProcessInitializationHandler {
String formattedOrigin) { String formattedOrigin) {
// TODO(crbug.com/1117536): remove this cast. // TODO(crbug.com/1117536): remove this cast.
ChromeActivity activity = (ChromeActivity) context; ChromeActivity activity = (ChromeActivity) context;
mDialog = new ContactsPickerDialog(activity.getWindowAndroid(), listener, mDialog = new ContactsPickerDialog(activity.getWindowAndroid(),
allowMultiple, includeNames, includeEmails, includeTel, includeAddresses, new ChromePickerAdapter(), listener, allowMultiple, includeNames,
includeIcons, formattedOrigin, new VrModeProviderImpl()); includeEmails, includeTel, includeAddresses, includeIcons, formattedOrigin,
new VrModeProviderImpl());
mDialog.getWindow().getAttributes().windowAnimations = mDialog.getWindow().getAttributes().windowAnimations =
R.style.PickerDialogAnimation; R.style.PickerDialogAnimation;
mDialog.show(); mDialog.show();
......
...@@ -170,9 +170,10 @@ public class ContactsPickerDialogTest ...@@ -170,9 +170,10 @@ public class ContactsPickerDialogTest
public ContactsPickerDialog call() { public ContactsPickerDialog call() {
final ContactsPickerDialog dialog = new ContactsPickerDialog( final ContactsPickerDialog dialog = new ContactsPickerDialog(
mActivityTestRule.getActivity().getWindowAndroid(), mActivityTestRule.getActivity().getWindowAndroid(),
ContactsPickerDialogTest.this, multiselect, includeNames, new ChromePickerAdapter(), ContactsPickerDialogTest.this,
includeEmails, includeTel, includeAddresses, includeIcons, multiselect, includeNames, includeEmails, includeTel,
"example.com", new VrModeProvider() { includeAddresses, includeIcons, "example.com",
new VrModeProvider() {
@Override @Override
public boolean isInVr() { public boolean isInVr() {
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment