1 /* 2 * Copyright (C) 2008 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 17 package com.android.server; 18 19 import static android.os.FileObserver.*; 20 import static android.os.ParcelFileDescriptor.*; 21 22 import android.app.IWallpaperManager; 23 import android.app.IWallpaperManagerCallback; 24 import android.app.PendingIntent; 25 import android.app.WallpaperInfo; 26 import android.backup.BackupManager; 27 import android.content.ComponentName; 28 import android.content.Context; 29 import android.content.Intent; 30 import android.content.ServiceConnection; 31 import android.content.pm.PackageManager; 32 import android.content.pm.ResolveInfo; 33 import android.content.pm.ServiceInfo; 34 import android.content.pm.PackageManager.NameNotFoundException; 35 import android.content.res.Resources; 36 import android.os.Binder; 37 import android.os.Bundle; 38 import android.os.IBinder; 39 import android.os.RemoteException; 40 import android.os.FileObserver; 41 import android.os.ParcelFileDescriptor; 42 import android.os.RemoteCallbackList; 43 import android.os.ServiceManager; 44 import android.os.SystemClock; 45 import android.service.wallpaper.IWallpaperConnection; 46 import android.service.wallpaper.IWallpaperEngine; 47 import android.service.wallpaper.IWallpaperService; 48 import android.service.wallpaper.WallpaperService; 49 import android.util.Log; 50 import android.util.Xml; 51 import android.view.IWindowManager; 52 import android.view.WindowManager; 53 54 import java.io.FileDescriptor; 55 import java.io.IOException; 56 import java.io.InputStream; 57 import java.io.File; 58 import java.io.FileNotFoundException; 59 import java.io.FileInputStream; 60 import java.io.FileOutputStream; 61 import java.io.PrintWriter; 62 import java.util.List; 63 64 import org.xmlpull.v1.XmlPullParser; 65 import org.xmlpull.v1.XmlPullParserException; 66 import org.xmlpull.v1.XmlSerializer; 67 68 import com.android.internal.service.wallpaper.ImageWallpaper; 69 import com.android.internal.util.FastXmlSerializer; 70 71 class WallpaperManagerService extends IWallpaperManager.Stub { 72 static final String TAG = "WallpaperService"; 73 static final boolean DEBUG = false; 74 75 Object mLock = new Object(); 76 77 /** 78 * Minimum time between crashes of a wallpaper service for us to consider 79 * restarting it vs. just reverting to the static wallpaper. 80 */ 81 static final long MIN_WALLPAPER_CRASH_TIME = 10000; 82 83 static final File WALLPAPER_DIR = new File( 84 "/data/data/com.android.settings/files"); 85 static final String WALLPAPER = "wallpaper"; 86 static final File WALLPAPER_FILE = new File(WALLPAPER_DIR, WALLPAPER); 87 88 /** 89 * List of callbacks registered they should each be notified 90 * when the wallpaper is changed. 91 */ 92 private final RemoteCallbackList<IWallpaperManagerCallback> mCallbacks 93 = new RemoteCallbackList<IWallpaperManagerCallback>(); 94 95 /** 96 * Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks 97 * that the wallpaper has changed. The CREATE is triggered when there is no 98 * wallpaper set and is created for the first time. The CLOSE_WRITE is triggered 99 * everytime the wallpaper is changed. 100 */ 101 private final FileObserver mWallpaperObserver = new FileObserver( 102 WALLPAPER_DIR.getAbsolutePath(), CREATE | CLOSE_WRITE | DELETE | DELETE_SELF) { 103 @Override 104 public void onEvent(int event, String path) { 105 if (path == null) { 106 return; 107 } 108 synchronized (mLock) { 109 // changing the wallpaper means we'll need to back up the new one 110 long origId = Binder.clearCallingIdentity(); 111 BackupManager bm = new BackupManager(mContext); 112 bm.dataChanged(); 113 Binder.restoreCallingIdentity(origId); 114 115 File changedFile = new File(WALLPAPER_DIR, path); 116 if (WALLPAPER_FILE.equals(changedFile)) { 117 notifyCallbacksLocked(); 118 } 119 } 120 } 121 }; 122 123 final Context mContext; 124 final IWindowManager mIWindowManager; 125 126 int mWidth = -1; 127 int mHeight = -1; 128 String mName = ""; 129 130 /** 131 * The component name of the currently set live wallpaper. This will be null if the 132 * wallpaper uses the built in ImageWallpaper component to display a bitmap. 133 */ 134 ComponentName mWallpaperComponent; 135 WallpaperConnection mWallpaperConnection; 136 long mLastDiedTime; 137 138 class WallpaperConnection extends IWallpaperConnection.Stub 139 implements ServiceConnection { 140 final WallpaperInfo mInfo; 141 final Binder mToken = new Binder(); 142 IWallpaperService mService; 143 IWallpaperEngine mEngine; 144 WallpaperConnection(WallpaperInfo info)145 public WallpaperConnection(WallpaperInfo info) { 146 mInfo = info; 147 } 148 onServiceConnected(ComponentName name, IBinder service)149 public void onServiceConnected(ComponentName name, IBinder service) { 150 synchronized (mLock) { 151 if (mWallpaperConnection == this) { 152 mService = IWallpaperService.Stub.asInterface(service); 153 attachServiceLocked(this); 154 // XXX should probably do saveSettingsLocked() later 155 // when we have an engine, but I'm not sure about 156 // locking there and anyway we always need to be able to 157 // recover if there is something wrong. 158 saveSettingsLocked(); 159 } 160 } 161 } 162 onServiceDisconnected(ComponentName name)163 public void onServiceDisconnected(ComponentName name) { 164 synchronized (mLock) { 165 mService = null; 166 mEngine = null; 167 if (mWallpaperConnection == this) { 168 Log.w(TAG, "Wallpaper service gone: " + mWallpaperComponent); 169 if ((mLastDiedTime+MIN_WALLPAPER_CRASH_TIME) 170 < SystemClock.uptimeMillis()) { 171 Log.w(TAG, "Reverting to built-in wallpaper!"); 172 bindWallpaperComponentLocked(null, false); 173 } 174 } 175 } 176 } 177 attachEngine(IWallpaperEngine engine)178 public void attachEngine(IWallpaperEngine engine) { 179 mEngine = engine; 180 } 181 setWallpaper(String name)182 public ParcelFileDescriptor setWallpaper(String name) { 183 synchronized (mLock) { 184 if (mWallpaperConnection == this) { 185 return updateWallpaperBitmapLocked(name); 186 } 187 return null; 188 } 189 } 190 } 191 WallpaperManagerService(Context context)192 public WallpaperManagerService(Context context) { 193 if (DEBUG) Log.d(TAG, "WallpaperService startup"); 194 mContext = context; 195 mIWindowManager = IWindowManager.Stub.asInterface( 196 ServiceManager.getService(Context.WINDOW_SERVICE)); 197 WALLPAPER_DIR.mkdirs(); 198 loadSettingsLocked(); 199 mWallpaperObserver.startWatching(); 200 } 201 202 @Override finalize()203 protected void finalize() throws Throwable { 204 super.finalize(); 205 mWallpaperObserver.stopWatching(); 206 } 207 systemReady()208 public void systemReady() { 209 synchronized (mLock) { 210 try { 211 bindWallpaperComponentLocked(mWallpaperComponent, false); 212 } catch (RuntimeException e) { 213 Log.w(TAG, "Failure starting previous wallpaper", e); 214 try { 215 bindWallpaperComponentLocked(null, false); 216 } catch (RuntimeException e2) { 217 Log.w(TAG, "Failure starting default wallpaper", e2); 218 clearWallpaperComponentLocked(); 219 } 220 } 221 } 222 } 223 clearWallpaper()224 public void clearWallpaper() { 225 synchronized (mLock) { 226 File f = WALLPAPER_FILE; 227 if (f.exists()) { 228 f.delete(); 229 } 230 final long ident = Binder.clearCallingIdentity(); 231 try { 232 bindWallpaperComponentLocked(null, false); 233 } finally { 234 Binder.restoreCallingIdentity(ident); 235 } 236 } 237 } 238 setDimensionHints(int width, int height)239 public void setDimensionHints(int width, int height) throws RemoteException { 240 checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS); 241 242 if (width <= 0 || height <= 0) { 243 throw new IllegalArgumentException("width and height must be > 0"); 244 } 245 246 synchronized (mLock) { 247 if (width != mWidth || height != mHeight) { 248 mWidth = width; 249 mHeight = height; 250 saveSettingsLocked(); 251 if (mWallpaperConnection != null) { 252 if (mWallpaperConnection.mEngine != null) { 253 try { 254 mWallpaperConnection.mEngine.setDesiredSize( 255 width, height); 256 } catch (RemoteException e) { 257 } 258 notifyCallbacksLocked(); 259 } 260 } 261 } 262 } 263 } 264 getWidthHint()265 public int getWidthHint() throws RemoteException { 266 synchronized (mLock) { 267 return mWidth; 268 } 269 } 270 getHeightHint()271 public int getHeightHint() throws RemoteException { 272 synchronized (mLock) { 273 return mHeight; 274 } 275 } 276 getWallpaper(IWallpaperManagerCallback cb, Bundle outParams)277 public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb, 278 Bundle outParams) { 279 synchronized (mLock) { 280 try { 281 if (outParams != null) { 282 outParams.putInt("width", mWidth); 283 outParams.putInt("height", mHeight); 284 } 285 mCallbacks.register(cb); 286 File f = WALLPAPER_FILE; 287 if (!f.exists()) { 288 return null; 289 } 290 return ParcelFileDescriptor.open(f, MODE_READ_ONLY); 291 } catch (FileNotFoundException e) { 292 /* Shouldn't happen as we check to see if the file exists */ 293 Log.w(TAG, "Error getting wallpaper", e); 294 } 295 return null; 296 } 297 } 298 getWallpaperInfo()299 public WallpaperInfo getWallpaperInfo() { 300 synchronized (mLock) { 301 if (mWallpaperConnection != null) { 302 return mWallpaperConnection.mInfo; 303 } 304 return null; 305 } 306 } 307 setWallpaper(String name)308 public ParcelFileDescriptor setWallpaper(String name) { 309 checkPermission(android.Manifest.permission.SET_WALLPAPER); 310 synchronized (mLock) { 311 final long ident = Binder.clearCallingIdentity(); 312 try { 313 ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name); 314 if (pfd != null) { 315 // Bind the wallpaper to an ImageWallpaper 316 bindWallpaperComponentLocked(null, true); 317 saveSettingsLocked(); 318 } 319 return pfd; 320 } finally { 321 Binder.restoreCallingIdentity(ident); 322 } 323 } 324 } 325 updateWallpaperBitmapLocked(String name)326 ParcelFileDescriptor updateWallpaperBitmapLocked(String name) { 327 if (name == null) name = ""; 328 try { 329 ParcelFileDescriptor fd = ParcelFileDescriptor.open(WALLPAPER_FILE, 330 MODE_CREATE|MODE_READ_WRITE); 331 mName = name; 332 return fd; 333 } catch (FileNotFoundException e) { 334 Log.w(TAG, "Error setting wallpaper", e); 335 } 336 return null; 337 } 338 setWallpaperComponent(ComponentName name)339 public void setWallpaperComponent(ComponentName name) { 340 checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT); 341 synchronized (mLock) { 342 final long ident = Binder.clearCallingIdentity(); 343 try { 344 bindWallpaperComponentLocked(name, false); 345 } finally { 346 Binder.restoreCallingIdentity(ident); 347 } 348 } 349 } 350 bindWallpaperComponentLocked(ComponentName componentName, boolean isBitmap)351 void bindWallpaperComponentLocked(ComponentName componentName, boolean isBitmap) { 352 // Has the component changed? 353 if (mWallpaperConnection != null) { 354 if (mWallpaperComponent == null) { 355 if (componentName == null) { 356 // Still using default wallpaper. 357 return; 358 } 359 } else if (mWallpaperComponent.equals(componentName)) { 360 // Changing to same wallpaper. 361 return; 362 } 363 } 364 365 try { 366 ComponentName realComponentName = componentName; 367 if (realComponentName == null) { 368 String defaultComponent = 369 mContext.getString(com.android.internal.R.string.default_wallpaper_component); 370 if (defaultComponent != null && !isBitmap) { 371 // See if there is a default wallpaper component specified 372 // Only look for this if the wallpaper is not being set to a bitmap 373 realComponentName = ComponentName.unflattenFromString(defaultComponent); 374 componentName = realComponentName; 375 } 376 if (realComponentName == null) { 377 // Fall back to static image wallpaper 378 realComponentName = new ComponentName("android", 379 ImageWallpaper.class.getName()); 380 //clearWallpaperComponentLocked(); 381 //return; 382 } 383 } 384 ServiceInfo si = mContext.getPackageManager().getServiceInfo(realComponentName, 385 PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS); 386 if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) { 387 throw new SecurityException("Selected service does not require " 388 + android.Manifest.permission.BIND_WALLPAPER 389 + ": " + realComponentName); 390 } 391 392 WallpaperInfo wi = null; 393 394 Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE); 395 if (componentName != null) { 396 // Make sure the selected service is actually a wallpaper service. 397 List<ResolveInfo> ris = mContext.getPackageManager() 398 .queryIntentServices(intent, PackageManager.GET_META_DATA); 399 for (int i=0; i<ris.size(); i++) { 400 ServiceInfo rsi = ris.get(i).serviceInfo; 401 if (rsi.name.equals(si.name) && 402 rsi.packageName.equals(si.packageName)) { 403 try { 404 wi = new WallpaperInfo(mContext, ris.get(i)); 405 } catch (XmlPullParserException e) { 406 throw new IllegalArgumentException(e); 407 } catch (IOException e) { 408 throw new IllegalArgumentException(e); 409 } 410 break; 411 } 412 } 413 if (wi == null) { 414 throw new SecurityException("Selected service is not a wallpaper: " 415 + realComponentName); 416 } 417 } 418 419 // Bind the service! 420 WallpaperConnection newConn = new WallpaperConnection(wi); 421 intent.setComponent(realComponentName); 422 intent.putExtra(Intent.EXTRA_CLIENT_LABEL, 423 com.android.internal.R.string.wallpaper_binding_label); 424 intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivity( 425 mContext, 0, 426 Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER), 427 mContext.getText(com.android.internal.R.string.chooser_wallpaper)), 428 0)); 429 if (!mContext.bindService(intent, newConn, 430 Context.BIND_AUTO_CREATE)) { 431 throw new IllegalArgumentException("Unable to bind service: " 432 + componentName); 433 } 434 435 clearWallpaperComponentLocked(); 436 mWallpaperComponent = componentName; 437 mWallpaperConnection = newConn; 438 mLastDiedTime = SystemClock.uptimeMillis(); 439 try { 440 if (DEBUG) Log.v(TAG, "Adding window token: " + newConn.mToken); 441 mIWindowManager.addWindowToken(newConn.mToken, 442 WindowManager.LayoutParams.TYPE_WALLPAPER); 443 } catch (RemoteException e) { 444 } 445 446 } catch (PackageManager.NameNotFoundException e) { 447 throw new IllegalArgumentException("Unknown component " + componentName); 448 } 449 } 450 clearWallpaperComponentLocked()451 void clearWallpaperComponentLocked() { 452 mWallpaperComponent = null; 453 if (mWallpaperConnection != null) { 454 if (mWallpaperConnection.mEngine != null) { 455 try { 456 mWallpaperConnection.mEngine.destroy(); 457 } catch (RemoteException e) { 458 } 459 } 460 mContext.unbindService(mWallpaperConnection); 461 try { 462 if (DEBUG) Log.v(TAG, "Removing window token: " 463 + mWallpaperConnection.mToken); 464 mIWindowManager.removeWindowToken(mWallpaperConnection.mToken); 465 } catch (RemoteException e) { 466 } 467 mWallpaperConnection = null; 468 } 469 } 470 attachServiceLocked(WallpaperConnection conn)471 void attachServiceLocked(WallpaperConnection conn) { 472 try { 473 conn.mService.attach(conn, conn.mToken, 474 WindowManager.LayoutParams.TYPE_WALLPAPER, false, 475 mWidth, mHeight); 476 } catch (RemoteException e) { 477 Log.w(TAG, "Failed attaching wallpaper; clearing", e); 478 bindWallpaperComponentLocked(null, false); 479 } 480 } 481 notifyCallbacksLocked()482 private void notifyCallbacksLocked() { 483 final int n = mCallbacks.beginBroadcast(); 484 for (int i = 0; i < n; i++) { 485 try { 486 mCallbacks.getBroadcastItem(i).onWallpaperChanged(); 487 } catch (RemoteException e) { 488 489 // The RemoteCallbackList will take care of removing 490 // the dead object for us. 491 } 492 } 493 mCallbacks.finishBroadcast(); 494 final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED); 495 mContext.sendBroadcast(intent); 496 } 497 checkPermission(String permission)498 private void checkPermission(String permission) { 499 if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) { 500 throw new SecurityException("Access denied to process: " + Binder.getCallingPid() 501 + ", must have permission " + permission); 502 } 503 } 504 makeJournaledFile()505 private static JournaledFile makeJournaledFile() { 506 final String base = "/data/system/wallpaper_info.xml"; 507 return new JournaledFile(new File(base), new File(base + ".tmp")); 508 } 509 saveSettingsLocked()510 private void saveSettingsLocked() { 511 JournaledFile journal = makeJournaledFile(); 512 FileOutputStream stream = null; 513 try { 514 stream = new FileOutputStream(journal.chooseForWrite(), false); 515 XmlSerializer out = new FastXmlSerializer(); 516 out.setOutput(stream, "utf-8"); 517 out.startDocument(null, true); 518 519 out.startTag(null, "wp"); 520 out.attribute(null, "width", Integer.toString(mWidth)); 521 out.attribute(null, "height", Integer.toString(mHeight)); 522 out.attribute(null, "name", mName); 523 if (mWallpaperComponent != null) { 524 out.attribute(null, "component", 525 mWallpaperComponent.flattenToShortString()); 526 } 527 out.endTag(null, "wp"); 528 529 out.endDocument(); 530 stream.close(); 531 journal.commit(); 532 } catch (IOException e) { 533 try { 534 if (stream != null) { 535 stream.close(); 536 } 537 } catch (IOException ex) { 538 // Ignore 539 } 540 journal.rollback(); 541 } 542 } 543 loadSettingsLocked()544 private void loadSettingsLocked() { 545 JournaledFile journal = makeJournaledFile(); 546 FileInputStream stream = null; 547 File file = journal.chooseForRead(); 548 boolean success = false; 549 try { 550 stream = new FileInputStream(file); 551 XmlPullParser parser = Xml.newPullParser(); 552 parser.setInput(stream, null); 553 554 int type; 555 do { 556 type = parser.next(); 557 if (type == XmlPullParser.START_TAG) { 558 String tag = parser.getName(); 559 if ("wp".equals(tag)) { 560 mWidth = Integer.parseInt(parser.getAttributeValue(null, "width")); 561 mHeight = Integer.parseInt(parser.getAttributeValue(null, "height")); 562 mName = parser.getAttributeValue(null, "name"); 563 String comp = parser.getAttributeValue(null, "component"); 564 mWallpaperComponent = comp != null 565 ? ComponentName.unflattenFromString(comp) 566 : null; 567 } 568 } 569 } while (type != XmlPullParser.END_DOCUMENT); 570 success = true; 571 } catch (NullPointerException e) { 572 Log.w(TAG, "failed parsing " + file + " " + e); 573 } catch (NumberFormatException e) { 574 Log.w(TAG, "failed parsing " + file + " " + e); 575 } catch (XmlPullParserException e) { 576 Log.w(TAG, "failed parsing " + file + " " + e); 577 } catch (IOException e) { 578 Log.w(TAG, "failed parsing " + file + " " + e); 579 } catch (IndexOutOfBoundsException e) { 580 Log.w(TAG, "failed parsing " + file + " " + e); 581 } 582 try { 583 if (stream != null) { 584 stream.close(); 585 } 586 } catch (IOException e) { 587 // Ignore 588 } 589 590 if (!success) { 591 mWidth = -1; 592 mHeight = -1; 593 mName = ""; 594 } 595 } 596 settingsRestored()597 void settingsRestored() { 598 boolean success = false; 599 synchronized (mLock) { 600 loadSettingsLocked(); 601 // If there's a wallpaper name, we use that. If that can't be loaded, then we 602 // use the default. 603 if ("".equals(mName)) { 604 success = true; 605 } else { 606 success = restoreNamedResourceLocked(); 607 } 608 } 609 610 if (!success) { 611 Log.e(TAG, "Failed to restore wallpaper: '" + mName + "'"); 612 mName = ""; 613 WALLPAPER_FILE.delete(); 614 } 615 saveSettingsLocked(); 616 } 617 restoreNamedResourceLocked()618 boolean restoreNamedResourceLocked() { 619 if (mName.length() > 4 && "res:".equals(mName.substring(0, 4))) { 620 String resName = mName.substring(4); 621 622 String pkg = null; 623 int colon = resName.indexOf(':'); 624 if (colon > 0) { 625 pkg = resName.substring(0, colon); 626 } 627 628 String ident = null; 629 int slash = resName.lastIndexOf('/'); 630 if (slash > 0) { 631 ident = resName.substring(slash+1); 632 } 633 634 String type = null; 635 if (colon > 0 && slash > 0 && (slash-colon) > 1) { 636 type = resName.substring(colon+1, slash); 637 } 638 639 if (pkg != null && ident != null && type != null) { 640 int resId = -1; 641 InputStream res = null; 642 FileOutputStream fos = null; 643 try { 644 Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED); 645 Resources r = c.getResources(); 646 resId = r.getIdentifier(resName, null, null); 647 if (resId == 0) { 648 Log.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type 649 + " ident=" + ident); 650 return false; 651 } 652 653 res = r.openRawResource(resId); 654 fos = new FileOutputStream(WALLPAPER_FILE); 655 656 byte[] buffer = new byte[32768]; 657 int amt; 658 while ((amt=res.read(buffer)) > 0) { 659 fos.write(buffer, 0, amt); 660 } 661 // mWallpaperObserver will notice the close and send the change broadcast 662 663 Log.d(TAG, "Restored wallpaper: " + resName); 664 return true; 665 } catch (NameNotFoundException e) { 666 Log.e(TAG, "Package name " + pkg + " not found"); 667 } catch (Resources.NotFoundException e) { 668 Log.e(TAG, "Resource not found: " + resId); 669 } catch (IOException e) { 670 Log.e(TAG, "IOException while restoring wallpaper ", e); 671 } finally { 672 if (res != null) { 673 try { 674 res.close(); 675 } catch (IOException ex) {} 676 } 677 if (fos != null) { 678 try { 679 fos.close(); 680 } catch (IOException ex) {} 681 } 682 } 683 } 684 } 685 return false; 686 } 687 688 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)689 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 690 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 691 != PackageManager.PERMISSION_GRANTED) { 692 693 pw.println("Permission Denial: can't dump wallpaper service from from pid=" 694 + Binder.getCallingPid() 695 + ", uid=" + Binder.getCallingUid()); 696 return; 697 } 698 699 synchronized (mLock) { 700 pw.println("Current Wallpaper Service state:"); 701 pw.print(" mWidth="); pw.print(mWidth); 702 pw.print(" mHeight="); pw.println(mHeight); 703 pw.print(" mName="); pw.println(mName); 704 pw.print(" mWallpaperComponent="); pw.println(mWallpaperComponent); 705 if (mWallpaperConnection != null) { 706 WallpaperConnection conn = mWallpaperConnection; 707 pw.print(" Wallpaper connection "); 708 pw.print(conn); pw.println(":"); 709 pw.print(" mInfo.component="); pw.println(conn.mInfo.getComponent()); 710 pw.print(" mToken="); pw.println(conn.mToken); 711 pw.print(" mService="); pw.println(conn.mService); 712 pw.print(" mEngine="); pw.println(conn.mEngine); 713 pw.print(" mLastDiedTime="); 714 pw.println(mLastDiedTime - SystemClock.uptimeMillis()); 715 } 716 } 717 } 718 } 719