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