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