/* * 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.datamodel.data; import android.app.LoaderManager; import android.content.Context; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; import com.android.messaging.datamodel.BoundCursorLoader; import com.android.messaging.datamodel.FrequentContactsCursorBuilder; import com.android.messaging.datamodel.MessagingContentProvider; import com.android.messaging.datamodel.binding.BindableData; import com.android.messaging.datamodel.binding.BindingBase; import com.android.messaging.sms.MmsConfig; import com.android.messaging.util.Assert; import com.android.messaging.util.ContactUtil; import com.android.messaging.util.LogUtil; /** * Class to access phone contacts. * The caller is responsible for ensuring that the app has READ_CONTACTS permission (see * {@link ContactUtil#hasReadContactsPermission()}) before instantiating this class. */ public class ContactPickerData extends BindableData implements LoaderManager.LoaderCallbacks { public interface ContactPickerDataListener { void onAllContactsCursorUpdated(Cursor data); void onFrequentContactsCursorUpdated(Cursor data); void onContactCustomColorLoaded(ContactPickerData data); } private static final String BINDING_ID = "bindingId"; private final Context mContext; private LoaderManager mLoaderManager; private ContactPickerDataListener mListener; private final FrequentContactsCursorBuilder mFrequentContactsCursorBuilder; public ContactPickerData(final Context context, final ContactPickerDataListener listener) { mListener = listener; mContext = context; mFrequentContactsCursorBuilder = new FrequentContactsCursorBuilder(); } private static final int ALL_CONTACTS_LOADER = 1; private static final int FREQUENT_CONTACTS_LOADER = 2; private static final int PARTICIPANT_LOADER = 3; @Override public Loader onCreateLoader(final int id, final Bundle args) { final String bindingId = args.getString(BINDING_ID); // Check if data still bound to the requesting ui element if (isBound(bindingId)) { switch (id) { case ALL_CONTACTS_LOADER: return ContactUtil.getPhones(mContext) .createBoundCursorLoader(bindingId); case FREQUENT_CONTACTS_LOADER: return ContactUtil.getFrequentContacts(mContext) .createBoundCursorLoader(bindingId); case PARTICIPANT_LOADER: return new BoundCursorLoader(bindingId, mContext, MessagingContentProvider.PARTICIPANTS_URI, ParticipantData.ParticipantsQuery.PROJECTION, null, null, null); default: Assert.fail("Unknown loader id for contact picker!"); break; } } else { LogUtil.w(LogUtil.BUGLE_TAG, "Loader created after unbinding the contacts list"); } return null; } /** * {@inheritDoc} */ @Override public void onLoadFinished(final Loader loader, final Cursor data) { final BoundCursorLoader cursorLoader = (BoundCursorLoader) loader; if (isBound(cursorLoader.getBindingId())) { switch (loader.getId()) { case ALL_CONTACTS_LOADER: mListener.onAllContactsCursorUpdated(data); mFrequentContactsCursorBuilder.setAllContacts(data); break; case FREQUENT_CONTACTS_LOADER: mFrequentContactsCursorBuilder.setFrequents(data); break; case PARTICIPANT_LOADER: mListener.onContactCustomColorLoaded(this); break; default: Assert.fail("Unknown loader id for contact picker!"); break; } if (loader.getId() != PARTICIPANT_LOADER) { // The frequent contacts cursor to be used in the UI depends on results from both // all contacts and frequent contacts loader, and we don't know which will finish // first. Therefore, try to build the cursor and notify the listener if it's // successfully built. final Cursor frequentContactsCursor = mFrequentContactsCursorBuilder.build(); if (frequentContactsCursor != null) { mListener.onFrequentContactsCursorUpdated(frequentContactsCursor); } } } else { LogUtil.w(LogUtil.BUGLE_TAG, "Loader finished after unbinding the contacts list"); } } /** * {@inheritDoc} */ @Override public void onLoaderReset(final Loader loader) { final BoundCursorLoader cursorLoader = (BoundCursorLoader) loader; if (isBound(cursorLoader.getBindingId())) { switch (loader.getId()) { case ALL_CONTACTS_LOADER: mListener.onAllContactsCursorUpdated(null); mFrequentContactsCursorBuilder.setAllContacts(null); break; case FREQUENT_CONTACTS_LOADER: mListener.onFrequentContactsCursorUpdated(null); mFrequentContactsCursorBuilder.setFrequents(null); break; case PARTICIPANT_LOADER: mListener.onContactCustomColorLoaded(this); break; default: Assert.fail("Unknown loader id for contact picker!"); break; } } else { LogUtil.w(LogUtil.BUGLE_TAG, "Loader reset after unbinding the contacts list"); } } public void init(final LoaderManager loaderManager, final BindingBase binding) { final Bundle args = new Bundle(); args.putString(BINDING_ID, binding.getBindingId()); mLoaderManager = loaderManager; mLoaderManager.initLoader(ALL_CONTACTS_LOADER, args, this); mLoaderManager.initLoader(FREQUENT_CONTACTS_LOADER, args, this); mLoaderManager.initLoader(PARTICIPANT_LOADER, args, this); } @Override protected void unregisterListeners() { mListener = null; // This could be null if we bind but the caller doesn't init the BindableData if (mLoaderManager != null) { mLoaderManager.destroyLoader(ALL_CONTACTS_LOADER); mLoaderManager.destroyLoader(FREQUENT_CONTACTS_LOADER); mLoaderManager.destroyLoader(PARTICIPANT_LOADER); mLoaderManager = null; } mFrequentContactsCursorBuilder.resetBuilder(); } public static boolean isTooManyParticipants(final int participantCount) { // When creating a conversation, the conversation will be created using the system's // default SIM, so use the default MmsConfig's recipient limit. return (participantCount > MmsConfig.get(ParticipantData.DEFAULT_SELF_SUB_ID) .getRecipientLimit()); } public static boolean getCanAddMoreParticipants(final int participantCount) { // When creating a conversation, the conversation will be created using the system's // default SIM, so use the default MmsConfig's recipient limit. return (participantCount < MmsConfig.get(ParticipantData.DEFAULT_SELF_SUB_ID) .getRecipientLimit()); } }