1/*
2 * Copyright (C) 2012 Google Inc.
3 * Licensed to The Android Open Source Project.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18package com.android.mail.ui;
19
20import android.app.Activity;
21import android.content.AsyncTaskLoader;
22import android.net.Uri;
23
24import com.android.mail.browse.ConversationCursor;
25import com.android.mail.providers.Account;
26import com.android.mail.providers.UIProvider.AccountCapabilities;
27import com.android.mail.utils.LogUtils;
28
29import java.util.ArrayList;
30
31public class ConversationCursorLoader extends AsyncTaskLoader<ConversationCursor> {
32    private static final String TAG = "ConversationCursorLoader";
33    private final Uri mUri;
34    private final ConversationCursor mConversationCursor;
35    private boolean mInit = false;
36    private boolean mClosed = false;
37    private boolean mRetain = false;
38    private boolean mRetained = false;
39    private final String mName;
40
41    /** Only used for debugging. Turn {@link #DEBUG} on to make this useful. */
42    private static final boolean DEBUG = false;
43    private static final ArrayList<ConversationCursorLoader> sLoaders =
44            new ArrayList<ConversationCursorLoader>();
45
46    public ConversationCursorLoader(Activity activity, Account account,
47            Uri uri, String name, boolean ignoreInitialConversationLimit) {
48        super(activity);
49        mUri = uri;
50        mName = name;
51        final boolean useInitialConversationLimit = ignoreInitialConversationLimit ? false :
52                account.supportsCapability(AccountCapabilities.INITIAL_CONVERSATION_LIMIT);
53        // Initialize the state of the conversation cursor
54        mConversationCursor = new ConversationCursor(
55                activity, mUri, useInitialConversationLimit, name);
56        addLoader();
57    }
58
59    private static void dumpLoaders() {
60        if (DEBUG) {
61            LogUtils.d(TAG, "Loaders: ");
62            for (ConversationCursorLoader loader: sLoaders) {
63                LogUtils.d(TAG, " >> " + loader.mName + " (" + loader.mUri + ")");
64            }
65        }
66    }
67
68    private void addLoader() {
69        if (DEBUG) {
70            LogUtils.d(TAG, "Add loader: " + mUri);
71            sLoaders.add(this);
72            if (sLoaders.size() > 1) {
73                dumpLoaders();
74            }
75        }
76    }
77
78    /**
79     * Indicate whether the loader's cursor should be retained after reset
80     * @param state whether this laoder's cursor should be retained
81     */
82    public void retainCursor(boolean state) {
83        mRetain = state;
84    }
85
86    @Override
87    public void onReset() {
88        if (!mRetain) {
89            // Mark the cursor as disabled
90            mConversationCursor.disable();
91            mClosed = true;
92            if (DEBUG) {
93                LogUtils.d(TAG, "Reset loader/disable cursor: " + mName);
94                sLoaders.remove(this);
95                if (!sLoaders.isEmpty()) {
96                    dumpLoaders();
97                }
98            }
99        } else {
100            if (DEBUG) {
101                LogUtils.d(TAG, "Reset loader/retain cursor: " + mName);
102                mRetained = true;
103            }
104        }
105    }
106
107    @Override
108    public ConversationCursor loadInBackground() {
109        if (!mInit) {
110            mConversationCursor.load();
111            mInit = true;
112        }
113        return mConversationCursor;
114    }
115
116    @Override
117    protected void onStartLoading() {
118        if (mClosed) {
119            mClosed = false;
120            mConversationCursor.load();
121            addLoader();
122            if (DEBUG) {
123                LogUtils.d(TAG, "Restarting reset loader: " + mName);
124            }
125        } else if (mRetained) {
126            mRetained = false;
127            if (DEBUG) {
128                LogUtils.d(TAG, "Resuming retained loader: " + mName);
129            }
130        }
131        forceLoad();
132        mConversationCursor.resume();
133    }
134
135    @Override
136    protected void onStopLoading() {
137        cancelLoad();
138        mConversationCursor.pause();
139    }
140}
141