blob: d1759ad5fb05b8c17614c2bcabaad8c5e5e299e1 [file] [log] [blame]
/*
* 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;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import com.android.messaging.util.FallbackStrategies;
import com.android.messaging.util.FallbackStrategies.Strategy;
import com.android.messaging.util.LogUtil;
import com.android.messaging.util.OsUtil;
/**
* Helper for querying frequent (and/or starred) contacts.
*/
public class FrequentContactsCursorQueryData extends CursorQueryData {
private static final String TAG = LogUtil.BUGLE_TAG;
private static class FrequentContactsCursorLoader extends BoundCursorLoader {
private final Uri mOriginalUri;
FrequentContactsCursorLoader(String bindingId, Context context, Uri uri,
String[] projection, String selection, String[] selectionArgs, String sortOrder) {
super(bindingId, context, uri, projection, selection, selectionArgs, sortOrder);
mOriginalUri = uri;
}
@Override
public Cursor loadInBackground() {
return FallbackStrategies
.startWith(new PrimaryStrequentContactsQueryStrategy())
.thenTry(new FrequentOnlyContactsQueryStrategy())
.thenTry(new PhoneOnlyStrequentContactsQueryStrategy())
.execute(null);
}
private abstract class StrequentContactsQueryStrategy implements Strategy<Void, Cursor> {
@Override
public Cursor execute(Void params) throws Exception {
final Uri uri = getUri();
if (uri != null) {
setUri(uri);
}
return FrequentContactsCursorLoader.super.loadInBackground();
}
protected abstract Uri getUri();
}
private class PrimaryStrequentContactsQueryStrategy extends StrequentContactsQueryStrategy {
@Override
protected Uri getUri() {
// Use the original URI requested.
return mOriginalUri;
}
}
private class FrequentOnlyContactsQueryStrategy extends StrequentContactsQueryStrategy {
@Override
protected Uri getUri() {
// Some phones have a buggy implementation of the Contacts provider which crashes
// when we query for strequent (starred+frequent) contacts (b/17991485).
// If this happens, switch to just querying for frequent contacts.
return Contacts.CONTENT_FREQUENT_URI;
}
}
private class PhoneOnlyStrequentContactsQueryStrategy extends
StrequentContactsQueryStrategy {
@Override
protected Uri getUri() {
// Some 3rd party ROMs have content provider
// implementation where invalid SQL queries are returned for regular strequent
// queries. Using strequent_phone_only query as a fallback to display only phone
// contacts. This is the last-ditch effort; if this fails, we will display an
// empty frequent list (b/18354836).
final String strequentQueryParam = OsUtil.isAtLeastL() ?
ContactsContract.STREQUENT_PHONE_ONLY : "strequent_phone_only";
// TODO: Handle enterprise contacts post M once contacts provider supports it
return Contacts.CONTENT_STREQUENT_URI.buildUpon()
.appendQueryParameter(strequentQueryParam, "true").build();
}
}
}
public FrequentContactsCursorQueryData(Context context, String[] projection,
String selection, String[] selectionArgs, String sortOrder) {
// TODO: Handle enterprise contacts post M once contacts provider supports it
super(context, Contacts.CONTENT_STREQUENT_URI, projection, selection, selectionArgs,
sortOrder);
}
@Override
public BoundCursorLoader createBoundCursorLoader(String bindingId) {
return new FrequentContactsCursorLoader(bindingId, mContext, mUri, mProjection, mSelection,
mSelectionArgs, mSortOrder);
}
}