1 /*
2  * Copyright (C) 2013 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.camera.data;
18 
19 import android.content.Context;
20 import android.net.Uri;
21 import android.os.AsyncTask;
22 import android.view.View;
23 
24 import com.android.camera.data.FilmstripItem.VideoClickedCallback;
25 import com.android.camera.debug.Log;
26 import com.android.camera.filmstrip.FilmstripDataAdapter;
27 import com.google.common.base.Optional;
28 
29 /**
30  * A {@link LocalFilmstripDataAdapter} which puts a {@link FilmstripItem} fixed at the first
31  * position. It's done by combining a {@link FilmstripItem} and another
32  * {@link LocalFilmstripDataAdapter}.
33  */
34 public class FixedFirstProxyAdapter extends FilmstripDataAdapterProxy
35         implements FilmstripDataAdapter.Listener {
36     @SuppressWarnings("unused")
37     private static final Log.Tag TAG = new Log.Tag("FixedFirstDataAdpt");
38 
39     private FilmstripItem mFirstData;
40     private Listener mListener;
41 
42     /**
43      * Constructor.
44      *
45      * @param context Valid Android context.
46      * @param wrappedAdapter The {@link LocalFilmstripDataAdapter} to be wrapped.
47      * @param firstData The {@link FilmstripItem} to be placed at the first
48      *            position.
49      */
FixedFirstProxyAdapter( Context context, LocalFilmstripDataAdapter wrappedAdapter, FilmstripItem firstData)50     public FixedFirstProxyAdapter(
51           Context context,
52           LocalFilmstripDataAdapter wrappedAdapter,
53           FilmstripItem firstData) {
54         super(context, wrappedAdapter);
55         if (firstData == null) {
56             throw new AssertionError("data is null");
57         }
58         mFirstData = firstData;
59     }
60 
61     @Override
getItemAt(int index)62     public FilmstripItem getItemAt(int index) {
63         if (index == 0) {
64             return mFirstData;
65         }
66         return mAdapter.getItemAt(index - 1);
67     }
68 
69     @Override
removeAt(int index)70     public void removeAt(int index) {
71         if (index > 0) {
72             mAdapter.removeAt(index - 1);
73         }
74     }
75 
76     @Override
findByContentUri(Uri uri)77     public int findByContentUri(Uri uri) {
78         int pos = mAdapter.findByContentUri(uri);
79         if (pos != -1) {
80             return pos + 1;
81         }
82         return -1;
83     }
84 
85     @Override
updateItemAt(int pos, FilmstripItem item)86     public void updateItemAt(int pos, FilmstripItem item) {
87         if (pos == 0) {
88             mFirstData = item;
89             if (mListener != null) {
90                 mListener.onFilmstripItemUpdated(new UpdateReporter() {
91                     @Override
92                     public boolean isDataRemoved(int index) {
93                         return false;
94                     }
95 
96                     @Override
97                     public boolean isDataUpdated(int index) {
98                         return (index == 0);
99                     }
100                 });
101             }
102         } else {
103             mAdapter.updateItemAt(pos - 1, item);
104         }
105     }
106 
107     @Override
getTotalNumber()108     public int getTotalNumber() {
109         return (mAdapter.getTotalNumber() + 1);
110     }
111 
112     @Override
getView(View recycled, int index, VideoClickedCallback videoClickedCallback)113     public View getView(View recycled, int index, VideoClickedCallback videoClickedCallback) {
114         if (index == 0) {
115             mFirstData.setSuggestedSize(mSuggestedWidth, mSuggestedHeight);
116             return mFirstData.getView(Optional.fromNullable(recycled), null, false,
117                   videoClickedCallback);
118         }
119         return mAdapter.getView(recycled, index - 1, videoClickedCallback);
120     }
121 
122     @Override
getItemViewType(int index)123     public int getItemViewType(int index) {
124         if (index == 0) {
125             return mFirstData.getItemViewType().ordinal();
126         }
127         return mAdapter.getItemViewType(index);
128     }
129 
130     @Override
getFilmstripItemAt(int index)131     public FilmstripItem getFilmstripItemAt(int index) {
132         if (index == 0) {
133             return mFirstData;
134         }
135         return mAdapter.getFilmstripItemAt(index - 1);
136     }
137 
138     @Override
setListener(Listener listener)139     public void setListener(Listener listener) {
140         mListener = listener;
141         mAdapter.setListener((listener == null) ? null : this);
142         // The first data is always there. Thus, When the listener is set,
143         // we should call listener.onFilmstripItemLoaded().
144         if (mListener != null) {
145             mListener.onFilmstripItemLoaded();
146         }
147     }
148 
149     @Override
onFilmstripItemLoaded()150     public void onFilmstripItemLoaded() {
151         if (mListener == null) {
152             return;
153         }
154         mListener.onFilmstripItemUpdated(new UpdateReporter() {
155             @Override
156             public boolean isDataRemoved(int index) {
157                 return false;
158             }
159 
160             @Override
161             public boolean isDataUpdated(int index) {
162                 return (index != 0);
163             }
164         });
165     }
166 
167     @Override
onFilmstripItemUpdated(final UpdateReporter reporter)168     public void onFilmstripItemUpdated(final UpdateReporter reporter) {
169         mListener.onFilmstripItemUpdated(new UpdateReporter() {
170             @Override
171             public boolean isDataRemoved(int index) {
172                 return (index != 0) && reporter.isDataRemoved(index - 1);
173             }
174 
175             @Override
176             public boolean isDataUpdated(int index) {
177                 return (index != 0) && reporter.isDataUpdated(index - 1);
178             }
179         });
180     }
181 
182     @Override
onFilmstripItemInserted(int index, FilmstripItem item)183     public void onFilmstripItemInserted(int index, FilmstripItem item) {
184         mListener.onFilmstripItemInserted(index + 1, item);
185     }
186 
187     @Override
onFilmstripItemRemoved(int index, FilmstripItem item)188     public void onFilmstripItemRemoved(int index, FilmstripItem item) {
189         mListener.onFilmstripItemRemoved(index + 1, item);
190     }
191 
192     @Override
updateMetadataAt(int index)193     public AsyncTask updateMetadataAt(int index) {
194         if (index > 0) {
195             return mAdapter.updateMetadataAt(index - 1);
196         } else {
197             MetadataLoader.loadMetadata(mContext, mFirstData);
198         }
199         return null;
200     }
201 
202     @Override
isMetadataUpdatedAt(int index)203     public boolean isMetadataUpdatedAt(int index) {
204         if (index > 0) {
205             return mAdapter.isMetadataUpdatedAt(index - 1);
206         } else {
207             return mFirstData.getMetadata().isLoaded();
208         }
209     }
210 }
211