blob: 28c79aadf84e5140bde61e581f19faf1fd4ee17c [file] [log] [blame]
Dianne Hackbornd6847842010-01-12 18:14:19 -08001/*
2 * Copyright (C) 2009 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
Dianne Hackborneb034652009-09-07 00:49:58 -070017package android.app;
18
Lucas Dupin4c8c3272018-11-06 17:47:48 -080019import android.annotation.SystemApi;
Weien Wang4710c042018-10-05 19:46:41 +080020import android.app.slice.Slice;
Dianne Hackborneb034652009-09-07 00:49:58 -070021import android.content.ComponentName;
22import android.content.Context;
Dianne Hackborn8aa2e892010-01-22 11:31:30 -080023import android.content.pm.ApplicationInfo;
Dianne Hackborneb034652009-09-07 00:49:58 -070024import android.content.pm.PackageManager;
Lucas Dupin7517b5d2017-08-22 12:51:25 -070025import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborneb034652009-09-07 00:49:58 -070026import android.content.pm.ResolveInfo;
27import android.content.pm.ServiceInfo;
Dianne Hackborn20cb56e2010-03-04 00:58:29 -080028import android.content.res.Resources;
Lucas Dupin7517b5d2017-08-22 12:51:25 -070029import android.content.res.Resources.NotFoundException;
Dianne Hackborneb034652009-09-07 00:49:58 -070030import android.content.res.TypedArray;
31import android.content.res.XmlResourceParser;
32import android.graphics.drawable.Drawable;
Jorim Jaggi526505d2016-05-24 00:29:19 -070033import android.net.Uri;
Dianne Hackborneb034652009-09-07 00:49:58 -070034import android.os.Parcel;
35import android.os.Parcelable;
36import android.service.wallpaper.WallpaperService;
37import android.util.AttributeSet;
38import android.util.Printer;
39import android.util.Xml;
wilsonshih968b30e2018-11-20 20:16:58 +080040import android.view.SurfaceHolder;
Dianne Hackborneb034652009-09-07 00:49:58 -070041
Lucas Dupin7517b5d2017-08-22 12:51:25 -070042import org.xmlpull.v1.XmlPullParser;
43import org.xmlpull.v1.XmlPullParserException;
44
Dianne Hackborneb034652009-09-07 00:49:58 -070045import java.io.IOException;
46
47/**
48 * This class is used to specify meta information of a wallpaper service.
Dianne Hackborneb034652009-09-07 00:49:58 -070049 */
50public final class WallpaperInfo implements Parcelable {
51 static final String TAG = "WallpaperInfo";
52
53 /**
54 * The Service that implements this wallpaper component.
55 */
56 final ResolveInfo mService;
57
58 /**
59 * The wallpaper setting activity's name, to
60 * launch the setting activity of this wallpaper.
61 */
62 final String mSettingsActivityName;
63
64 /**
Daniel Sandler465ccb82009-09-16 15:54:39 -040065 * Resource identifier for this wallpaper's thumbnail image.
66 */
67 final int mThumbnailResource;
68
69 /**
Daniel Sandler18a509d2009-11-05 15:05:27 -050070 * Resource identifier for a string indicating the author of the wallpaper.
71 */
72 final int mAuthorResource;
73
74 /**
75 * Resource identifier for a string containing a short description of the wallpaper.
76 */
77 final int mDescriptionResource;
78
Jorim Jaggi526505d2016-05-24 00:29:19 -070079 final int mContextUriResource;
80 final int mContextDescriptionResource;
81 final boolean mShowMetadataInPreview;
Lucas Dupin7517b5d2017-08-22 12:51:25 -070082 final boolean mSupportsAmbientMode;
Weien Wang4710c042018-10-05 19:46:41 +080083 final String mSettingsSliceUri;
wilsonshih968b30e2018-11-20 20:16:58 +080084 final boolean mSupportMultipleDisplays;
Jorim Jaggi526505d2016-05-24 00:29:19 -070085
Daniel Sandler18a509d2009-11-05 15:05:27 -050086 /**
Dianne Hackborneb034652009-09-07 00:49:58 -070087 * Constructor.
88 *
89 * @param context The Context in which we are parsing the wallpaper.
90 * @param service The ResolveInfo returned from the package manager about
91 * this wallpaper's component.
92 */
93 public WallpaperInfo(Context context, ResolveInfo service)
94 throws XmlPullParserException, IOException {
95 mService = service;
96 ServiceInfo si = service.serviceInfo;
97
Lucas Dupin7517b5d2017-08-22 12:51:25 -070098 final PackageManager pm = context.getPackageManager();
Dianne Hackborneb034652009-09-07 00:49:58 -070099 XmlResourceParser parser = null;
100 try {
101 parser = si.loadXmlMetaData(pm, WallpaperService.SERVICE_META_DATA);
102 if (parser == null) {
103 throw new XmlPullParserException("No "
104 + WallpaperService.SERVICE_META_DATA + " meta-data");
105 }
106
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800107 Resources res = pm.getResourcesForApplication(si.applicationInfo);
108
Dianne Hackborneb034652009-09-07 00:49:58 -0700109 AttributeSet attrs = Xml.asAttributeSet(parser);
110
111 int type;
112 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
113 && type != XmlPullParser.START_TAG) {
114 }
115
116 String nodeName = parser.getName();
117 if (!"wallpaper".equals(nodeName)) {
118 throw new XmlPullParserException(
119 "Meta-data does not start with wallpaper tag");
120 }
121
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800122 TypedArray sa = res.obtainAttributes(attrs,
Dianne Hackborneb034652009-09-07 00:49:58 -0700123 com.android.internal.R.styleable.Wallpaper);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700124 mSettingsActivityName = sa.getString(
Dianne Hackborneb034652009-09-07 00:49:58 -0700125 com.android.internal.R.styleable.Wallpaper_settingsActivity);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700126 mThumbnailResource = sa.getResourceId(
Daniel Sandler465ccb82009-09-16 15:54:39 -0400127 com.android.internal.R.styleable.Wallpaper_thumbnail,
128 -1);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700129 mAuthorResource = sa.getResourceId(
Dianne Hackborn23ef7b42009-11-18 18:20:39 -0800130 com.android.internal.R.styleable.Wallpaper_author,
Daniel Sandler18a509d2009-11-05 15:05:27 -0500131 -1);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700132 mDescriptionResource = sa.getResourceId(
Dianne Hackborn23ef7b42009-11-18 18:20:39 -0800133 com.android.internal.R.styleable.Wallpaper_description,
Daniel Sandler18a509d2009-11-05 15:05:27 -0500134 -1);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700135 mContextUriResource = sa.getResourceId(
Jorim Jaggi526505d2016-05-24 00:29:19 -0700136 com.android.internal.R.styleable.Wallpaper_contextUri,
137 -1);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700138 mContextDescriptionResource = sa.getResourceId(
Jorim Jaggi526505d2016-05-24 00:29:19 -0700139 com.android.internal.R.styleable.Wallpaper_contextDescription,
140 -1);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700141 mShowMetadataInPreview = sa.getBoolean(
Jorim Jaggi526505d2016-05-24 00:29:19 -0700142 com.android.internal.R.styleable.Wallpaper_showMetadataInPreview,
143 false);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700144 mSupportsAmbientMode = sa.getBoolean(
145 com.android.internal.R.styleable.Wallpaper_supportsAmbientMode,
146 false);
Weien Wang4710c042018-10-05 19:46:41 +0800147 mSettingsSliceUri = sa.getString(
148 com.android.internal.R.styleable.Wallpaper_settingsSliceUri);
wilsonshih968b30e2018-11-20 20:16:58 +0800149 mSupportMultipleDisplays = sa.getBoolean(
150 com.android.internal.R.styleable.Wallpaper_supportsMultipleDisplays,
151 false);
Daniel Sandler465ccb82009-09-16 15:54:39 -0400152
Dianne Hackborneb034652009-09-07 00:49:58 -0700153 sa.recycle();
Dianne Hackborn20cb56e2010-03-04 00:58:29 -0800154 } catch (NameNotFoundException e) {
155 throw new XmlPullParserException(
156 "Unable to create context for: " + si.packageName);
Dianne Hackborneb034652009-09-07 00:49:58 -0700157 } finally {
158 if (parser != null) parser.close();
159 }
Dianne Hackborneb034652009-09-07 00:49:58 -0700160 }
161
162 WallpaperInfo(Parcel source) {
163 mSettingsActivityName = source.readString();
Daniel Sandler465ccb82009-09-16 15:54:39 -0400164 mThumbnailResource = source.readInt();
Daniel Sandler18a509d2009-11-05 15:05:27 -0500165 mAuthorResource = source.readInt();
166 mDescriptionResource = source.readInt();
Jorim Jaggi526505d2016-05-24 00:29:19 -0700167 mContextUriResource = source.readInt();
168 mContextDescriptionResource = source.readInt();
169 mShowMetadataInPreview = source.readInt() != 0;
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700170 mSupportsAmbientMode = source.readInt() != 0;
Weien Wang4710c042018-10-05 19:46:41 +0800171 mSettingsSliceUri = source.readString();
wilsonshih968b30e2018-11-20 20:16:58 +0800172 mSupportMultipleDisplays = source.readInt() != 0;
Dianne Hackborneb034652009-09-07 00:49:58 -0700173 mService = ResolveInfo.CREATOR.createFromParcel(source);
174 }
175
176 /**
177 * Return the .apk package that implements this wallpaper.
178 */
179 public String getPackageName() {
180 return mService.serviceInfo.packageName;
181 }
182
183 /**
184 * Return the class name of the service component that implements
185 * this wallpaper.
186 */
187 public String getServiceName() {
188 return mService.serviceInfo.name;
189 }
190
191 /**
192 * Return the raw information about the Service implementing this
193 * wallpaper. Do not modify the returned object.
194 */
195 public ServiceInfo getServiceInfo() {
196 return mService.serviceInfo;
197 }
198
199 /**
200 * Return the component of the service that implements this wallpaper.
201 */
202 public ComponentName getComponent() {
203 return new ComponentName(mService.serviceInfo.packageName,
204 mService.serviceInfo.name);
205 }
206
207 /**
208 * Load the user-displayed label for this wallpaper.
209 *
210 * @param pm Supply a PackageManager used to load the wallpaper's
211 * resources.
212 */
213 public CharSequence loadLabel(PackageManager pm) {
214 return mService.loadLabel(pm);
215 }
216
217 /**
218 * Load the user-displayed icon for this wallpaper.
219 *
220 * @param pm Supply a PackageManager used to load the wallpaper's
221 * resources.
222 */
223 public Drawable loadIcon(PackageManager pm) {
224 return mService.loadIcon(pm);
225 }
226
227 /**
Daniel Sandler465ccb82009-09-16 15:54:39 -0400228 * Load the thumbnail image for this wallpaper.
229 *
230 * @param pm Supply a PackageManager used to load the wallpaper's
231 * resources.
232 */
233 public Drawable loadThumbnail(PackageManager pm) {
234 if (mThumbnailResource < 0) return null;
235
236 return pm.getDrawable(mService.serviceInfo.packageName,
237 mThumbnailResource,
Dianne Hackborn8aa2e892010-01-22 11:31:30 -0800238 mService.serviceInfo.applicationInfo);
Daniel Sandler465ccb82009-09-16 15:54:39 -0400239 }
Daniel Sandler18a509d2009-11-05 15:05:27 -0500240
241 /**
242 * Return a string indicating the author(s) of this wallpaper.
243 */
244 public CharSequence loadAuthor(PackageManager pm) throws NotFoundException {
245 if (mAuthorResource <= 0) throw new NotFoundException();
Dianne Hackborn8aa2e892010-01-22 11:31:30 -0800246 String packageName = mService.resolvePackageName;
247 ApplicationInfo applicationInfo = null;
248 if (packageName == null) {
249 packageName = mService.serviceInfo.packageName;
250 applicationInfo = mService.serviceInfo.applicationInfo;
251 }
252 return pm.getText(packageName, mAuthorResource, applicationInfo);
Daniel Sandler18a509d2009-11-05 15:05:27 -0500253 }
254
255 /**
256 * Return a brief summary of this wallpaper's behavior.
257 */
258 public CharSequence loadDescription(PackageManager pm) throws NotFoundException {
Dianne Hackborn8aa2e892010-01-22 11:31:30 -0800259 String packageName = mService.resolvePackageName;
260 ApplicationInfo applicationInfo = null;
261 if (packageName == null) {
262 packageName = mService.serviceInfo.packageName;
263 applicationInfo = mService.serviceInfo.applicationInfo;
264 }
265 if (mService.serviceInfo.descriptionRes != 0) {
266 return pm.getText(packageName, mService.serviceInfo.descriptionRes,
267 applicationInfo);
268
269 }
Daniel Sandler18a509d2009-11-05 15:05:27 -0500270 if (mDescriptionResource <= 0) throw new NotFoundException();
Dianne Hackborn8aa2e892010-01-22 11:31:30 -0800271 return pm.getText(packageName, mDescriptionResource,
272 mService.serviceInfo.applicationInfo);
Daniel Sandler18a509d2009-11-05 15:05:27 -0500273 }
Jorim Jaggi526505d2016-05-24 00:29:19 -0700274
275 /**
276 * Returns an URI that specifies a link for further context about this wallpaper.
277 *
278 * @param pm An instance of {@link PackageManager} to retrieve the URI.
279 * @return The URI.
280 */
281 public Uri loadContextUri(PackageManager pm) throws NotFoundException {
282 if (mContextUriResource <= 0) throw new NotFoundException();
283 String packageName = mService.resolvePackageName;
284 ApplicationInfo applicationInfo = null;
285 if (packageName == null) {
286 packageName = mService.serviceInfo.packageName;
287 applicationInfo = mService.serviceInfo.applicationInfo;
288 }
289 String contextUriString = pm.getText(
290 packageName, mContextUriResource, applicationInfo).toString();
291 if (contextUriString == null) {
292 return null;
293 }
294 return Uri.parse(contextUriString);
295 }
296
297 /**
298 * Retrieves a title of the URI that specifies a link for further context about this wallpaper.
299 *
300 * @param pm An instance of {@link PackageManager} to retrieve the title.
301 * @return The title.
302 */
303 public CharSequence loadContextDescription(PackageManager pm) throws NotFoundException {
304 if (mContextDescriptionResource <= 0) throw new NotFoundException();
305 String packageName = mService.resolvePackageName;
306 ApplicationInfo applicationInfo = null;
307 if (packageName == null) {
308 packageName = mService.serviceInfo.packageName;
309 applicationInfo = mService.serviceInfo.applicationInfo;
310 }
311 return pm.getText(packageName, mContextDescriptionResource, applicationInfo).toString();
312 }
313
314 /**
Jorim Jaggid136ba12016-06-23 16:25:52 -0700315 * Queries whether any metadata should be shown when previewing the wallpaper. If this value is
316 * set to true, any component that shows a preview of this live wallpaper should also show
317 * accompanying information like {@link #loadLabel},
318 * {@link #loadDescription}, {@link #loadAuthor} and
319 * {@link #loadContextDescription(PackageManager)}, so the user gets to know further information
320 * about this wallpaper.
Jorim Jaggi526505d2016-05-24 00:29:19 -0700321 *
322 * @return Whether any metadata should be shown when previewing the wallpaper.
323 */
324 public boolean getShowMetadataInPreview() {
325 return mShowMetadataInPreview;
326 }
327
Daniel Sandler465ccb82009-09-16 15:54:39 -0400328 /**
Lucas Dupin8f09a502018-07-27 16:47:45 +0800329 * Returns whether a wallpaper was optimized or not for ambient mode and can be drawn in there.
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700330 *
Lucas Dupin8f09a502018-07-27 16:47:45 +0800331 * @see WallpaperService.Engine#onAmbientModeChanged(boolean, boolean)
332 * @see WallpaperService.Engine#isInAmbientMode()
333 * @return {@code true} if wallpaper can draw when in ambient mode.
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800334 * @hide
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700335 */
Lucas Dupin4c8c3272018-11-06 17:47:48 -0800336 @SystemApi
Lucas Dupin8f09a502018-07-27 16:47:45 +0800337 public boolean supportsAmbientMode() {
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700338 return mSupportsAmbientMode;
339 }
340
341 /**
Dianne Hackborneb034652009-09-07 00:49:58 -0700342 * Return the class name of an activity that provides a settings UI for
343 * the wallpaper. You can launch this activity be starting it with
344 * an {@link android.content.Intent} whose action is MAIN and with an
345 * explicit {@link android.content.ComponentName}
346 * composed of {@link #getPackageName} and the class name returned here.
347 *
Weien Wang4710c042018-10-05 19:46:41 +0800348 * <p>{@code null} will be returned if there is no settings activity associated
Dianne Hackborneb034652009-09-07 00:49:58 -0700349 * with the wallpaper.
350 */
351 public String getSettingsActivity() {
352 return mSettingsActivityName;
353 }
354
Weien Wang4710c042018-10-05 19:46:41 +0800355 /**
356 * Returns an URI that provides a settings {@link Slice} for this wallpaper.
357 *
358 * <p>{@code null} will be returned if there is no settings Slice URI associated
359 * with the wallpaper.
360 *
361 * @return The URI.
362 */
363 public Uri getSettingsSliceUri() {
364 if (mSettingsSliceUri == null) {
365 return null;
366 }
367 return Uri.parse(mSettingsSliceUri);
368 }
369
wilsonshih968b30e2018-11-20 20:16:58 +0800370 /**
371 * Returns whether this wallpaper service can support multiple engines to render on each surface
372 * independently. An example use case is a multi-display set-up where the wallpaper service can
373 * render surfaces to each of the connected displays.
wilsonshihfd058f62019-02-13 15:57:06 +0800374 * <p>
375 * This corresponds to the value {@link android.R.styleable#Wallpaper_supportsMultipleDisplays}
376 * in the XML description of the wallpaper.
377 * <p>
378 * The default value is {@code false}.
wilsonshih968b30e2018-11-20 20:16:58 +0800379 *
380 * @see WallpaperService#onCreateEngine()
381 * @see WallpaperService.Engine#onCreate(SurfaceHolder)
382 * @return {@code true} if multiple engines can render independently on each surface.
wilsonshihfd058f62019-02-13 15:57:06 +0800383 *
384 * @attr ref android.R.styleable#Wallpaper_supportsMultipleDisplays
wilsonshih968b30e2018-11-20 20:16:58 +0800385 */
386 public boolean supportsMultipleDisplays() {
387 return mSupportMultipleDisplays;
388 }
389
Dianne Hackborneb034652009-09-07 00:49:58 -0700390 public void dump(Printer pw, String prefix) {
391 pw.println(prefix + "Service:");
392 mService.dump(pw, prefix + " ");
393 pw.println(prefix + "mSettingsActivityName=" + mSettingsActivityName);
394 }
395
396 @Override
397 public String toString() {
398 return "WallpaperInfo{" + mService.serviceInfo.name
399 + ", settings: "
400 + mSettingsActivityName + "}";
401 }
402
403 /**
404 * Used to package this object into a {@link Parcel}.
405 *
406 * @param dest The {@link Parcel} to be written.
407 * @param flags The flags used for parceling.
408 */
409 public void writeToParcel(Parcel dest, int flags) {
410 dest.writeString(mSettingsActivityName);
Daniel Sandler465ccb82009-09-16 15:54:39 -0400411 dest.writeInt(mThumbnailResource);
Daniel Sandler18a509d2009-11-05 15:05:27 -0500412 dest.writeInt(mAuthorResource);
413 dest.writeInt(mDescriptionResource);
Jorim Jaggi526505d2016-05-24 00:29:19 -0700414 dest.writeInt(mContextUriResource);
415 dest.writeInt(mContextDescriptionResource);
416 dest.writeInt(mShowMetadataInPreview ? 1 : 0);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700417 dest.writeInt(mSupportsAmbientMode ? 1 : 0);
Weien Wang4710c042018-10-05 19:46:41 +0800418 dest.writeString(mSettingsSliceUri);
wilsonshih968b30e2018-11-20 20:16:58 +0800419 dest.writeInt(mSupportMultipleDisplays ? 1 : 0);
Dianne Hackborneb034652009-09-07 00:49:58 -0700420 mService.writeToParcel(dest, flags);
421 }
422
423 /**
424 * Used to make this class parcelable.
425 */
426 public static final Parcelable.Creator<WallpaperInfo> CREATOR = new Parcelable.Creator<WallpaperInfo>() {
427 public WallpaperInfo createFromParcel(Parcel source) {
428 return new WallpaperInfo(source);
429 }
430
431 public WallpaperInfo[] newArray(int size) {
432 return new WallpaperInfo[size];
433 }
434 };
435
436 public int describeContents() {
437 return 0;
438 }
439}