1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/* 2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project 3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License"); 5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License. 6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at 7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * http://www.apache.org/licenses/LICENSE-2.0 9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * 10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software 11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS, 12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and 14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License. 15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */ 16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 17d6db8eab6df048b9065834113a6d46a885af01d3Owen Linpackage com.android.gallery3d.gadget; 18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 19a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Linimport android.annotation.TargetApi; 20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.appwidget.AppWidgetManager; 21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.Intent; 22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.graphics.Bitmap; 23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri; 24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.widget.RemoteViews; 25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.widget.RemoteViewsService; 26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 272b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.R; 282b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.app.GalleryApp; 29a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Linimport com.android.gallery3d.common.ApiHelper; 302b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.data.ContentListener; 312b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.data.DataManager; 322b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.data.MediaSet; 332b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Linimport com.android.gallery3d.data.Path; 342b3ee0ea07246b859a5b75d8a6102a7cce7ec838Owen Lin 35a2cb30b688131380cab763a1b4da25f15a9fa45aOwen Lin@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB) 36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class WidgetService extends RemoteViewsService { 37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @SuppressWarnings("unused") 39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static final String TAG = "GalleryAppWidgetService"; 40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static final String EXTRA_WIDGET_TYPE = "widget-type"; 42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public static final String EXTRA_ALBUM_PATH = "album-path"; 43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public RemoteViewsFactory onGetViewFactory(Intent intent) { 46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int id = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, 47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AppWidgetManager.INVALID_APPWIDGET_ID); 48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin int type = intent.getIntExtra(EXTRA_WIDGET_TYPE, 0); 49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin String albumPath = intent.getStringExtra(EXTRA_ALBUM_PATH); 50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return new PhotoRVFactory((GalleryApp) getApplicationContext(), 52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin id, type, albumPath); 53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static class EmptySource implements WidgetSource { 56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int size() { 59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return 0; 60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Bitmap getImage(int index) { 64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin throw new UnsupportedOperationException(); 65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public Uri getContentUri(int index) { 69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin throw new UnsupportedOperationException(); 70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void setContentListener(ContentListener listener) {} 74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void reload() {} 77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void close() {} 80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private static class PhotoRVFactory implements 83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin RemoteViewsService.RemoteViewsFactory, ContentListener { 84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mAppWidgetId; 86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final int mType; 87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final String mAlbumPath; 88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private final GalleryApp mApp; 89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin private WidgetSource mSource; 91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public PhotoRVFactory(GalleryApp app, int id, int type, String albumPath) { 93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mApp = app; 94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAppWidgetId = id; 95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mType = type; 96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAlbumPath = albumPath; 97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onCreate() { 101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (mType == WidgetDatabaseHelper.TYPE_ALBUM) { 102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Path path = Path.fromString(mAlbumPath); 103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin DataManager manager = mApp.getDataManager(); 104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin MediaSet mediaSet = (MediaSet) manager.getMediaObject(path); 105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource = mediaSet == null 106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin ? new EmptySource() 107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin : new MediaSetSource(mediaSet); 108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } else { 109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource = new LocalPhotoSource(mApp.getAndroidContext()); 110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource.setContentListener(this); 112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AppWidgetManager.getInstance(mApp.getAndroidContext()) 113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin .notifyAppWidgetViewDataChanged( 114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAppWidgetId, R.id.appwidget_stack_view); 115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onDestroy() { 119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource.close(); 120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource = null; 121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1237817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getCount() { 125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return mSource.size(); 126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1287817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public long getItemId(int position) { 130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return position; 131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1337817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public int getViewTypeCount() { 135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return 1; 136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1387817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public boolean hasStableIds() { 140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return true; 141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1437817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public RemoteViews getLoadingView() { 145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin RemoteViews rv = new RemoteViews( 146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mApp.getAndroidContext().getPackageName(), 147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin R.layout.appwidget_loading_item); 148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin rv.setProgressBar(R.id.appwidget_loading_item, 0, 0, true); 149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return rv; 150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 1527817979db0c52ffeacb951625b1e821eba303285Ahbong Chang @Override 153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public RemoteViews getViewAt(int position) { 154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin Bitmap bitmap = mSource.getImage(position); 155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin if (bitmap == null) return getLoadingView(); 156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin RemoteViews views = new RemoteViews( 157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mApp.getAndroidContext().getPackageName(), 158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin R.layout.appwidget_photo_item); 159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin views.setImageViewBitmap(R.id.appwidget_photo_item, bitmap); 160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin views.setOnClickFillInIntent(R.id.appwidget_photo_item, new Intent() 161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin .setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin .setData(mSource.getContentUri(position))); 163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin return views; 164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onDataSetChanged() { 168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mSource.reload(); 169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin 171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin @Override 172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin public void onContentDirty() { 173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin AppWidgetManager.getInstance(mApp.getAndroidContext()) 174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin .notifyAppWidgetViewDataChanged( 175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin mAppWidgetId, R.id.appwidget_stack_view); 176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin } 178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin} 179