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.net.Uri;
24 import android.os.Bundle;
25 
26 import com.android.messaging.datamodel.BoundCursorLoader;
27 import com.android.messaging.datamodel.MessagingContentProvider;
28 import com.android.messaging.datamodel.action.BugleActionToasts;
29 import com.android.messaging.datamodel.action.UpdateConversationOptionsAction;
30 import com.android.messaging.datamodel.action.UpdateDestinationBlockedAction;
31 import com.android.messaging.datamodel.binding.BindableData;
32 import com.android.messaging.datamodel.binding.BindingBase;
33 import com.android.messaging.util.Assert;
34 import com.android.messaging.util.LogUtil;
35 
36 import java.util.List;
37 
38 /**
39  * Services data needs for PeopleAndOptionsFragment.
40  */
41 public class PeopleAndOptionsData extends BindableData implements
42         LoaderManager.LoaderCallbacks<Cursor> {
43     public interface PeopleAndOptionsDataListener {
onOptionsCursorUpdated(PeopleAndOptionsData data, Cursor cursor)44         void onOptionsCursorUpdated(PeopleAndOptionsData data, Cursor cursor);
onParticipantsListLoaded(PeopleAndOptionsData data, List<ParticipantData> participants)45         void onParticipantsListLoaded(PeopleAndOptionsData data,
46                 List<ParticipantData> participants);
47     }
48 
49     private static final String BINDING_ID = "bindingId";
50     private final Context mContext;
51     private final String mConversationId;
52     private final ConversationParticipantsData mParticipantData;
53     private LoaderManager mLoaderManager;
54     private PeopleAndOptionsDataListener mListener;
55 
PeopleAndOptionsData(final String conversationId, final Context context, final PeopleAndOptionsDataListener listener)56     public PeopleAndOptionsData(final String conversationId, final Context context,
57             final PeopleAndOptionsDataListener listener) {
58         mListener = listener;
59         mContext = context;
60         mConversationId = conversationId;
61         mParticipantData = new ConversationParticipantsData();
62     }
63 
64     private static final int CONVERSATION_OPTIONS_LOADER = 1;
65     private static final int PARTICIPANT_LOADER = 2;
66 
67     @Override
onCreateLoader(final int id, final Bundle args)68     public Loader<Cursor> onCreateLoader(final int id, final Bundle args) {
69         final String bindingId = args.getString(BINDING_ID);
70         // Check if data still bound to the requesting ui element
71         if (isBound(bindingId)) {
72             switch (id) {
73                 case CONVERSATION_OPTIONS_LOADER: {
74                     final Uri uri =
75                             MessagingContentProvider.buildConversationMetadataUri(mConversationId);
76                     return new BoundCursorLoader(bindingId, mContext, uri,
77                             PeopleOptionsItemData.PROJECTION, null, null, null);
78                 }
79 
80                 case PARTICIPANT_LOADER: {
81                     final Uri uri =
82                             MessagingContentProvider
83                                     .buildConversationParticipantsUri(mConversationId);
84                     return new BoundCursorLoader(bindingId, mContext, uri,
85                             ParticipantData.ParticipantsQuery.PROJECTION, null, null, null);
86                 }
87 
88                 default:
89                     Assert.fail("Unknown loader id for PeopleAndOptionsFragment!");
90                     break;
91             }
92         } else {
93             LogUtil.w(LogUtil.BUGLE_TAG, "Loader created after unbinding PeopleAndOptionsFragment");
94         }
95         return null;
96     }
97 
98     /**
99      * {@inheritDoc}
100      */
101     @Override
onLoadFinished(final Loader<Cursor> loader, final Cursor data)102     public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
103         final BoundCursorLoader cursorLoader = (BoundCursorLoader) loader;
104         if (isBound(cursorLoader.getBindingId())) {
105             switch (loader.getId()) {
106                 case CONVERSATION_OPTIONS_LOADER:
107                     mListener.onOptionsCursorUpdated(this, data);
108                     break;
109 
110                 case PARTICIPANT_LOADER:
111                     mParticipantData.bind(data);
112                     mListener.onParticipantsListLoaded(this,
113                             mParticipantData.getParticipantListExcludingSelf());
114                     break;
115 
116                 default:
117                     Assert.fail("Unknown loader id for PeopleAndOptionsFragment!");
118                     break;
119             }
120         } else {
121             LogUtil.w(LogUtil.BUGLE_TAG,
122                     "Loader finished after unbinding PeopleAndOptionsFragment");
123         }
124     }
125 
126     /**
127      * {@inheritDoc}
128      */
129     @Override
onLoaderReset(final Loader<Cursor> loader)130     public void onLoaderReset(final Loader<Cursor> loader) {
131         final BoundCursorLoader cursorLoader = (BoundCursorLoader) loader;
132         if (isBound(cursorLoader.getBindingId())) {
133             switch (loader.getId()) {
134                 case CONVERSATION_OPTIONS_LOADER:
135                     mListener.onOptionsCursorUpdated(this, null);
136                     break;
137 
138                 case PARTICIPANT_LOADER:
139                     mParticipantData.bind(null);
140                     break;
141 
142                 default:
143                     Assert.fail("Unknown loader id for PeopleAndOptionsFragment!");
144                     break;
145             }
146         } else {
147             LogUtil.w(LogUtil.BUGLE_TAG, "Loader reset after unbinding PeopleAndOptionsFragment");
148         }
149     }
150 
init(final LoaderManager loaderManager, final BindingBase<PeopleAndOptionsData> binding)151     public void init(final LoaderManager loaderManager,
152             final BindingBase<PeopleAndOptionsData> binding) {
153         final Bundle args = new Bundle();
154         args.putString(BINDING_ID, binding.getBindingId());
155         mLoaderManager = loaderManager;
156         mLoaderManager.initLoader(CONVERSATION_OPTIONS_LOADER, args, this);
157         mLoaderManager.initLoader(PARTICIPANT_LOADER, args, this);
158     }
159 
160     @Override
unregisterListeners()161     protected void unregisterListeners() {
162         mListener = null;
163 
164         // This could be null if we bind but the caller doesn't init the BindableData
165         if (mLoaderManager != null) {
166             mLoaderManager.destroyLoader(CONVERSATION_OPTIONS_LOADER);
167             mLoaderManager.destroyLoader(PARTICIPANT_LOADER);
168             mLoaderManager = null;
169         }
170     }
171 
enableConversationNotifications(final BindingBase<PeopleAndOptionsData> binding, final boolean enable)172     public void enableConversationNotifications(final BindingBase<PeopleAndOptionsData> binding,
173             final boolean enable) {
174         final String bindingId = binding.getBindingId();
175         if (isBound(bindingId)) {
176             UpdateConversationOptionsAction.enableConversationNotifications(
177                     mConversationId, enable);
178         }
179     }
180 
setConversationNotificationSound(final BindingBase<PeopleAndOptionsData> binding, final String ringtoneUri)181     public void setConversationNotificationSound(final BindingBase<PeopleAndOptionsData> binding,
182             final String ringtoneUri) {
183         final String bindingId = binding.getBindingId();
184         if (isBound(bindingId)) {
185             UpdateConversationOptionsAction.setConversationNotificationSound(mConversationId,
186                     ringtoneUri);
187         }
188     }
189 
enableConversationNotificationVibration( final BindingBase<PeopleAndOptionsData> binding, final boolean enable)190     public void enableConversationNotificationVibration(
191             final BindingBase<PeopleAndOptionsData> binding, final boolean enable) {
192         final String bindingId = binding.getBindingId();
193         if (isBound(bindingId)) {
194             UpdateConversationOptionsAction.enableVibrationForConversationNotification(
195                     mConversationId, enable);
196         }
197     }
198 
setDestinationBlocked(final BindingBase<PeopleAndOptionsData> binding, final boolean blocked)199     public void setDestinationBlocked(final BindingBase<PeopleAndOptionsData> binding,
200             final boolean blocked) {
201         final String bindingId = binding.getBindingId();
202         final ParticipantData participantData = mParticipantData.getOtherParticipant();
203         if (isBound(bindingId) && participantData != null) {
204             UpdateDestinationBlockedAction.updateDestinationBlocked(
205                     participantData.getNormalizedDestination(),
206                     blocked, mConversationId,
207                     BugleActionToasts.makeUpdateDestinationBlockedActionListener(mContext));
208         }
209     }
210 }
211