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 
17 package com.android.messaging.datamodel.data;
18 
19 import android.app.LoaderManager;
20 import android.content.Context;
21 import android.content.Loader;
22 import android.database.Cursor;
23 import android.os.Bundle;
24 import androidx.annotation.Nullable;
25 
26 import com.android.messaging.datamodel.BoundCursorLoader;
27 import com.android.messaging.datamodel.GalleryBoundCursorLoader;
28 import com.android.messaging.datamodel.binding.BindableData;
29 import com.android.messaging.datamodel.binding.BindingBase;
30 import com.android.messaging.util.Assert;
31 import com.android.messaging.util.BuglePrefs;
32 import com.android.messaging.util.BuglePrefsKeys;
33 import com.android.messaging.util.LogUtil;
34 
35 /**
36  * Services data needs for MediaPicker.
37  */
38 public class MediaPickerData extends BindableData {
39     public interface MediaPickerDataListener {
onMediaPickerDataUpdated(MediaPickerData mediaPickerData, Object data, int loaderId)40         void onMediaPickerDataUpdated(MediaPickerData mediaPickerData, Object data, int loaderId);
41     }
42 
43     private static final String BINDING_ID = "bindingId";
44     private final Context mContext;
45     private LoaderManager mLoaderManager;
46     private final GalleryLoaderCallbacks mGalleryLoaderCallbacks;
47     private MediaPickerDataListener mListener;
48 
MediaPickerData(final Context context)49     public MediaPickerData(final Context context) {
50         mContext = context;
51         mGalleryLoaderCallbacks = new GalleryLoaderCallbacks();
52     }
53 
54     public static final int GALLERY_MEDIA_LOADER = 1;
55 
56     /**
57      * A trampoline class so that we can inherit from LoaderManager.LoaderCallbacks multiple times.
58      */
59     private class GalleryLoaderCallbacks implements LoaderManager.LoaderCallbacks<Cursor> {
60         @Override
onCreateLoader(final int id, final Bundle args)61         public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
62             final String bindingId = args.getString(BINDING_ID);
63             // Check if data still bound to the requesting ui element
64             if (isBound(bindingId)) {
65                 switch (id) {
66                     case GALLERY_MEDIA_LOADER:
67                         return new GalleryBoundCursorLoader(bindingId, mContext);
68 
69                     default:
70                         Assert.fail("Unknown loader id for gallery picker!");
71                         break;
72                 }
73             } else {
74                 LogUtil.w(LogUtil.BUGLE_TAG, "Loader created after unbinding the media picker");
75             }
76             return null;
77         }
78 
79         /**
80          * {@inheritDoc}
81          */
82         @Override
onLoadFinished(final Loader<Cursor> loader, final Cursor data)83         public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
84             final BoundCursorLoader cursorLoader = (BoundCursorLoader) loader;
85             if (isBound(cursorLoader.getBindingId())) {
86                 switch (loader.getId()) {
87                     case GALLERY_MEDIA_LOADER:
88                         mListener.onMediaPickerDataUpdated(MediaPickerData.this, data,
89                                 GALLERY_MEDIA_LOADER);
90                         break;
91 
92                     default:
93                         Assert.fail("Unknown loader id for gallery picker!");
94                         break;
95                 }
96             } else {
97                 LogUtil.w(LogUtil.BUGLE_TAG, "Loader finished after unbinding the media picker");
98             }
99         }
100 
101         /**
102          * {@inheritDoc}
103          */
104         @Override
onLoaderReset(final Loader<Cursor> loader)105         public void onLoaderReset(final Loader<Cursor> loader) {
106             final BoundCursorLoader cursorLoader = (BoundCursorLoader) loader;
107             if (isBound(cursorLoader.getBindingId())) {
108                 switch (loader.getId()) {
109                     case GALLERY_MEDIA_LOADER:
110                         mListener.onMediaPickerDataUpdated(MediaPickerData.this, null,
111                                 GALLERY_MEDIA_LOADER);
112                         break;
113 
114                     default:
115                         Assert.fail("Unknown loader id for media picker!");
116                         break;
117                 }
118             } else {
119                 LogUtil.w(LogUtil.BUGLE_TAG, "Loader reset after unbinding the media picker");
120             }
121         }
122     }
123 
124 
125 
startLoader(final int loaderId, final BindingBase<MediaPickerData> binding, @Nullable Bundle args, final MediaPickerDataListener listener)126     public void startLoader(final int loaderId, final BindingBase<MediaPickerData> binding,
127             @Nullable Bundle args, final MediaPickerDataListener listener) {
128         if (args == null) {
129             args = new Bundle();
130         }
131         args.putString(BINDING_ID, binding.getBindingId());
132         if (loaderId == GALLERY_MEDIA_LOADER) {
133             mLoaderManager.initLoader(loaderId, args, mGalleryLoaderCallbacks).forceLoad();
134         } else {
135             Assert.fail("Unsupported loader id for media picker!");
136         }
137         mListener = listener;
138     }
139 
destroyLoader(final int loaderId)140     public void destroyLoader(final int loaderId) {
141         mLoaderManager.destroyLoader(loaderId);
142     }
143 
init(final LoaderManager loaderManager)144     public void init(final LoaderManager loaderManager) {
145         mLoaderManager = loaderManager;
146     }
147 
148     @Override
unregisterListeners()149     protected void unregisterListeners() {
150         // This could be null if we bind but the caller doesn't init the BindableData
151         if (mLoaderManager != null) {
152             mLoaderManager.destroyLoader(GALLERY_MEDIA_LOADER);
153             mLoaderManager = null;
154         }
155     }
156 
157     /**
158      * Gets the last selected chooser index, or -1 if no selection has been saved.
159      */
getSelectedChooserIndex()160     public int getSelectedChooserIndex() {
161         return BuglePrefs.getApplicationPrefs().getInt(
162                 BuglePrefsKeys.SELECTED_MEDIA_PICKER_CHOOSER_INDEX,
163                 BuglePrefsKeys.SELECTED_MEDIA_PICKER_CHOOSER_INDEX_DEFAULT);
164     }
165 
166     /**
167      * Saves the selected media chooser index.
168      * @param selectedIndex the selected media chooser index.
169      */
saveSelectedChooserIndex(final int selectedIndex)170     public void saveSelectedChooserIndex(final int selectedIndex) {
171         BuglePrefs.getApplicationPrefs().putInt(BuglePrefsKeys.SELECTED_MEDIA_PICKER_CHOOSER_INDEX,
172                 selectedIndex);
173     }
174 
175 }
176