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.messaging.datamodel.data;
18
19import android.app.LoaderManager;
20import android.content.Context;
21import android.content.Loader;
22import android.database.Cursor;
23import android.net.Uri;
24import android.os.Bundle;
25
26import com.android.messaging.datamodel.BoundCursorLoader;
27import com.android.messaging.datamodel.MessagingContentProvider;
28import com.android.messaging.datamodel.action.BugleActionToasts;
29import com.android.messaging.datamodel.action.UpdateConversationOptionsAction;
30import com.android.messaging.datamodel.action.UpdateDestinationBlockedAction;
31import com.android.messaging.datamodel.binding.BindableData;
32import com.android.messaging.datamodel.binding.BindingBase;
33import com.android.messaging.util.Assert;
34import com.android.messaging.util.LogUtil;
35
36import java.util.List;
37
38/**
39 * Services data needs for PeopleAndOptionsFragment.
40 */
41public class PeopleAndOptionsData extends BindableData implements
42        LoaderManager.LoaderCallbacks<Cursor> {
43    public interface PeopleAndOptionsDataListener {
44        void onOptionsCursorUpdated(PeopleAndOptionsData data, Cursor cursor);
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
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
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
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
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
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
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
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
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
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
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