summaryrefslogtreecommitdiffstats
path: root/src/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java')
-rw-r--r--src/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java289
1 files changed, 0 insertions, 289 deletions
diff --git a/src/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java b/src/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java
deleted file mode 100644
index c7c2731..0000000
--- a/src/com/android/messaging/ui/contact/ContactRecipientAutoCompleteView.java
+++ /dev/null
@@ -1,289 +0,0 @@
-/*
- * Copyright (C) 2015 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.messaging.ui.contact;
-
-import android.content.Context;
-import android.database.Cursor;
-import android.graphics.Rect;
-import android.os.AsyncTask;
-import android.support.v7.appcompat.R;
-import android.text.Editable;
-import android.text.TextPaint;
-import android.text.TextWatcher;
-import android.text.util.Rfc822Tokenizer;
-import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
-import android.view.KeyEvent;
-import android.view.inputmethod.EditorInfo;
-import android.widget.TextView;
-
-import com.android.ex.chips.RecipientEditTextView;
-import com.android.ex.chips.RecipientEntry;
-import com.android.ex.chips.recipientchip.DrawableRecipientChip;
-import com.android.messaging.datamodel.data.ParticipantData;
-import com.android.messaging.util.ContactRecipientEntryUtils;
-import com.android.messaging.util.ContactUtil;
-import com.android.messaging.util.PhoneUtils;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-
-/**
- * An extension for {@link RecipientEditTextView} which shows a list of Materialized contact chips.
- * It uses Bugle's ContactUtil to perform contact lookup, and is able to return the list of
- * recipients in the form of a ParticipantData list.
- */
-public class ContactRecipientAutoCompleteView extends RecipientEditTextView {
- public interface ContactChipsChangeListener {
- void onContactChipsChanged(int oldCount, int newCount);
- void onInvalidContactChipsPruned(int prunedCount);
- void onEntryComplete();
- }
-
- private final int mTextHeight;
- private ContactChipsChangeListener mChipsChangeListener;
-
- /**
- * Watches changes in contact chips to determine possible state transitions.
- */
- private class ContactChipsWatcher implements TextWatcher {
- /**
- * Tracks the old chips count before text changes. Note that we currently don't compare
- * the entire chip sets but just the cheaper-to-do before and after counts, because
- * the chips view don't allow for replacing chips.
- */
- private int mLastChipsCount = 0;
-
- @Override
- public void onTextChanged(final CharSequence s, final int start, final int before,
- final int count) {
- }
-
- @Override
- public void beforeTextChanged(final CharSequence s, final int start, final int count,
- final int after) {
- // We don't take mLastChipsCount from here but from the last afterTextChanged() run.
- // The reason is because at this point, any chip spans to be removed is already removed
- // from s in the chips text view.
- }
-
- @Override
- public void afterTextChanged(final Editable s) {
- final int currentChipsCount = s.getSpans(0, s.length(),
- DrawableRecipientChip.class).length;
- if (currentChipsCount != mLastChipsCount) {
- // When a sanitizing task is running, we don't want to notify any chips count
- // change, but we do want to track the last chip count.
- if (mChipsChangeListener != null && mCurrentSanitizeTask == null) {
- mChipsChangeListener.onContactChipsChanged(mLastChipsCount, currentChipsCount);
- }
- mLastChipsCount = currentChipsCount;
- }
- }
- }
-
- private static final String TEXT_HEIGHT_SAMPLE = "a";
-
- public ContactRecipientAutoCompleteView(final Context context, final AttributeSet attrs) {
- super(new ContextThemeWrapper(context, R.style.ColorAccentGrayOverrideStyle), attrs);
-
- // Get the height of the text, given the currently set font face and size.
- final Rect textBounds = new Rect(0, 0, 0, 0);
- final TextPaint paint = getPaint();
- paint.getTextBounds(TEXT_HEIGHT_SAMPLE, 0, TEXT_HEIGHT_SAMPLE.length(), textBounds);
- mTextHeight = textBounds.height();
-
- setTokenizer(new Rfc822Tokenizer());
- addTextChangedListener(new ContactChipsWatcher());
- setOnFocusListShrinkRecipients(false);
-
- setBackground(context.getResources().getDrawable(
- R.drawable.abc_textfield_search_default_mtrl_alpha));
- }
-
- public void setContactChipsListener(final ContactChipsChangeListener listener) {
- mChipsChangeListener = listener;
- }
-
- /**
- * A tuple of chips which AsyncContactChipSanitizeTask reports as progress to have the
- * chip actually replaced/removed on the UI thread.
- */
- private class ChipReplacementTuple {
- public final DrawableRecipientChip removedChip;
- public final RecipientEntry replacedChipEntry;
-
- public ChipReplacementTuple(final DrawableRecipientChip removedChip,
- final RecipientEntry replacedChipEntry) {
- this.removedChip = removedChip;
- this.replacedChipEntry = replacedChipEntry;
- }
- }
-
- /**
- * An AsyncTask that cleans up contact chips on every chips commit (i.e. get or create a new
- * conversation with the given chips).
- */
- private class AsyncContactChipSanitizeTask extends
- AsyncTask<Void, ChipReplacementTuple, Integer> {
-
- @Override
- protected Integer doInBackground(final Void... params) {
- final DrawableRecipientChip[] recips = getText()
- .getSpans(0, getText().length(), DrawableRecipientChip.class);
- int invalidChipsRemoved = 0;
- for (final DrawableRecipientChip recipient : recips) {
- final RecipientEntry entry = recipient.getEntry();
- if (entry != null) {
- if (entry.isValid()) {
- if (RecipientEntry.isCreatedRecipient(entry.getContactId()) ||
- ContactRecipientEntryUtils.isSendToDestinationContact(entry)) {
- // This is a generated/send-to contact chip, try to look it up and
- // display a chip for the corresponding local contact.
- final Cursor lookupResult = ContactUtil.lookupDestination(getContext(),
- entry.getDestination()).performSynchronousQuery();
- if (lookupResult != null && lookupResult.moveToNext()) {
- // Found a match, remove the generated entry and replace with
- // a better local entry.
- publishProgress(new ChipReplacementTuple(recipient,
- ContactUtil.createRecipientEntryForPhoneQuery(
- lookupResult, true)));
- } else if (PhoneUtils.isValidSmsMmsDestination(
- entry.getDestination())){
- // No match was found, but we have a valid destination so let's at
- // least create an entry that shows an avatar.
- publishProgress(new ChipReplacementTuple(recipient,
- ContactRecipientEntryUtils.constructNumberWithAvatarEntry(
- entry.getDestination())));
- } else {
- // Not a valid contact. Remove and show an error.
- publishProgress(new ChipReplacementTuple(recipient, null));
- invalidChipsRemoved++;
- }
- }
- } else {
- publishProgress(new ChipReplacementTuple(recipient, null));
- invalidChipsRemoved++;
- }
- }
- }
- return invalidChipsRemoved;
- }
-
- @Override
- protected void onProgressUpdate(final ChipReplacementTuple... values) {
- for (final ChipReplacementTuple tuple : values) {
- if (tuple.removedChip != null) {
- final Editable text = getText();
- final int chipStart = text.getSpanStart(tuple.removedChip);
- final int chipEnd = text.getSpanEnd(tuple.removedChip);
- if (chipStart >= 0 && chipEnd >= 0) {
- text.delete(chipStart, chipEnd);
- }
-
- if (tuple.replacedChipEntry != null) {
- appendRecipientEntry(tuple.replacedChipEntry);
- }
- }
- }
- }
-
- @Override
- protected void onPostExecute(final Integer invalidChipsRemoved) {
- mCurrentSanitizeTask = null;
- if (invalidChipsRemoved > 0) {
- mChipsChangeListener.onInvalidContactChipsPruned(invalidChipsRemoved);
- }
- }
- }
-
- /**
- * We don't use SafeAsyncTask but instead use a single threaded executor to ensure that
- * all sanitization tasks are serially executed so as not to interfere with each other.
- */
- private static final Executor SANITIZE_EXECUTOR = Executors.newSingleThreadExecutor();
-
- private AsyncContactChipSanitizeTask mCurrentSanitizeTask;
-
- /**
- * Whenever the caller wants to start a new conversation with the list of chips we have,
- * make sure we asynchronously:
- * 1. Remove invalid chips.
- * 2. Attempt to resolve unknown contacts to known local contacts.
- * 3. Convert still unknown chips to chips with generated avatar.
- *
- * Note that we don't need to perform this synchronously since we can
- * resolve any unknown contacts to local contacts when needed.
- */
- private void sanitizeContactChips() {
- if (mCurrentSanitizeTask != null && !mCurrentSanitizeTask.isCancelled()) {
- mCurrentSanitizeTask.cancel(false);
- mCurrentSanitizeTask = null;
- }
- mCurrentSanitizeTask = new AsyncContactChipSanitizeTask();
- mCurrentSanitizeTask.executeOnExecutor(SANITIZE_EXECUTOR);
- }
-
- /**
- * Returns a list of ParticipantData from the entered chips in order to create
- * new conversation.
- */
- public ArrayList<ParticipantData> getRecipientParticipantDataForConversationCreation() {
- final DrawableRecipientChip[] recips = getText()
- .getSpans(0, getText().length(), DrawableRecipientChip.class);
- final ArrayList<ParticipantData> contacts =
- new ArrayList<ParticipantData>(recips.length);
- for (final DrawableRecipientChip recipient : recips) {
- final RecipientEntry entry = recipient.getEntry();
- if (entry != null && entry.isValid() && entry.getDestination() != null &&
- PhoneUtils.isValidSmsMmsDestination(entry.getDestination())) {
- contacts.add(ParticipantData.getFromRecipientEntry(recipient.getEntry()));
- }
- }
- sanitizeContactChips();
- return contacts;
- }
-
- /**c
- * Gets a set of currently selected chips' emails/phone numbers. This will facilitate the
- * consumer with determining quickly whether a contact is currently selected.
- */
- public Set<String> getSelectedDestinations() {
- Set<String> set = new HashSet<String>();
- final DrawableRecipientChip[] recips = getText()
- .getSpans(0, getText().length(), DrawableRecipientChip.class);
-
- for (final DrawableRecipientChip recipient : recips) {
- final RecipientEntry entry = recipient.getEntry();
- if (entry != null && entry.isValid() && entry.getDestination() != null) {
- set.add(PhoneUtils.getDefault().getCanonicalBySystemLocale(
- entry.getDestination()));
- }
- }
- return set;
- }
-
- @Override
- public boolean onEditorAction(final TextView view, final int actionId, final KeyEvent event) {
- if (actionId == EditorInfo.IME_ACTION_DONE) {
- mChipsChangeListener.onEntryComplete();
- }
- return super.onEditorAction(view, actionId, event);
- }
-}