1d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/*
2d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Copyright (C) 2011 The Android Open Source Project
3d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *
4d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License");
5d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * you may not use this file except in compliance with the License.
6d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * You may obtain a copy of the License at
7d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *
8d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *      http://www.apache.org/licenses/LICENSE-2.0
9d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng *
10d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * Unless required by applicable law or agreed to in writing, software
11d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS,
12d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * See the License for the specific language governing permissions and
14d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * limitations under the License.
15d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */
16d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpackage com.android.contacts.common.list;
17d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
18d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.content.Context;
19d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.content.CursorLoader;
20d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.database.Cursor;
21d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.database.MatrixCursor;
22d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.database.MergeCursor;
23d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.os.Bundle;
24d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport android.provider.ContactsContract.Profile;
25d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
26d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport com.google.common.collect.Lists;
27d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
28d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengimport java.util.List;
29d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
30d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng/**
31d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * A loader for use in the default contact list, which will also query for the user's profile
32d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng * if configured to do so.
33d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng */
34d6bba124836ec2f528b329759e38fda6297fec49Chiao Chengpublic class ProfileAndContactsLoader extends CursorLoader {
35d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
36d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private boolean mLoadProfile;
37d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private String[] mProjection;
38d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
39d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public ProfileAndContactsLoader(Context context) {
40d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        super(context);
41d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
42d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
43d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public void setLoadProfile(boolean flag) {
44d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mLoadProfile = flag;
45d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
46d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
47d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public void setProjection(String[] projection) {
48d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        super.setProjection(projection);
49d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        mProjection = projection;
50d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
51d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
52d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    @Override
53d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    public Cursor loadInBackground() {
54d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        // First load the profile, if enabled.
55d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        List<Cursor> cursors = Lists.newArrayList();
56d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        if (mLoadProfile) {
57d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            cursors.add(loadProfile());
58d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
592d731e2c9b856d42fa4ee41035f44afa5a502593Jay Shrauner        // ContactsCursor.loadInBackground() can return null; MergeCursor
602d731e2c9b856d42fa4ee41035f44afa5a502593Jay Shrauner        // correctly handles null cursors.
61fda11a1730cdd4ef20f434f95bc671b26a78f041Jay Shrauner        Cursor cursor = null;
62fda11a1730cdd4ef20f434f95bc671b26a78f041Jay Shrauner        try {
63fda11a1730cdd4ef20f434f95bc671b26a78f041Jay Shrauner            cursor = super.loadInBackground();
64fda11a1730cdd4ef20f434f95bc671b26a78f041Jay Shrauner        } catch (NullPointerException e) {
65fda11a1730cdd4ef20f434f95bc671b26a78f041Jay Shrauner            // Ignore NPEs thrown by providers
66fda11a1730cdd4ef20f434f95bc671b26a78f041Jay Shrauner        }
67fda11a1730cdd4ef20f434f95bc671b26a78f041Jay Shrauner        final Cursor contactsCursor = cursor;
68d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        cursors.add(contactsCursor);
69d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        return new MergeCursor(cursors.toArray(new Cursor[cursors.size()])) {
70d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            @Override
71d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            public Bundle getExtras() {
72d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                // Need to get the extras from the contacts cursor.
73e87886ebb31545bdedd464d8271c22f9ad898c91Jay Shrauner                return contactsCursor == null ? new Bundle() : contactsCursor.getExtras();
74d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
75d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        };
76d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
77d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng
78d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    /**
792d731e2c9b856d42fa4ee41035f44afa5a502593Jay Shrauner     * Loads the profile into a MatrixCursor. On failure returns null, which
802d731e2c9b856d42fa4ee41035f44afa5a502593Jay Shrauner     * matches the behavior of CursorLoader.loadInBackground().
812d731e2c9b856d42fa4ee41035f44afa5a502593Jay Shrauner     *
822d731e2c9b856d42fa4ee41035f44afa5a502593Jay Shrauner     * @return MatrixCursor containing profile or null on query failure.
83d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng     */
84d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    private MatrixCursor loadProfile() {
85d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        Cursor cursor = getContext().getContentResolver().query(Profile.CONTENT_URI, mProjection,
86d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                null, null, null);
872d731e2c9b856d42fa4ee41035f44afa5a502593Jay Shrauner        if (cursor == null) {
882d731e2c9b856d42fa4ee41035f44afa5a502593Jay Shrauner            return null;
892d731e2c9b856d42fa4ee41035f44afa5a502593Jay Shrauner        }
90d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        try {
91d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            MatrixCursor matrix = new MatrixCursor(mProjection);
92d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            Object[] row = new Object[mProjection.length];
93d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            while (cursor.moveToNext()) {
94d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                for (int i = 0; i < row.length; i++) {
95d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                    row[i] = cursor.getString(i);
96d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                }
97d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng                matrix.addRow(row);
98d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            }
99d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            return matrix;
100d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        } finally {
101d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng            cursor.close();
102d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng        }
103d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng    }
104d6bba124836ec2f528b329759e38fda6297fec49Chiao Cheng}
105