1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.tv.settings.util;
18
19import android.content.AsyncTaskLoader;
20import android.content.Context;
21
22/**
23 * This class fills in some boilerplate for AsyncTaskLoader to actually load things.
24 *
25 * Subclasses need to implement {@link SettingsAsyncTaskLoader#loadInBackground()} to perform the
26 * actual background task, and {@link SettingsAsyncTaskLoader#onDiscardResult(T)} to clean up
27 * previously loaded results.
28 */
29
30public abstract class SettingsAsyncTaskLoader<T> extends AsyncTaskLoader<T> {
31    private T mResult;
32
33    public SettingsAsyncTaskLoader(final Context context) {
34        super(context);
35    }
36
37    @Override
38    protected void onStartLoading() {
39        if (mResult != null) {
40            deliverResult(mResult);
41        }
42
43        if (takeContentChanged() || mResult == null) {
44            forceLoad();
45        }
46    }
47
48    @Override
49    protected void onStopLoading() {
50        cancelLoad();
51    }
52
53    @Override
54    public void deliverResult(final T data) {
55        if (isReset()) {
56            if (data != null) {
57                onDiscardResult(data);
58            }
59            return;
60        }
61
62        final T oldResult = mResult;
63        mResult = data;
64
65        if (isStarted()) {
66            super.deliverResult(data);
67        }
68
69        if (oldResult != null && oldResult != mResult) {
70            onDiscardResult(oldResult);
71        }
72    }
73
74    @Override
75    protected void onReset() {
76        super.onReset();
77
78        onStopLoading();
79
80        if (mResult != null) {
81            onDiscardResult(mResult);
82        }
83        mResult = null;
84    }
85
86    @Override
87    public void onCanceled(final T data) {
88        super.onCanceled(data);
89
90        if (data != null) {
91            onDiscardResult(data);
92        }
93    }
94
95    /**
96     * Called when discarding the load results so subclasses can take care of clean-up or
97     * recycling tasks. This is not called if the same result (by way of pointer equality) is
98     * returned again by a subsequent call to loadInBackground, or if result is null.
99     *
100     * Note that this may be called concurrently with loadInBackground(), and in some circumstances
101     * may be called more than once for a given object.
102     *
103     * @param result The value returned from {@link SettingsAsyncTaskLoader#loadInBackground()} which
104     *               is to be discarded.
105     */
106    protected abstract void onDiscardResult(final T result);
107}
108