OSDN Git Service

theme engine fixes
[android-x86/packages-apps-Eleven.git] / src / com / android / music / MediaAppWidgetProvider4x2.java
1 /*\r
2  * Copyright (C) 2009 The Android Open Source Project\r
3  *\r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 package com.android.music;\r
18 \r
19 import android.app.PendingIntent;\r
20 import android.appwidget.AppWidgetManager;\r
21 import android.appwidget.AppWidgetProvider;\r
22 import android.content.ComponentName;\r
23 import android.content.Context;\r
24 import android.content.Intent;\r
25 import android.content.SharedPreferences;\r
26 import android.content.pm.PackageManager;\r
27 import android.content.pm.PackageManager.NameNotFoundException;\r
28 import android.content.res.Resources;\r
29 import android.graphics.Color;\r
30 import android.net.Uri;\r
31 import android.os.Environment;\r
32 import android.preference.PreferenceManager;\r
33 import android.view.View;\r
34 import android.widget.RemoteViews;\r
35 \r
36 /**\r
37  * Simple widget to show currently playing album art along with play/pause and\r
38  * next track buttons.\r
39  */\r
40 public class MediaAppWidgetProvider4x2 extends AppWidgetProvider {\r
41         static final String TAG = "MusicAppWidgetProvider4x2";\r
42 \r
43         public static final String CMDAPPWIDGETUPDATE = "appwidgetupdate4x2";\r
44 \r
45         // ADW Theme constants\r
46         public static final int THEME_ITEM_BACKGROUND = 0;\r
47         public static final int THEME_ITEM_FOREGROUND = 1;\r
48         private static MediaAppWidgetProvider4x2 sInstance;\r
49 \r
50         static synchronized MediaAppWidgetProvider4x2 getInstance() {\r
51                 if (sInstance == null) {\r
52                         sInstance = new MediaAppWidgetProvider4x2();\r
53                 }\r
54                 return sInstance;\r
55         }\r
56 \r
57         @Override\r
58         public void onUpdate(Context context, AppWidgetManager appWidgetManager,\r
59                         int[] appWidgetIds) {\r
60                 defaultAppWidget(context, appWidgetIds);\r
61 \r
62                 // Send broadcast intent to any running MediaPlaybackService so it can\r
63                 // wrap around with an immediate update.\r
64                 Intent updateIntent = new Intent(MediaPlaybackService.SERVICECMD);\r
65                 updateIntent.putExtra(MediaPlaybackService.CMDNAME,\r
66                                 MediaAppWidgetProvider4x2.CMDAPPWIDGETUPDATE);\r
67                 updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,\r
68                                 appWidgetIds);\r
69                 updateIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);\r
70                 context.sendBroadcast(updateIntent);\r
71         }\r
72 \r
73         /**\r
74          * Initialize given widgets to default state, where we launch Music on\r
75          * default click and hide actions if service not running.\r
76          */\r
77         private void defaultAppWidget(Context context, int[] appWidgetIds) {\r
78                 final Resources res = context.getResources();\r
79                 final RemoteViews views = new RemoteViews(context.getPackageName(),\r
80                                 R.layout.album_appwidget4x2);\r
81 \r
82                 views.setViewVisibility(R.id.albumname, View.GONE);\r
83                 views.setViewVisibility(R.id.trackname, View.GONE);\r
84                 views.setTextViewText(R.id.artistname,\r
85                                 res.getText(R.string.widget_initial_text));\r
86                 views.setImageViewResource(R.id.albumart,\r
87                                 R.drawable.albumart_mp_unknown);\r
88 \r
89                 linkButtons(context, views, false /* not playing */);\r
90                 pushUpdate(context, appWidgetIds, views);\r
91         }\r
92 \r
93         private void pushUpdate(Context context, int[] appWidgetIds,\r
94                         RemoteViews views) {\r
95                 // Update specific list of appWidgetIds if given, otherwise default to\r
96                 // all\r
97                 final AppWidgetManager gm = AppWidgetManager.getInstance(context);\r
98                 if (appWidgetIds != null) {\r
99                         gm.updateAppWidget(appWidgetIds, views);\r
100                 } else {\r
101                         gm.updateAppWidget(new ComponentName(context, this.getClass()),\r
102                                         views);\r
103                 }\r
104         }\r
105 \r
106         /**\r
107          * Check against {@link AppWidgetManager} if there are any instances of this\r
108          * widget.\r
109          */\r
110         private boolean hasInstances(Context context) {\r
111                 AppWidgetManager appWidgetManager = AppWidgetManager\r
112                                 .getInstance(context);\r
113                 int[] appWidgetIds = appWidgetManager\r
114                                 .getAppWidgetIds(new ComponentName(context, this.getClass()));\r
115                 return (appWidgetIds.length > 0);\r
116         }\r
117 \r
118         /**\r
119          * Handle a change notification coming over from\r
120          * {@link MediaPlaybackService}\r
121          */\r
122         void notifyChange(MediaPlaybackService service, String what) {\r
123                 if (hasInstances(service)) {\r
124                         if (MediaPlaybackService.META_CHANGED.equals(what)\r
125                                         || MediaPlaybackService.PROGRESSBAR_CHANGED.equals(what)\r
126                                         || MediaPlaybackService.PLAYSTATE_CHANGED.equals(what)\r
127                                         || MediaPlaybackService.REPEATMODE_CHANGED.equals(what)\r
128                                         || MediaPlaybackService.SHUFFLEMODE_CHANGED.equals(what)) {\r
129                                 performUpdate(service, null);\r
130                         }\r
131                 }\r
132         }\r
133 \r
134         /**\r
135          * Update all active widget instances by pushing changes\r
136          */\r
137         void performUpdate(MediaPlaybackService service, int[] appWidgetIds) {\r
138                 final Resources res = service.getResources();\r
139                 final RemoteViews views = new RemoteViews(service.getPackageName(),\r
140                                 R.layout.album_appwidget4x2);\r
141 \r
142                 CharSequence artistName = service.getArtistName();\r
143                 CharSequence albumName = service.getAlbumName();\r
144                 CharSequence trackName = service.getTrackName();\r
145                 long albumId = service.getAlbumId();\r
146                 long songId = service.getAudioId();\r
147                 long pos = service.position();\r
148                 long dur = service.duration();\r
149                 CharSequence errorState = null;\r
150 \r
151                 // Format title string with track number, or show SD card message\r
152                 String status = Environment.getExternalStorageState();\r
153                 if (status.equals(Environment.MEDIA_SHARED)\r
154                                 || status.equals(Environment.MEDIA_UNMOUNTED)) {\r
155                         if (android.os.Environment.isExternalStorageRemovable()) {\r
156                                 errorState = res.getText(R.string.sdcard_busy_title);\r
157                         } else {\r
158                                 errorState = res.getText(R.string.sdcard_busy_title_nosdcard);\r
159                         }\r
160                 } else if (status.equals(Environment.MEDIA_REMOVED)) {\r
161                         if (android.os.Environment.isExternalStorageRemovable()) {\r
162                                 errorState = res.getText(R.string.sdcard_missing_title);\r
163                         } else {\r
164                                 errorState = res\r
165                                                 .getText(R.string.sdcard_missing_title_nosdcard);\r
166                         }\r
167                 } else if (trackName == null) {\r
168                         errorState = res.getText(R.string.emptyplaylist);\r
169                 }\r
170                 SharedPreferences mPrefs = PreferenceManager\r
171                                 .getDefaultSharedPreferences(service);\r
172                 int aColor = new Integer(mPrefs.getInt(null,\r
173                                 MusicSettingsActivity.DEFAULT_SCREENSAVER_COLOR_ALPHA));\r
174                 int rColor = new Integer(mPrefs.getInt(null,\r
175                                 MusicSettingsActivity.DEFAULT_SCREENSAVER_COLOR_RED));\r
176                 int gColor = new Integer(mPrefs.getInt(null,\r
177                                 MusicSettingsActivity.DEFAULT_SCREENSAVER_COLOR_GREEN));\r
178                 int bColor = new Integer(mPrefs.getInt(null,\r
179                                 MusicSettingsActivity.DEFAULT_SCREENSAVER_COLOR_BLUE));\r
180                 int SCREEN_SAVER_COLOR_DIM = Color.argb(aColor, rColor, gColor, bColor);\r
181 \r
182                 if (errorState != null) {\r
183                         // Show error state to user\r
184                         views.setViewVisibility(R.id.albumname, View.GONE);\r
185                         views.setViewVisibility(R.id.trackname, View.GONE);\r
186                         views.setTextViewText(R.id.artistname, errorState);\r
187                         views.setImageViewResource(R.id.albumart,\r
188                                         R.drawable.albumart_mp_unknown);\r
189                 } else {\r
190                         // No error, so show normal titles and artwork\r
191                         views.setViewVisibility(R.id.albumname, View.VISIBLE);\r
192                         views.setViewVisibility(R.id.trackname, View.VISIBLE);\r
193                         views.setTextViewText(R.id.artistname, "  " + artistName);\r
194                         views.setTextViewText(R.id.albumname, "  " + albumName);\r
195                         views.setTextViewText(R.id.trackname, "  " + trackName);\r
196                         views.setTextColor(R.id.artistname, SCREEN_SAVER_COLOR_DIM);\r
197                         views.setTextColor(R.id.albumname, SCREEN_SAVER_COLOR_DIM);\r
198                         views.setTextColor(R.id.trackname, SCREEN_SAVER_COLOR_DIM);\r
199                         views.setProgressBar(R.id.progress, 1000, (int) (1000 * pos / dur),\r
200                                         false);\r
201 \r
202                         // Set album art\r
203                         Uri uri = MusicUtils.getArtworkUri(service, songId, albumId);\r
204                         if (uri != null) {\r
205                                 views.setImageViewUri(R.id.albumart, uri);\r
206                         } else {\r
207                                 views.setImageViewResource(R.id.albumart,\r
208                                                 R.drawable.albumart_mp_unknown);\r
209                         }\r
210                 }\r
211 \r
212                 // Set correct drawable for pause state\r
213                 final boolean playing = service.isPlaying();\r
214                 if (playing) {\r
215                         views.setImageViewResource(R.id.control_play,\r
216                                         R.drawable.ic_media_pause);\r
217                 } else {\r
218                         views.setImageViewResource(R.id.control_play,\r
219                                         R.drawable.ic_appwidget_music_play);\r
220                 }\r
221 \r
222                 // Set correct drawable for repeat state\r
223                 switch (service.getRepeatMode()) {\r
224                 case MediaPlaybackService.REPEAT_ALL:\r
225                         views.setImageViewResource(R.id.control_repeat,\r
226                                         R.drawable.ic_mp_repeat_all_btn);\r
227                         break;\r
228                 case MediaPlaybackService.REPEAT_CURRENT:\r
229                         views.setImageViewResource(R.id.control_repeat,\r
230                                         R.drawable.ic_mp_repeat_once_btn);\r
231                         break;\r
232                 default:\r
233                         views.setImageViewResource(R.id.control_repeat,\r
234                                         R.drawable.ic_mp_repeat_off_btn);\r
235                         break;\r
236                 }\r
237 \r
238                 // Set correct drawable for shuffle state\r
239                 switch (service.getShuffleMode()) {\r
240                 case MediaPlaybackService.SHUFFLE_NONE:\r
241                         views.setImageViewResource(R.id.control_shuffle,\r
242                                         R.drawable.ic_mp_shuffle_off_btn);\r
243                         break;\r
244                 case MediaPlaybackService.SHUFFLE_AUTO:\r
245                         views.setImageViewResource(R.id.control_shuffle,\r
246                                         R.drawable.ic_mp_partyshuffle_on_btn);\r
247                         break;\r
248                 default:\r
249                         views.setImageViewResource(R.id.control_shuffle,\r
250                                         R.drawable.ic_mp_shuffle_on_btn);\r
251                         break;\r
252                 }\r
253                 // Link actions buttons to intents\r
254                 linkButtons(service, views, playing);\r
255 \r
256                 pushUpdate(service, appWidgetIds, views);\r
257 \r
258         }\r
259 \r
260         /**\r
261          * Link up various button actions using {@link PendingIntents}.\r
262          * \r
263          * @param playerActive\r
264          *            True if player is active in background, which means widget\r
265          *            click will launch {@link MediaPlaybackActivity}, otherwise we\r
266          *            launch {@link MusicBrowserActivity}.\r
267          */\r
268         private void linkButtons(Context context, RemoteViews views,\r
269                         boolean playerActive) {\r
270 \r
271                 // ADW: Load the specified theme\r
272                 String themePackage = MusicUtils.getThemePackageName(context,\r
273                                 MusicSettingsActivity.THEME_DEFAULT);\r
274                 PackageManager pm = context.getPackageManager();\r
275                 Resources themeResources = null;\r
276                 if (!themePackage.equals(MusicSettingsActivity.THEME_DEFAULT)) {\r
277                         try {\r
278                                 themeResources = pm.getResourcesForApplication(themePackage);\r
279                         } catch (NameNotFoundException e) {\r
280                                 // ADW The saved theme was uninstalled so we save the\r
281                                 // default one\r
282                                 MusicUtils.setThemePackageName(context,\r
283                                                 MusicSettingsActivity.THEME_DEFAULT);\r
284                         }\r
285                         int albumName = themeResources.getIdentifier(\r
286                                         "four_by_two_album_name", "color", themePackage);\r
287                         if (albumName != 0) {\r
288                                 views.setTextColor(R.id.albumname,\r
289                                                 themeResources.getColor(albumName));\r
290                         }\r
291                         int trackName = themeResources.getIdentifier(\r
292                                         "four_by_two_track_name", "color", themePackage);\r
293                         if (trackName != 0) {\r
294                                 views.setTextColor(R.id.trackname,\r
295                                                 themeResources.getColor(trackName));\r
296                         }\r
297                         int artistName = themeResources.getIdentifier(\r
298                                         "four_by_two_artist_name", "color", themePackage);\r
299                         if (artistName != 0) {\r
300                                 views.setTextColor(R.id.artistname,\r
301                                                 themeResources.getColor(artistName));\r
302                         }\r
303                 }\r
304 \r
305                 // Connect up various buttons and touch events\r
306                 Intent intent;\r
307                 PendingIntent pendingIntent;\r
308 \r
309                 final ComponentName serviceName = new ComponentName(context,\r
310                                 MediaPlaybackService.class);\r
311 \r
312                 if (playerActive) {\r
313                         intent = new Intent(context, MediaPlaybackActivity.class);\r
314                         pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);\r
315                         views.setOnClickPendingIntent(R.id.albumart, pendingIntent);\r
316                         views.setOnClickPendingIntent(R.id.info, pendingIntent);\r
317                 } else {\r
318                         intent = new Intent(context, MusicBrowserActivity.class);\r
319                         pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);\r
320                         views.setOnClickPendingIntent(R.id.albumart, pendingIntent);\r
321                         views.setOnClickPendingIntent(R.id.info, pendingIntent);\r
322                 }\r
323 \r
324                 intent = new Intent(MediaPlaybackService.TOGGLEPAUSE_ACTION);\r
325                 intent.setComponent(serviceName);\r
326                 pendingIntent = PendingIntent.getService(context, 0, intent, 0);\r
327                 views.setOnClickPendingIntent(R.id.control_play, pendingIntent);\r
328 \r
329                 intent = new Intent(MediaPlaybackService.NEXT_ACTION);\r
330                 intent.setComponent(serviceName);\r
331                 pendingIntent = PendingIntent.getService(context, 0, intent, 0);\r
332                 views.setOnClickPendingIntent(R.id.control_next, pendingIntent);\r
333 \r
334                 intent = new Intent(MediaPlaybackService.PREVIOUS_ACTION);\r
335                 intent.setComponent(serviceName);\r
336                 pendingIntent = PendingIntent.getService(context, 0, intent, 0);\r
337                 views.setOnClickPendingIntent(R.id.control_prev, pendingIntent);\r
338 \r
339                 intent = new Intent(MediaPlaybackService.CYCLEREPEAT_ACTION);\r
340                 intent.setComponent(serviceName);\r
341                 pendingIntent = PendingIntent.getService(context, 0, intent, 0);\r
342                 views.setOnClickPendingIntent(R.id.control_repeat, pendingIntent);\r
343 \r
344                 intent = new Intent(MediaPlaybackService.TOGGLESHUFFLE_ACTION);\r
345                 intent.setComponent(serviceName);\r
346                 pendingIntent = PendingIntent.getService(context, 0, intent, 0);\r
347                 views.setOnClickPendingIntent(R.id.control_shuffle, pendingIntent);\r
348         }\r
349 }\r