1c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren/* 2c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * Copyright (C) 2012 The Android Open Source Project 3c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * 4c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * Licensed under the Apache License, Version 2.0 (the "License"); 5c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * you may not use this file except in compliance with the License. 6c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * You may obtain a copy of the License at 7c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * 8c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * http://www.apache.org/licenses/LICENSE-2.0 9c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * 10c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * Unless required by applicable law or agreed to in writing, software 11c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * distributed under the License is distributed on an "AS IS" BASIS, 12c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * See the License for the specific language governing permissions and 14c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren * limitations under the License. 15c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren */ 16c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wrenpackage com.android.dreams.phototable; 17c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 18c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wrenimport android.content.Context; 19d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wrenimport android.content.SharedPreferences; 20c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wrenimport android.database.Cursor; 21e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wrenimport android.net.ConnectivityManager; 22c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wrenimport android.net.Uri; 23c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wrenimport android.util.DisplayMetrics; 24146ce64b748e2393e80174240624c2e9f2b61c41Chris Wrenimport android.util.Log; 25c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wrenimport android.view.WindowManager; 26c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 27c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wrenimport java.io.FileNotFoundException; 28c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wrenimport java.io.InputStream; 29c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wrenimport java.io.IOException; 3083fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wrenimport java.util.Collection; 31146ce64b748e2393e80174240624c2e9f2b61c41Chris Wrenimport java.util.Collections; 32d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wrenimport java.util.HashMap; 33c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wrenimport java.util.LinkedList; 34d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wrenimport java.util.Set; 35c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 36c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren/** 3783fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren * Loads images from Picasa. 38c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren */ 3983fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wrenpublic class PicasaSource extends PhotoSource { 40c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren private static final String TAG = "PhotoTable.PicasaSource"; 41c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 42d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_AUTHORITY = 43d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren "com.google.android.gallery3d.GooglePhotoProvider"; 44d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 45d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_PHOTO_PATH = "photos"; 46d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_ALBUM_PATH = "albums"; 47e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private static final String PICASA_USER_PATH = "users"; 48d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 49c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren private static final String PICASA_ID = "_id"; 50c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren private static final String PICASA_URL = "content_url"; 51c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren private static final String PICASA_ROTATION = "rotation"; 52c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren private static final String PICASA_ALBUM_ID = "album_id"; 53d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_TITLE = "title"; 54d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_THUMB = "thumbnail_url"; 55d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_ALBUM_TYPE = "album_type"; 56c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren private static final String PICASA_ALBUM_USER = "user_id"; 57d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_ALBUM_UPDATED = "date_updated"; 58e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private static final String PICASA_ACCOUNT = "account"; 59c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 60c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren private static final String PICASA_URL_KEY = "content_url"; 61c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren private static final String PICASA_TYPE_KEY = "type"; 62d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_TYPE_FULL_VALUE = "full"; 63d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_TYPE_SCREEN_VALUE = "screennail"; 64d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_TYPE_THUMB_VALUE = "thumbnail"; 65d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private static final String PICASA_TYPE_IMAGE_VALUE = "image"; 66c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren private static final String PICASA_POSTS_TYPE = "Buzz"; 67c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren private static final String PICASA_UPLOAD_TYPE = "InstantUpload"; 68c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 69d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private final int mMaxPostAblums; 70e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private final String mPostsAlbumName; 71e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private final String mUploadsAlbumName; 72e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private final String mUnknownAlbumName; 73e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren private final LinkedList<ImageData> mRecycleBin; 74e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren private final ConnectivityManager mConnectivityManager; 75e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren private final int mMaxRecycleSize; 76c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 77d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren private Set<String> mFoundAlbumIds; 78d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren private int mNextPosition; 79c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren private int mDisplayLongSide; 8083fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren 81d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren public PicasaSource(Context context, SharedPreferences settings) { 82d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren super(context, settings); 8383fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren mSourceName = TAG; 84c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren mNextPosition = -1; 85d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren mMaxPostAblums = mResources.getInteger(R.integer.max_post_albums); 86e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mPostsAlbumName = mResources.getString(R.string.posts_album_name, "Posts"); 87e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mUploadsAlbumName = mResources.getString(R.string.uploads_album_name, "Instant Uploads"); 88e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren mUnknownAlbumName = mResources.getString(R.string.unknown_album_name, "Unknown"); 89e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren mMaxRecycleSize = mResources.getInteger(R.integer.recycle_image_pool_size); 90e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren mConnectivityManager = 91e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 92e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren mRecycleBin = new LinkedList<ImageData>(); 93c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren fillQueue(); 94c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren mDisplayLongSide = getDisplayLongSide(); 95c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren } 96c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren 97c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren private int getDisplayLongSide() { 98c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren DisplayMetrics metrics = new DisplayMetrics(); 99c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren WindowManager wm = (WindowManager) 100c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren mContext.getSystemService(Context.WINDOW_SERVICE); 101c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren wm.getDefaultDisplay().getMetrics(metrics); 102c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren return Math.max(metrics.heightPixels, metrics.widthPixels); 103c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 104c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 10583fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren @Override 10683fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren protected Collection<ImageData> findImages(int howMany) { 10783fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, "finding images"); 10883fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren LinkedList<ImageData> foundImages = new LinkedList<ImageData>(); 109e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren if (mConnectivityManager.isActiveNetworkMetered()) { 110e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren howMany = Math.min(howMany, mMaxRecycleSize); 111e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren log(TAG, "METERED: " + howMany); 112e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren if (!mRecycleBin.isEmpty()) { 113e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren foundImages.addAll(mRecycleBin); 114e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren log(TAG, "recycled " + foundImages.size() + " items."); 115e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren return foundImages; 116e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren } 117e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren } 118e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren 119c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren String[] projection = {PICASA_ID, PICASA_URL, PICASA_ROTATION, PICASA_ALBUM_ID}; 120d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren boolean usePosts = false; 121c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren LinkedList<String> albumIds = new LinkedList<String>(); 122d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren for (String id : getFoundAlbums()) { 123d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren if (mSettings.isAlbumEnabled(id)) { 124d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren String[] parts = id.split(":"); 125c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren if (parts.length > 2) { 126c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren albumIds.addAll(resolveAlbumIds(id)); 127c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren } else { 128c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren albumIds.add(parts[1]); 129d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 130c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 131c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 132c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren 133146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren if (albumIds.size() > mMaxPostAblums) { 134146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren Collections.shuffle(albumIds); 135146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren } 136146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren 137c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren StringBuilder selection = new StringBuilder(); 138146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren int albumIdx = 0; 139c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren for (String albumId : albumIds) { 140146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren if (albumIdx < mMaxPostAblums) { 141d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (selection.length() > 0) { 142d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren selection.append(" OR "); 143d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 144c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren log(TAG, "adding: " + albumId); 145146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren selection.append(PICASA_ALBUM_ID + " = '" + albumId + "'"); 146146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren } else { 147146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren log(TAG, "too many albums, dropping: " + albumId); 148d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 149146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren albumIdx++; 150d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 151d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 152d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (selection.length() == 0) { 153d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren return foundImages; 154d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 155c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren 156146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren log(TAG, "selection is (" + selection.length() + "): " + selection.toString()); 157d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 158c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren Uri.Builder picasaUriBuilder = new Uri.Builder() 159c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren .scheme("content") 160d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .authority(PICASA_AUTHORITY) 161d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .appendPath(PICASA_PHOTO_PATH); 162c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren Cursor cursor = mResolver.query(picasaUriBuilder.build(), 163d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren projection, selection.toString(), null, null); 164c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren if (cursor != null) { 16583fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren if (cursor.getCount() > howMany && mNextPosition == -1) { 166c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren mNextPosition = 16783fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren (int) Math.abs(mRNG.nextInt() % (cursor.getCount() - howMany)); 168c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 169c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren if (mNextPosition == -1) { 170c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren mNextPosition = 0; 171c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 17283fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, "moving to position: " + mNextPosition); 173c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren cursor.moveToPosition(mNextPosition); 174c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 175c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren int idIndex = cursor.getColumnIndex(PICASA_ID); 176c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren int urlIndex = cursor.getColumnIndex(PICASA_URL); 177c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren int orientationIndex = cursor.getColumnIndex(PICASA_ROTATION); 178c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren int bucketIndex = cursor.getColumnIndex(PICASA_ALBUM_ID); 179c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 180c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren if (idIndex < 0) { 18183fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, "can't find the ID column!"); 182c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } else { 18383fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren while (foundImages.size() < howMany && !cursor.isAfterLast()) { 184c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren if (idIndex >= 0) { 185c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren ImageData data = new ImageData(); 186c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren data.id = cursor.getString(idIndex); 187c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 188c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren if (urlIndex >= 0) { 189c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren data.url = cursor.getString(urlIndex); 190c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 191c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 19283fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren foundImages.offer(data); 193c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 194c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren if (cursor.moveToNext()) { 195c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren mNextPosition++; 196c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 197c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 198c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren if (cursor.isAfterLast()) { 199c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren mNextPosition = 0; 200c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 201c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 202c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 203c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren cursor.close(); 204146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren } else { 205146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren Log.w(TAG, "received a null cursor in findImages()"); 206c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 20783fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, "found " + foundImages.size() + " items."); 20883fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren return foundImages; 209c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 210c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 211e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren private String resolveAccount(String id) { 212e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren String displayName = "unknown"; 213e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren String[] projection = {PICASA_ACCOUNT}; 214e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren Uri.Builder picasaUriBuilder = new Uri.Builder() 215e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren .scheme("content") 216e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren .authority(PICASA_AUTHORITY) 217e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren .appendPath(PICASA_USER_PATH) 218e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren .appendPath(id); 219e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren Cursor cursor = mResolver.query(picasaUriBuilder.build(), 220e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren projection, null, null, null); 221e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (cursor != null) { 222e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren cursor.moveToFirst(); 223e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren int accountIndex = cursor.getColumnIndex(PICASA_ACCOUNT); 224e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (accountIndex >= 0) { 225e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren displayName = cursor.getString(accountIndex); 226e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 227e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren cursor.close(); 228146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren } else { 229146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren Log.w(TAG, "received a null cursor in resolveAccount()"); 230e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 231e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren return displayName; 232e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 233e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 234c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren private Collection<String> resolveAlbumIds(String id) { 235c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren LinkedList<String> albumIds = new LinkedList<String>(); 236c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren log(TAG, "resolving " + id); 237c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren 238c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren String[] parts = id.split(":"); 239c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren if (parts.length < 3) { 240c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren return albumIds; 241c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren } 242c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren 243c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren String[] projection = {PICASA_ID, PICASA_ALBUM_TYPE, PICASA_ALBUM_UPDATED, 244c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren PICASA_ALBUM_USER}; 245d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren String order = PICASA_ALBUM_UPDATED + " DESC"; 246e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren String selection = (PICASA_ALBUM_USER + " = '" + parts[2] + "' AND " + 247c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren PICASA_ALBUM_TYPE + " = '" + parts[1] + "'"); 248d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren Uri.Builder picasaUriBuilder = new Uri.Builder() 249d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .scheme("content") 250d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .authority(PICASA_AUTHORITY) 251d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .appendPath(PICASA_ALBUM_PATH) 252d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .appendQueryParameter(PICASA_TYPE_KEY, PICASA_TYPE_IMAGE_VALUE); 253d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren Cursor cursor = mResolver.query(picasaUriBuilder.build(), 254c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren projection, selection, null, order); 255d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (cursor != null) { 256146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren log(TAG, " " + id + " resolved to " + cursor.getCount() + " albums"); 257d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren cursor.moveToFirst(); 258d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 259d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int idIndex = cursor.getColumnIndex(PICASA_ID); 260d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int typeIndex = cursor.getColumnIndex(PICASA_ALBUM_TYPE); 261d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 262d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (idIndex < 0) { 263d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren log(TAG, "can't find the ID column!"); 264d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } else { 265c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren while (!cursor.isAfterLast()) { 266c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren albumIds.add(cursor.getString(idIndex)); 267d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren cursor.moveToNext(); 268d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 269d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 270d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren cursor.close(); 271146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren } else { 272146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren Log.w(TAG, "received a null cursor in resolveAlbumIds()"); 273d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 274c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren return albumIds; 275d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 276d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 277d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren private Set<String> getFoundAlbums() { 278d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren if (mFoundAlbumIds == null) { 279d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren findAlbums(); 280d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren } 281d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren return mFoundAlbumIds; 282d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren } 283d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren 284d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren @Override 285d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren public Collection<AlbumData> findAlbums() { 286d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren log(TAG, "finding albums"); 287d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren HashMap<String, AlbumData> foundAlbums = new HashMap<String, AlbumData>(); 288e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren HashMap<String, String> accounts = new HashMap<String, String>(); 289d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren String[] projection = {PICASA_ID, PICASA_TITLE, PICASA_THUMB, PICASA_ALBUM_TYPE, 290c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren PICASA_ALBUM_USER, PICASA_ALBUM_UPDATED}; 291d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren Uri.Builder picasaUriBuilder = new Uri.Builder() 292d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .scheme("content") 293d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .authority(PICASA_AUTHORITY) 294d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .appendPath(PICASA_ALBUM_PATH) 295d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .appendQueryParameter(PICASA_TYPE_KEY, PICASA_TYPE_IMAGE_VALUE); 296d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren Cursor cursor = mResolver.query(picasaUriBuilder.build(), 297d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren projection, null, null, null); 298d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (cursor != null) { 299d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren cursor.moveToFirst(); 300d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 301d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int idIndex = cursor.getColumnIndex(PICASA_ID); 302d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int thumbIndex = cursor.getColumnIndex(PICASA_THUMB); 303d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int titleIndex = cursor.getColumnIndex(PICASA_TITLE); 304d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int typeIndex = cursor.getColumnIndex(PICASA_ALBUM_TYPE); 305d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren int updatedIndex = cursor.getColumnIndex(PICASA_ALBUM_UPDATED); 306c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren int userIndex = cursor.getColumnIndex(PICASA_ALBUM_USER); 307d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 308d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren if (idIndex < 0) { 309d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren log(TAG, "can't find the ID column!"); 310d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } else { 311d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren while (!cursor.isAfterLast()) { 312d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren String id = TAG + ":" + cursor.getString(idIndex); 313c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren String user = (userIndex >= 0 ? cursor.getString(userIndex) : "-1"); 314c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren String type = (typeIndex >= 0 ? cursor.getString(typeIndex) : "none"); 315c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren boolean isPosts = (typeIndex >= 0 && PICASA_POSTS_TYPE.equals(type)); 316c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren boolean isUpload = (typeIndex >= 0 && PICASA_UPLOAD_TYPE.equals(type)); 317c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren 318e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren String account = accounts.get(user); 319e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren if (account == null) { 320e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren account = resolveAccount(user); 321e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren accounts.put(user, account); 322e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren } 323e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren 324c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren if (isPosts) { 325146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren log(TAG, "replacing " + id + " with " + PICASA_POSTS_TYPE); 326c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren id = TAG + ":" + PICASA_POSTS_TYPE + ":" + user; 327c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren } 328d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 329c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren if (isUpload) { 330146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren log(TAG, "replacing " + id + " with " + PICASA_UPLOAD_TYPE); 331c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren id = TAG + ":" + PICASA_UPLOAD_TYPE + ":" + user; 332d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 333c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren 334c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren String thumbnailUrl = null; 335c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren long updated = 0; 3365b4b44688dac0053be77b282b7501bd291efb0d3Chris Wren AlbumData data = foundAlbums.get(id); 3375b4b44688dac0053be77b282b7501bd291efb0d3Chris Wren if (data == null) { 3385b4b44688dac0053be77b282b7501bd291efb0d3Chris Wren data = new AlbumData(); 339d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren data.id = id; 340e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren data.account = account; 341d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 342c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren if (isPosts) { 343e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren data.title = mPostsAlbumName; 344c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren } else if (isUpload) { 345e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren data.title = mUploadsAlbumName; 346d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } else if (titleIndex >= 0) { 347d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren data.title = cursor.getString(titleIndex); 348d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } else { 349e38c0c80e3e9b3b835e5c2e014ccf23e29663396Chris Wren data.title = mUnknownAlbumName; 350d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 351d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 352c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren log(TAG, "found " + data.title + "(" + data.id + ")" + 353146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren " of type " + type + " owned by " + user); 354d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren foundAlbums.put(id, data); 355d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 356d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 3575b4b44688dac0053be77b282b7501bd291efb0d3Chris Wren if (updatedIndex >= 0) { 358146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren updated = cursor.getLong(updatedIndex); 359c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren } 360c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren 361146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren if (thumbIndex >= 0) { 362146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren thumbnailUrl = cursor.getString(thumbIndex); 363146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren } 364146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren 365146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren data.updated = (long) Math.max(data.updated, updated); 366146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren 367c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren if (data.thumbnailUrl == null || data.updated == updated) { 368c6175b1e065fb544ea3744a991a33304abc2f8edChris Wren data.thumbnailUrl = thumbnailUrl; 3695b4b44688dac0053be77b282b7501bd291efb0d3Chris Wren } 3705b4b44688dac0053be77b282b7501bd291efb0d3Chris Wren 371d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren cursor.moveToNext(); 372d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 373d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 374d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren cursor.close(); 375d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 376146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren } else { 377146ce64b748e2393e80174240624c2e9f2b61c41Chris Wren Log.w(TAG, "received a null cursor in findAlbums()"); 378d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 379d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren log(TAG, "found " + foundAlbums.size() + " items."); 380d9b659aa5dfa4a3af96582ae49ba9ae145854a84Chris Wren mFoundAlbumIds = foundAlbums.keySet(); 381d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren return foundAlbums.values(); 382d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren } 383d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren 38483fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren @Override 385c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren protected InputStream getStream(ImageData data, int longSide) { 38683fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren InputStream is = null; 38783fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren try { 38883fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren Uri.Builder photoUriBuilder = new Uri.Builder() 38983fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren .scheme("content") 390d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .authority(PICASA_AUTHORITY) 391d85f53c69dead1f1f6c0290b8104422143bc5166Chris Wren .appendPath(PICASA_PHOTO_PATH) 392e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren .appendPath(data.id); 393c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren if (mConnectivityManager.isActiveNetworkMetered() || 394c6bebae5e07c0108294d05e33fbace209d2f9b0dChris Wren ((2 * longSide) <= mDisplayLongSide)) { 395e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren photoUriBuilder.appendQueryParameter(PICASA_TYPE_KEY, PICASA_TYPE_SCREEN_VALUE); 396e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren } else { 397e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren photoUriBuilder.appendQueryParameter(PICASA_TYPE_KEY, PICASA_TYPE_FULL_VALUE); 398e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren } 39983fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren if (data.url != null) { 40083fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren photoUriBuilder.appendQueryParameter(PICASA_URL_KEY, data.url); 401c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 40283fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren is = mResolver.openInputStream(photoUriBuilder.build()); 40383fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren } catch (FileNotFoundException fnf) { 40483fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, "file not found: " + fnf); 40583fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren is = null; 40683fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren } catch (IOException ioe) { 40783fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren log(TAG, "i/o exception: " + ioe); 40883fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren is = null; 409c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 410c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren 411e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren if (is != null) { 412e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren mRecycleBin.offer(data); 413e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren log(TAG, "RECYCLED"); 414e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren while (mRecycleBin.size() > mMaxRecycleSize) { 415e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren mRecycleBin.poll(); 416e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren } 417e8f4d55d6895e1f2bc298ef8978e1aef43ff57c5Chris Wren } 41883fee9012b6d5c5940de5b96fe8d98653ba14c0dChris Wren return is; 419c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren } 420c1501041b64faa6c205a93baf403c4c87a0c1acfChris Wren} 421