diff options
author | 2024-12-16 21:45:41 -0500 | |
---|---|---|
committer | 2025-01-11 14:17:35 -0500 | |
commit | e9a0e66716dab4dd3184d009d8920de1961efdfa (patch) | |
tree | 02dcc096643d74645bf28459c2834c3d4a2ad7f2 /java/src/com/android/inputmethod/latin/ContactsManager.java | |
parent | fb3b9360d70596d7e921de8bf7d3ca99564a077e (diff) | |
download | latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.tar.gz latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.tar.xz latinime-e9a0e66716dab4dd3184d009d8920de1961efdfa.zip |
Rename to Kelar Keyboard (org.kelar.inputmethod.latin)
Diffstat (limited to 'java/src/com/android/inputmethod/latin/ContactsManager.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/ContactsManager.java | 245 |
1 files changed, 0 insertions, 245 deletions
diff --git a/java/src/com/android/inputmethod/latin/ContactsManager.java b/java/src/com/android/inputmethod/latin/ContactsManager.java deleted file mode 100644 index 13503ff45..000000000 --- a/java/src/com/android/inputmethod/latin/ContactsManager.java +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2014 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.inputmethod.latin; - -import android.content.Context; -import android.database.Cursor; -import android.database.sqlite.SQLiteException; -import android.net.Uri; -import android.provider.ContactsContract.Contacts; -import android.text.TextUtils; -import android.util.Log; - -import com.android.inputmethod.latin.common.Constants; -import com.android.inputmethod.latin.common.StringUtils; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Manages all interactions with Contacts DB. - * - * The manager provides an API for listening to meaning full updates by keeping a - * measure of the current state of the content provider. - */ -public class ContactsManager { - private static final String TAG = "ContactsManager"; - - /** - * Use at most this many of the highest affinity contacts. - */ - public static final int MAX_CONTACT_NAMES = 200; - - protected static class RankedContact { - public final String mName; - public final long mLastContactedTime; - public final int mTimesContacted; - public final boolean mInVisibleGroup; - - private float mAffinity = 0.0f; - - RankedContact(final Cursor cursor) { - mName = cursor.getString( - ContactsDictionaryConstants.NAME_INDEX); - mTimesContacted = cursor.getInt( - ContactsDictionaryConstants.TIMES_CONTACTED_INDEX); - mLastContactedTime = cursor.getLong( - ContactsDictionaryConstants.LAST_TIME_CONTACTED_INDEX); - mInVisibleGroup = cursor.getInt( - ContactsDictionaryConstants.IN_VISIBLE_GROUP_INDEX) == 1; - } - - float getAffinity() { - return mAffinity; - } - - /** - * Calculates the affinity with the contact based on: - * - How many times it has been contacted - * - How long since the last contact. - * - Whether the contact is in the visible group (i.e., Contacts list). - * - * Note: This affinity is limited by the fact that some apps currently do not update the - * LAST_TIME_CONTACTED or TIMES_CONTACTED counters. As a result, a frequently messaged - * contact may still have 0 affinity. - */ - void computeAffinity(final int maxTimesContacted, final long currentTime) { - final float timesWeight = ((float) mTimesContacted + 1) / (maxTimesContacted + 1); - final long timeSinceLastContact = Math.min( - Math.max(0, currentTime - mLastContactedTime), - TimeUnit.MILLISECONDS.convert(180, TimeUnit.DAYS)); - final float lastTimeWeight = (float) Math.pow(0.5, - timeSinceLastContact / (TimeUnit.MILLISECONDS.convert(10, TimeUnit.DAYS))); - final float visibleWeight = mInVisibleGroup ? 1.0f : 0.0f; - mAffinity = (timesWeight + lastTimeWeight + visibleWeight) / 3; - } - } - - private static class AffinityComparator implements Comparator<RankedContact> { - @Override - public int compare(RankedContact contact1, RankedContact contact2) { - return Float.compare(contact2.getAffinity(), contact1.getAffinity()); - } - } - - /** - * Interface to implement for classes interested in getting notified for updates - * to Contacts content provider. - */ - public static interface ContactsChangedListener { - public void onContactsChange(); - } - - /** - * The number of contacts observed in the most recent instance of - * contacts content provider. - */ - private AtomicInteger mContactCountAtLastRebuild = new AtomicInteger(0); - - /** - * The hash code of list of valid contacts names in the most recent dictionary - * rebuild. - */ - private AtomicInteger mHashCodeAtLastRebuild = new AtomicInteger(0); - - private final Context mContext; - private final ContactsContentObserver mObserver; - - public ContactsManager(final Context context) { - mContext = context; - mObserver = new ContactsContentObserver(this /* ContactsManager */, context); - } - - // TODO: This was synchronized in previous version. Why? - public void registerForUpdates(final ContactsChangedListener listener) { - mObserver.registerObserver(listener); - } - - public int getContactCountAtLastRebuild() { - return mContactCountAtLastRebuild.get(); - } - - public int getHashCodeAtLastRebuild() { - return mHashCodeAtLastRebuild.get(); - } - - /** - * Returns all the valid names in the Contacts DB. Callers should also - * call {@link #updateLocalState(ArrayList)} after they are done with result - * so that the manager can cache local state for determining updates. - * - * These names are sorted by their affinity to the user, with favorite - * contacts appearing first. - */ - public ArrayList<String> getValidNames(final Uri uri) { - // Check all contacts since it's not possible to find out which names have changed. - // This is needed because it's possible to receive extraneous onChange events even when no - // name has changed. - final Cursor cursor = mContext.getContentResolver().query(uri, - ContactsDictionaryConstants.PROJECTION, null, null, null); - final ArrayList<RankedContact> contacts = new ArrayList<>(); - int maxTimesContacted = 0; - if (cursor != null) { - try { - if (cursor.moveToFirst()) { - while (!cursor.isAfterLast()) { - final String name = cursor.getString( - ContactsDictionaryConstants.NAME_INDEX); - if (isValidName(name)) { - final int timesContacted = cursor.getInt( - ContactsDictionaryConstants.TIMES_CONTACTED_INDEX); - if (timesContacted > maxTimesContacted) { - maxTimesContacted = timesContacted; - } - contacts.add(new RankedContact(cursor)); - } - cursor.moveToNext(); - } - } - } finally { - cursor.close(); - } - } - final long currentTime = System.currentTimeMillis(); - for (RankedContact contact : contacts) { - contact.computeAffinity(maxTimesContacted, currentTime); - } - Collections.sort(contacts, new AffinityComparator()); - final HashSet<String> names = new HashSet<>(); - for (int i = 0; i < contacts.size() && names.size() < MAX_CONTACT_NAMES; ++i) { - names.add(contacts.get(i).mName); - } - return new ArrayList<>(names); - } - - /** - * Returns the number of contacts in contacts content provider. - */ - public int getContactCount() { - // TODO: consider switching to a rawQuery("select count(*)...") on the database if - // performance is a bottleneck. - Cursor cursor = null; - try { - cursor = mContext.getContentResolver().query(Contacts.CONTENT_URI, - ContactsDictionaryConstants.PROJECTION_ID_ONLY, null, null, null); - if (null == cursor) { - return 0; - } - return cursor.getCount(); - } catch (final SQLiteException e) { - Log.e(TAG, "SQLiteException in the remote Contacts process.", e); - } finally { - if (null != cursor) { - cursor.close(); - } - } - return 0; - } - - private static boolean isValidName(final String name) { - if (TextUtils.isEmpty(name) || name.indexOf(Constants.CODE_COMMERCIAL_AT) != -1) { - return false; - } - final boolean hasSpace = name.indexOf(Constants.CODE_SPACE) != -1; - if (!hasSpace) { - // Only allow an isolated word if it does not contain a hyphen. - // This helps to filter out mailing lists. - return name.indexOf(Constants.CODE_DASH) == -1; - } - return true; - } - - /** - * Updates the local state of the manager. This should be called when the callers - * are done with all the updates of the content provider successfully. - */ - public void updateLocalState(final ArrayList<String> names) { - mContactCountAtLastRebuild.set(getContactCount()); - mHashCodeAtLastRebuild.set(names.hashCode()); - } - - /** - * Performs any necessary cleanup. - */ - public void close() { - mObserver.unregister(); - } -} |