fork download
  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://w...content-available-to-author-only...e.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.ParcelFileDescriptor.*;
  20.  
  21. import android.app.ActivityManagerNative;
  22. import android.app.AppGlobals;
  23. import android.app.IUserSwitchObserver;
  24. import android.app.IWallpaperManager;
  25. import android.app.IWallpaperManagerCallback;
  26. import android.app.PendingIntent;
  27. import android.app.WallpaperInfo;
  28. import android.app.backup.BackupManager;
  29. import android.app.backup.WallpaperBackupHelper;
  30. import android.content.BroadcastReceiver;
  31. import android.content.ComponentName;
  32. import android.content.Context;
  33. import android.content.Intent;
  34. import android.content.IntentFilter;
  35. import android.content.ServiceConnection;
  36. import android.content.pm.IPackageManager;
  37. import android.content.pm.PackageManager;
  38. import android.content.pm.ResolveInfo;
  39. import android.content.pm.ServiceInfo;
  40. import android.content.pm.PackageManager.NameNotFoundException;
  41. import android.content.pm.UserInfo;
  42. import android.content.res.Resources;
  43. import android.os.Binder;
  44. import android.os.Bundle;
  45. import android.os.Environment;
  46. import android.os.FileUtils;
  47. import android.os.IBinder;
  48. import android.os.IRemoteCallback;
  49. import android.os.RemoteException;
  50. import android.os.FileObserver;
  51. import android.os.ParcelFileDescriptor;
  52. import android.os.RemoteCallbackList;
  53. import android.os.SELinux;
  54. import android.os.ServiceManager;
  55. import android.os.SystemClock;
  56. import android.os.UserHandle;
  57. import android.os.UserManager;
  58. import android.service.wallpaper.IWallpaperConnection;
  59. import android.service.wallpaper.IWallpaperEngine;
  60. import android.service.wallpaper.IWallpaperService;
  61. import android.service.wallpaper.WallpaperService;
  62. import android.util.Slog;
  63. import android.util.SparseArray;
  64. import android.util.Xml;
  65. import android.view.Display;
  66. import android.view.IWindowManager;
  67. import android.view.WindowManager;
  68.  
  69. import java.io.FileDescriptor;
  70. import java.io.IOException;
  71. import java.io.InputStream;
  72. import java.io.File;
  73. import java.io.FileNotFoundException;
  74. import java.io.FileInputStream;
  75. import java.io.FileOutputStream;
  76. import java.io.PrintWriter;
  77. import java.util.List;
  78.  
  79. import org.xmlpull.v1.XmlPullParser;
  80. import org.xmlpull.v1.XmlPullParserException;
  81. import org.xmlpull.v1.XmlSerializer;
  82.  
  83. import com.android.internal.content.PackageMonitor;
  84. import com.android.internal.util.FastXmlSerializer;
  85. import com.android.internal.util.JournaledFile;
  86.  
  87. class WallpaperManagerService extends IWallpaperManager.Stub {
  88. static final String TAG = "WallpaperService";
  89. static final boolean DEBUG = false;
  90.  
  91. final Object mLock = new Object[0];
  92.  
  93. /**
  94.   * Minimum time between crashes of a wallpaper service for us to consider
  95.   * restarting it vs. just reverting to the static wallpaper.
  96.   */
  97. static final long MIN_WALLPAPER_CRASH_TIME = 10000;
  98. static final String WALLPAPER = "wallpaper";
  99. static final String WALLPAPER_INFO = "wallpaper_info.xml";
  100.  
  101. /**
  102.   * Name of the component used to display bitmap wallpapers from either the gallery or
  103.   * built-in wallpapers.
  104.   */
  105. static final ComponentName IMAGE_WALLPAPER = new ComponentName("com.android.systemui",
  106. "com.android.systemui.ImageWallpaper");
  107.  
  108. /**
  109.   * Observes the wallpaper for changes and notifies all IWallpaperServiceCallbacks
  110.   * that the wallpaper has changed. The CREATE is triggered when there is no
  111.   * wallpaper set and is created for the first time. The CLOSE_WRITE is triggered
  112.   * everytime the wallpaper is changed.
  113.   */
  114. private class WallpaperObserver extends FileObserver {
  115.  
  116. final WallpaperData mWallpaper;
  117. final File mWallpaperDir;
  118. final File mWallpaperFile;
  119.  
  120. public WallpaperObserver(WallpaperData wallpaper) {
  121. super(getWallpaperDir(wallpaper.userId).getAbsolutePath(),
  122. CLOSE_WRITE | DELETE | DELETE_SELF);
  123. mWallpaperDir = getWallpaperDir(wallpaper.userId);
  124. mWallpaper = wallpaper;
  125. mWallpaperFile = new File(mWallpaperDir, WALLPAPER);
  126. }
  127.  
  128. @Override
  129. public void onEvent(int event, String path) {
  130. if (path == null) {
  131. return;
  132. }
  133. synchronized (mLock) {
  134. // changing the wallpaper means we'll need to back up the new one
  135. long origId = Binder.clearCallingIdentity();
  136. BackupManager bm = new BackupManager(mContext);
  137. bm.dataChanged();
  138. Binder.restoreCallingIdentity(origId);
  139.  
  140. File changedFile = new File(mWallpaperDir, path);
  141. if (mWallpaperFile.equals(changedFile)) {
  142. notifyCallbacksLocked(mWallpaper);
  143. if (mWallpaper.wallpaperComponent == null || event != CLOSE_WRITE
  144. || mWallpaper.imageWallpaperPending) {
  145. if (event == CLOSE_WRITE) {
  146. mWallpaper.imageWallpaperPending = false;
  147. }
  148. bindWallpaperComponentLocked(IMAGE_WALLPAPER, true,
  149. false, mWallpaper, null);
  150. saveSettingsLocked(mWallpaper);
  151. }
  152. }
  153. }
  154. }
  155. }
  156.  
  157. final Context mContext;
  158. final IWindowManager mIWindowManager;
  159. final IPackageManager mIPackageManager;
  160. final MyPackageMonitor mMonitor;
  161. WallpaperData mLastWallpaper;
  162.  
  163. SparseArray<WallpaperData> mWallpaperMap = new SparseArray<WallpaperData>();
  164.  
  165. int mCurrentUserId;
  166.  
  167. static class WallpaperData {
  168.  
  169. int userId;
  170.  
  171. File wallpaperFile;
  172.  
  173. /**
  174.   * Client is currently writing a new image wallpaper.
  175.   */
  176. boolean imageWallpaperPending;
  177.  
  178. /**
  179.   * Resource name if using a picture from the wallpaper gallery
  180.   */
  181. String name = "";
  182.  
  183. /**
  184.   * The component name of the currently set live wallpaper.
  185.   */
  186. ComponentName wallpaperComponent;
  187.  
  188. /**
  189.   * The component name of the wallpaper that should be set next.
  190.   */
  191. ComponentName nextWallpaperComponent;
  192.  
  193. WallpaperConnection connection;
  194. long lastDiedTime;
  195. boolean wallpaperUpdating;
  196. WallpaperObserver wallpaperObserver;
  197.  
  198. /**
  199.   * List of callbacks registered they should each be notified when the wallpaper is changed.
  200.   */
  201. private RemoteCallbackList<IWallpaperManagerCallback> callbacks
  202. = new RemoteCallbackList<IWallpaperManagerCallback>();
  203.  
  204. int width = -1;
  205. int height = -1;
  206.  
  207. WallpaperData(int userId) {
  208. this.userId = userId;
  209. wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
  210. }
  211. }
  212.  
  213. class WallpaperConnection extends IWallpaperConnection.Stub
  214. implements ServiceConnection {
  215. final WallpaperInfo mInfo;
  216. final Binder mToken = new Binder();
  217. IWallpaperService mService;
  218. IWallpaperEngine mEngine;
  219. WallpaperData mWallpaper;
  220. IRemoteCallback mReply;
  221.  
  222. public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
  223. mInfo = info;
  224. mWallpaper = wallpaper;
  225. }
  226.  
  227. @Override
  228. public void onServiceConnected(ComponentName name, IBinder service) {
  229. synchronized (mLock) {
  230. if (mWallpaper.connection == this) {
  231. mWallpaper.lastDiedTime = SystemClock.uptimeMillis();
  232. mService = IWallpaperService.Stub.asInterface(service);
  233. attachServiceLocked(this, mWallpaper);
  234. // XXX should probably do saveSettingsLocked() later
  235. // when we have an engine, but I'm not sure about
  236. // locking there and anyway we always need to be able to
  237. // recover if there is something wrong.
  238. saveSettingsLocked(mWallpaper);
  239. }
  240. }
  241. }
  242.  
  243. @Override
  244. public void onServiceDisconnected(ComponentName name) {
  245. synchronized (mLock) {
  246. mService = null;
  247. mEngine = null;
  248. if (mWallpaper.connection == this) {
  249. Slog.w(TAG, "Wallpaper service gone: " + mWallpaper.wallpaperComponent);
  250. if (mWallpaper.wallpaperComponent.equals(IMAGE_WALLPAPER)) {
  251. Slog.w(TAG, "SystemUI wallpaper disconnected, assuming it's being restarted, not clearing wallpaper.");
  252. return;
  253. }
  254. if (!mWallpaper.wallpaperUpdating
  255. && (mWallpaper.lastDiedTime + MIN_WALLPAPER_CRASH_TIME)
  256. > SystemClock.uptimeMillis()
  257. && mWallpaper.userId == mCurrentUserId) {
  258. Slog.w(TAG, "Reverting to built-in wallpaper!");
  259. clearWallpaperLocked(true, mWallpaper.userId, null);
  260. }
  261. }
  262. }
  263. }
  264.  
  265. @Override
  266. public void attachEngine(IWallpaperEngine engine) {
  267. synchronized (mLock) {
  268. mEngine = engine;
  269. }
  270. }
  271.  
  272. @Override
  273. public void engineShown(IWallpaperEngine engine) {
  274. synchronized (mLock) {
  275. if (mReply != null) {
  276. long ident = Binder.clearCallingIdentity();
  277. try {
  278. mReply.sendResult(null);
  279. } catch (RemoteException e) {
  280. Binder.restoreCallingIdentity(ident);
  281. }
  282. mReply = null;
  283. }
  284. }
  285. }
  286.  
  287. @Override
  288. public ParcelFileDescriptor setWallpaper(String name) {
  289. synchronized (mLock) {
  290. if (mWallpaper.connection == this) {
  291. return updateWallpaperBitmapLocked(name, mWallpaper);
  292. }
  293. return null;
  294. }
  295. }
  296. }
  297.  
  298. class MyPackageMonitor extends PackageMonitor {
  299. @Override
  300. public void onPackageUpdateFinished(String packageName, int uid) {
  301. synchronized (mLock) {
  302. if (mCurrentUserId != getChangingUserId()) {
  303. return;
  304. }
  305. WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
  306. if (wallpaper != null) {
  307. if (wallpaper.wallpaperComponent != null
  308. && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
  309. wallpaper.wallpaperUpdating = false;
  310. ComponentName comp = wallpaper.wallpaperComponent;
  311. clearWallpaperComponentLocked(wallpaper);
  312. if (!bindWallpaperComponentLocked(comp, false, false,
  313. wallpaper, null)) {
  314. Slog.w(TAG, "Wallpaper no longer available; reverting to default");
  315. clearWallpaperLocked(false, wallpaper.userId, null);
  316. }
  317. }
  318. }
  319. }
  320. }
  321.  
  322. @Override
  323. public void onPackageModified(String packageName) {
  324. synchronized (mLock) {
  325. if (mCurrentUserId != getChangingUserId()) {
  326. return;
  327. }
  328. WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
  329. if (wallpaper != null) {
  330. if (wallpaper.wallpaperComponent == null
  331. || !wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
  332. return;
  333. }
  334. doPackagesChangedLocked(true, wallpaper);
  335. }
  336. }
  337. }
  338.  
  339. @Override
  340. public void onPackageUpdateStarted(String packageName, int uid) {
  341. synchronized (mLock) {
  342. if (mCurrentUserId != getChangingUserId()) {
  343. return;
  344. }
  345. WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
  346. if (wallpaper != null) {
  347. if (wallpaper.wallpaperComponent != null
  348. && wallpaper.wallpaperComponent.getPackageName().equals(packageName)) {
  349. wallpaper.wallpaperUpdating = true;
  350. }
  351. }
  352. }
  353. }
  354.  
  355. @Override
  356. public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
  357. synchronized (mLock) {
  358. boolean changed = false;
  359. if (mCurrentUserId != getChangingUserId()) {
  360. return false;
  361. }
  362. WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
  363. if (wallpaper != null) {
  364. boolean res = doPackagesChangedLocked(doit, wallpaper);
  365. changed |= res;
  366. }
  367. return changed;
  368. }
  369. }
  370.  
  371. @Override
  372. public void onSomePackagesChanged() {
  373. synchronized (mLock) {
  374. if (mCurrentUserId != getChangingUserId()) {
  375. return;
  376. }
  377. WallpaperData wallpaper = mWallpaperMap.get(mCurrentUserId);
  378. if (wallpaper != null) {
  379. doPackagesChangedLocked(true, wallpaper);
  380. }
  381. }
  382. }
  383.  
  384. boolean doPackagesChangedLocked(boolean doit, WallpaperData wallpaper) {
  385. boolean changed = false;
  386. if (wallpaper.wallpaperComponent != null) {
  387. int change = isPackageDisappearing(wallpaper.wallpaperComponent
  388. .getPackageName());
  389. if (change == PACKAGE_PERMANENT_CHANGE
  390. || change == PACKAGE_TEMPORARY_CHANGE) {
  391. changed = true;
  392. if (doit) {
  393. Slog.w(TAG, "Wallpaper uninstalled, removing: "
  394. + wallpaper.wallpaperComponent);
  395. clearWallpaperLocked(false, wallpaper.userId, null);
  396. }
  397. }
  398. }
  399. if (wallpaper.nextWallpaperComponent != null) {
  400. int change = isPackageDisappearing(wallpaper.nextWallpaperComponent
  401. .getPackageName());
  402. if (change == PACKAGE_PERMANENT_CHANGE
  403. || change == PACKAGE_TEMPORARY_CHANGE) {
  404. wallpaper.nextWallpaperComponent = null;
  405. }
  406. }
  407. if (wallpaper.wallpaperComponent != null
  408. && isPackageModified(wallpaper.wallpaperComponent.getPackageName())) {
  409. try {
  410. mContext.getPackageManager().getServiceInfo(
  411. wallpaper.wallpaperComponent, 0);
  412. } catch (NameNotFoundException e) {
  413. Slog.w(TAG, "Wallpaper component gone, removing: "
  414. + wallpaper.wallpaperComponent);
  415. clearWallpaperLocked(false, wallpaper.userId, null);
  416. }
  417. }
  418. if (wallpaper.nextWallpaperComponent != null
  419. && isPackageModified(wallpaper.nextWallpaperComponent.getPackageName())) {
  420. try {
  421. mContext.getPackageManager().getServiceInfo(
  422. wallpaper.nextWallpaperComponent, 0);
  423. } catch (NameNotFoundException e) {
  424. wallpaper.nextWallpaperComponent = null;
  425. }
  426. }
  427. return changed;
  428. }
  429. }
  430.  
  431. public WallpaperManagerService(Context context) {
  432. if (DEBUG) Slog.v(TAG, "WallpaperService startup");
  433. mContext = context;
  434. mIWindowManager = IWindowManager.Stub.asInterface(
  435. ServiceManager.getService(Context.WINDOW_SERVICE));
  436. mIPackageManager = AppGlobals.getPackageManager();
  437. mMonitor = new MyPackageMonitor();
  438. mMonitor.register(context, null, UserHandle.ALL, true);
  439. getWallpaperDir(UserHandle.USER_OWNER).mkdirs();
  440. loadSettingsLocked(UserHandle.USER_OWNER);
  441. }
  442.  
  443. private static File getWallpaperDir(int userId) {
  444. return Environment.getUserSystemDirectory(userId);
  445. }
  446.  
  447. @Override
  448. protected void finalize() throws Throwable {
  449. super.finalize();
  450. for (int i = 0; i < mWallpaperMap.size(); i++) {
  451. WallpaperData wallpaper = mWallpaperMap.valueAt(i);
  452. wallpaper.wallpaperObserver.stopWatching();
  453. }
  454. }
  455.  
  456. public void systemReady() {
  457. if (DEBUG) Slog.v(TAG, "systemReady");
  458. WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_OWNER);
  459. switchWallpaper(wallpaper, null);
  460. wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
  461. wallpaper.wallpaperObserver.startWatching();
  462.  
  463. IntentFilter userFilter = new IntentFilter();
  464. userFilter.addAction(Intent.ACTION_USER_REMOVED);
  465. userFilter.addAction(Intent.ACTION_USER_STOPPING);
  466. mContext.registerReceiver(new BroadcastReceiver() {
  467. @Override
  468. public void onReceive(Context context, Intent intent) {
  469. String action = intent.getAction();
  470. if (Intent.ACTION_USER_REMOVED.equals(action)) {
  471. onRemoveUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
  472. UserHandle.USER_NULL));
  473. }
  474. // TODO: Race condition causing problems when cleaning up on stopping a user.
  475. // Comment this out for now.
  476. // else if (Intent.ACTION_USER_STOPPING.equals(action)) {
  477. // onStoppingUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
  478. // UserHandle.USER_NULL));
  479. // }
  480. }
  481. }, userFilter);
  482.  
  483. try {
  484. ActivityManagerNative.getDefault().registerUserSwitchObserver(
  485. new IUserSwitchObserver.Stub() {
  486. @Override
  487. public void onUserSwitching(int newUserId, IRemoteCallback reply) {
  488. switchUser(newUserId, reply);
  489. }
  490.  
  491. @Override
  492. public void onUserSwitchComplete(int newUserId) throws RemoteException {
  493. }
  494. });
  495. } catch (RemoteException e) {
  496. // TODO Auto-generated catch block
  497. e.printStackTrace();
  498. }
  499. }
  500.  
  501. String getName() {
  502. synchronized (mLock) {
  503. return mWallpaperMap.get(0).name;
  504. }
  505. }
  506.  
  507. void onStoppingUser(int userId) {
  508. if (userId < 1) return;
  509. synchronized (mLock) {
  510. WallpaperData wallpaper = mWallpaperMap.get(userId);
  511. if (wallpaper != null) {
  512. if (wallpaper.wallpaperObserver != null) {
  513. wallpaper.wallpaperObserver.stopWatching();
  514. wallpaper.wallpaperObserver = null;
  515. }
  516. mWallpaperMap.remove(userId);
  517. }
  518. }
  519. }
  520.  
  521. void onRemoveUser(int userId) {
  522. if (userId < 1) return;
  523. synchronized (mLock) {
  524. onStoppingUser(userId);
  525. File wallpaperFile = new File(getWallpaperDir(userId), WALLPAPER);
  526. wallpaperFile.delete();
  527. File wallpaperInfoFile = new File(getWallpaperDir(userId), WALLPAPER_INFO);
  528. wallpaperInfoFile.delete();
  529. }
  530. }
  531.  
  532. void switchUser(int userId, IRemoteCallback reply) {
  533. synchronized (mLock) {
  534. mCurrentUserId = userId;
  535. WallpaperData wallpaper = mWallpaperMap.get(userId);
  536. if (wallpaper == null) {
  537. wallpaper = new WallpaperData(userId);
  538. mWallpaperMap.put(userId, wallpaper);
  539. loadSettingsLocked(userId);
  540. }
  541. // Not started watching yet, in case wallpaper data was loaded for other reasons.
  542. if (wallpaper.wallpaperObserver == null) {
  543. wallpaper.wallpaperObserver = new WallpaperObserver(wallpaper);
  544. wallpaper.wallpaperObserver.startWatching();
  545. }
  546. switchWallpaper(wallpaper, reply);
  547. }
  548. }
  549.  
  550. void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
  551. synchronized (mLock) {
  552. RuntimeException e = null;
  553. try {
  554. ComponentName cname = wallpaper.wallpaperComponent != null ?
  555. wallpaper.wallpaperComponent : wallpaper.nextWallpaperComponent;
  556. if (bindWallpaperComponentLocked(cname, true, false, wallpaper, reply)) {
  557. return;
  558. }
  559. } catch (RuntimeException e1) {
  560. e = e1;
  561. }
  562. Slog.w(TAG, "Failure starting previous wallpaper", e);
  563. clearWallpaperLocked(false, wallpaper.userId, reply);
  564. }
  565. }
  566.  
  567. public void clearWallpaper() {
  568. if (DEBUG) Slog.v(TAG, "clearWallpaper");
  569. synchronized (mLock) {
  570. clearWallpaperLocked(false, UserHandle.getCallingUserId(), null);
  571. }
  572. }
  573.  
  574. void clearWallpaperLocked(boolean defaultFailed, int userId, IRemoteCallback reply) {
  575. WallpaperData wallpaper = mWallpaperMap.get(userId);
  576. File f = new File(getWallpaperDir(userId), WALLPAPER);
  577. if (f.exists()) {
  578. f.delete();
  579. }
  580. final long ident = Binder.clearCallingIdentity();
  581. RuntimeException e = null;
  582. try {
  583. wallpaper.imageWallpaperPending = false;
  584. if (userId != mCurrentUserId) return;
  585. if (bindWallpaperComponentLocked(defaultFailed
  586. ? IMAGE_WALLPAPER
  587. : null, true, false, wallpaper, reply)) {
  588. return;
  589. }
  590. } catch (IllegalArgumentException e1) {
  591. e = e1;
  592. } finally {
  593. Binder.restoreCallingIdentity(ident);
  594. }
  595.  
  596. // This can happen if the default wallpaper component doesn't
  597. // exist. This should be a system configuration problem, but
  598. // let's not let it crash the system and just live with no
  599. // wallpaper.
  600. Slog.e(TAG, "Default wallpaper component not found!", e);
  601. clearWallpaperComponentLocked(wallpaper);
  602. if (reply != null) {
  603. try {
  604. reply.sendResult(null);
  605. } catch (RemoteException e1) {
  606. }
  607. }
  608. }
  609.  
  610. public boolean hasNamedWallpaper(String name) {
  611. synchronized (mLock) {
  612. List<UserInfo> users;
  613. long ident = Binder.clearCallingIdentity();
  614. try {
  615. users = ((UserManager) mContext.getSystemService(Context.USER_SERVICE)).getUsers();
  616. } finally {
  617. Binder.restoreCallingIdentity(ident);
  618. }
  619. for (UserInfo user: users) {
  620. WallpaperData wd = mWallpaperMap.get(user.id);
  621. if (wd == null) {
  622. // User hasn't started yet, so load her settings to peek at the wallpaper
  623. loadSettingsLocked(user.id);
  624. wd = mWallpaperMap.get(user.id);
  625. }
  626. if (wd != null && name.equals(wd.name)) {
  627. return true;
  628. }
  629. }
  630. }
  631. return false;
  632. }
  633.  
  634. public void setDimensionHints(int width, int height) throws RemoteException {
  635. checkPermission(android.Manifest.permission.SET_WALLPAPER_HINTS);
  636. synchronized (mLock) {
  637. int userId = UserHandle.getCallingUserId();
  638. WallpaperData wallpaper = mWallpaperMap.get(userId);
  639. if (wallpaper == null) {
  640. throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
  641. }
  642. if (width <= 0 || height <= 0) {
  643. throw new IllegalArgumentException("width and height must be > 0");
  644. }
  645.  
  646. if (width != wallpaper.width || height != wallpaper.height) {
  647. wallpaper.width = width;
  648. wallpaper.height = height;
  649. saveSettingsLocked(wallpaper);
  650. if (mCurrentUserId != userId) return; // Don't change the properties now
  651. if (wallpaper.connection != null) {
  652. if (wallpaper.connection.mEngine != null) {
  653. try {
  654. wallpaper.connection.mEngine.setDesiredSize(
  655. width, height);
  656. } catch (RemoteException e) {
  657. }
  658. notifyCallbacksLocked(wallpaper);
  659. }
  660. }
  661. }
  662. }
  663. }
  664.  
  665. public int getWidthHint() throws RemoteException {
  666. synchronized (mLock) {
  667. WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
  668. return wallpaper.width;
  669. }
  670. }
  671.  
  672. public int getHeightHint() throws RemoteException {
  673. synchronized (mLock) {
  674. WallpaperData wallpaper = mWallpaperMap.get(UserHandle.getCallingUserId());
  675. return wallpaper.height;
  676. }
  677. }
  678.  
  679. public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
  680. Bundle outParams) {
  681. synchronized (mLock) {
  682. // This returns the current user's wallpaper, if called by a system service. Else it
  683. // returns the wallpaper for the calling user.
  684. int callingUid = Binder.getCallingUid();
  685. int wallpaperUserId = 0;
  686. if (callingUid == android.os.Process.SYSTEM_UID) {
  687. wallpaperUserId = mCurrentUserId;
  688. } else {
  689. wallpaperUserId = UserHandle.getUserId(callingUid);
  690. }
  691. WallpaperData wallpaper = mWallpaperMap.get(wallpaperUserId);
  692. try {
  693. if (outParams != null) {
  694. outParams.putInt("width", wallpaper.width);
  695. outParams.putInt("height", wallpaper.height);
  696. }
  697. wallpaper.callbacks.register(cb);
  698. File f = new File(getWallpaperDir(wallpaperUserId), WALLPAPER);
  699. if (!f.exists()) {
  700. return null;
  701. }
  702. return ParcelFileDescriptor.open(f, MODE_READ_ONLY);
  703. } catch (FileNotFoundException e) {
  704. /* Shouldn't happen as we check to see if the file exists */
  705. Slog.w(TAG, "Error getting wallpaper", e);
  706. }
  707. return null;
  708. }
  709. }
  710.  
  711. public WallpaperInfo getWallpaperInfo() {
  712. int userId = UserHandle.getCallingUserId();
  713. synchronized (mLock) {
  714. WallpaperData wallpaper = mWallpaperMap.get(userId);
  715. if (wallpaper.connection != null) {
  716. return wallpaper.connection.mInfo;
  717. }
  718. return null;
  719. }
  720. }
  721.  
  722. public ParcelFileDescriptor setWallpaper(String name) {
  723. checkPermission(android.Manifest.permission.SET_WALLPAPER);
  724. synchronized (mLock) {
  725. if (DEBUG) Slog.v(TAG, "setWallpaper");
  726. int userId = UserHandle.getCallingUserId();
  727. WallpaperData wallpaper = mWallpaperMap.get(userId);
  728. if (wallpaper == null) {
  729. throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
  730. }
  731. final long ident = Binder.clearCallingIdentity();
  732. try {
  733. ParcelFileDescriptor pfd = updateWallpaperBitmapLocked(name, wallpaper);
  734. if (pfd != null) {
  735. wallpaper.imageWallpaperPending = true;
  736. }
  737. return pfd;
  738. } finally {
  739. Binder.restoreCallingIdentity(ident);
  740. }
  741. }
  742. }
  743.  
  744. ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
  745. if (name == null) name = "";
  746. try {
  747. File dir = getWallpaperDir(wallpaper.userId);
  748. if (!dir.exists()) {
  749. dir.mkdir();
  750. FileUtils.setPermissions(
  751. dir.getPath(),
  752. FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
  753. -1, -1);
  754. }
  755. File file = new File(dir, WALLPAPER);
  756. ParcelFileDescriptor fd = ParcelFileDescriptor.open(file,
  757. MODE_CREATE|MODE_READ_WRITE);
  758. if (!SELinux.restorecon(file)) {
  759. return null;
  760. }
  761. wallpaper.name = name;
  762. return fd;
  763. } catch (FileNotFoundException e) {
  764. Slog.w(TAG, "Error setting wallpaper", e);
  765. }
  766. return null;
  767. }
  768.  
  769. public void setWallpaperComponent(ComponentName name) {
  770. checkPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT);
  771. synchronized (mLock) {
  772. if (DEBUG) Slog.v(TAG, "setWallpaperComponent name=" + name);
  773. int userId = UserHandle.getCallingUserId();
  774. WallpaperData wallpaper = mWallpaperMap.get(userId);
  775. if (wallpaper == null) {
  776. throw new IllegalStateException("Wallpaper not yet initialized for user " + userId);
  777. }
  778. final long ident = Binder.clearCallingIdentity();
  779. try {
  780. wallpaper.imageWallpaperPending = false;
  781. bindWallpaperComponentLocked(name, false, true, wallpaper, null);
  782. } finally {
  783. Binder.restoreCallingIdentity(ident);
  784. }
  785. }
  786. }
  787.  
  788. boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
  789. boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) {
  790. if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: componentName=" + componentName);
  791. // Has the component changed?
  792. if (!force) {
  793. if (wallpaper.connection != null) {
  794. if (wallpaper.wallpaperComponent == null) {
  795. if (componentName == null) {
  796. if (DEBUG) Slog.v(TAG, "bindWallpaperComponentLocked: still using default");
  797. // Still using default wallpaper.
  798. return true;
  799. }
  800. } else if (wallpaper.wallpaperComponent.equals(componentName)) {
  801. // Changing to same wallpaper.
  802. if (DEBUG) Slog.v(TAG, "same wallpaper");
  803. return true;
  804. }
  805. }
  806. }
  807.  
  808. try {
  809. if (componentName == null) {
  810. String defaultComponent =
  811. mContext.getString(com.android.internal.R.string.default_wallpaper_component);
  812. if (defaultComponent != null) {
  813. // See if there is a default wallpaper component specified
  814. componentName = ComponentName.unflattenFromString(defaultComponent);
  815. if (DEBUG) Slog.v(TAG, "Use default component wallpaper:" + componentName);
  816. }
  817. if (componentName == null) {
  818. // Fall back to static image wallpaper
  819. componentName = IMAGE_WALLPAPER;
  820. //clearWallpaperComponentLocked();
  821. //return;
  822. if (DEBUG) Slog.v(TAG, "Using image wallpaper");
  823. }
  824. }
  825. int serviceUserId = wallpaper.userId;
  826. ServiceInfo si = mIPackageManager.getServiceInfo(componentName,
  827. PackageManager.GET_META_DATA | PackageManager.GET_PERMISSIONS, serviceUserId);
  828. if (!android.Manifest.permission.BIND_WALLPAPER.equals(si.permission)) {
  829. String msg = "Selected service does not require "
  830. + android.Manifest.permission.BIND_WALLPAPER
  831. + ": " + componentName;
  832. if (fromUser) {
  833. throw new SecurityException(msg);
  834. }
  835. Slog.w(TAG, msg);
  836. return false;
  837. }
  838.  
  839. WallpaperInfo wi = null;
  840.  
  841. Intent intent = new Intent(WallpaperService.SERVICE_INTERFACE);
  842. if (componentName != null && !componentName.equals(IMAGE_WALLPAPER)) {
  843. // Make sure the selected service is actually a wallpaper service.
  844. List<ResolveInfo> ris =
  845. mIPackageManager.queryIntentServices(intent,
  846. intent.resolveTypeIfNeeded(mContext.getContentResolver()),
  847. PackageManager.GET_META_DATA, serviceUserId);
  848. for (int i=0; i<ris.size(); i++) {
  849. ServiceInfo rsi = ris.get(i).serviceInfo;
  850. if (rsi.name.equals(si.name) &&
  851. rsi.packageName.equals(si.packageName)) {
  852. try {
  853. wi = new WallpaperInfo(mContext, ris.get(i));
  854. } catch (XmlPullParserException e) {
  855. if (fromUser) {
  856. }
  857. Slog.w(TAG, e);
  858. return false;
  859. } catch (IOException e) {
  860. if (fromUser) {
  861. }
  862. Slog.w(TAG, e);
  863. return false;
  864. }
  865. break;
  866. }
  867. }
  868. if (wi == null) {
  869. String msg = "Selected service is not a wallpaper: "
  870. + componentName;
  871. if (fromUser) {
  872. throw new SecurityException(msg);
  873. }
  874. Slog.w(TAG, msg);
  875. return false;
  876. }
  877. }
  878.  
  879. // Bind the service!
  880. if (DEBUG) Slog.v(TAG, "Binding to:" + componentName);
  881. WallpaperConnection newConn = new WallpaperConnection(wi, wallpaper);
  882. intent.setComponent(componentName);
  883. intent.putExtra(Intent.EXTRA_CLIENT_LABEL,
  884. com.android.internal.R.string.wallpaper_binding_label);
  885. intent.putExtra(Intent.EXTRA_CLIENT_INTENT, PendingIntent.getActivityAsUser(
  886. mContext, 0,
  887. Intent.createChooser(new Intent(Intent.ACTION_SET_WALLPAPER),
  888. mContext.getText(com.android.internal.R.string.chooser_wallpaper)),
  889. 0, null, new UserHandle(serviceUserId)));
  890. if (!mContext.bindService(intent, newConn, Context.BIND_AUTO_CREATE, serviceUserId)) {
  891. String msg = "Unable to bind service: "
  892. + componentName;
  893. if (fromUser) {
  894. throw new IllegalArgumentException(msg);
  895. }
  896. Slog.w(TAG, msg);
  897. return false;
  898. }
  899. if (wallpaper.userId == mCurrentUserId && mLastWallpaper != null) {
  900. detachWallpaperLocked(mLastWallpaper);
  901. }
  902. wallpaper.wallpaperComponent = componentName;
  903. wallpaper.connection = newConn;
  904. wallpaper.lastDiedTime = SystemClock.uptimeMillis();
  905. newConn.mReply = reply;
  906. try {
  907. if (wallpaper.userId == mCurrentUserId) {
  908. if (DEBUG)
  909. Slog.v(TAG, "Adding window token: " + newConn.mToken);
  910. mIWindowManager.addWindowToken(newConn.mToken,
  911. WindowManager.LayoutParams.TYPE_WALLPAPER);
  912. mLastWallpaper = wallpaper;
  913. }
  914. } catch (RemoteException e) {
  915. }
  916. } catch (RemoteException e) {
  917. String msg = "Remote exception for " + componentName + "\n" + e;
  918. if (fromUser) {
  919. throw new IllegalArgumentException(msg);
  920. }
  921. Slog.w(TAG, msg);
  922. return false;
  923. }
  924. return true;
  925. }
  926.  
  927. void detachWallpaperLocked(WallpaperData wallpaper) {
  928. if (wallpaper.connection != null) {
  929. if (wallpaper.connection.mReply != null) {
  930. try {
  931. wallpaper.connection.mReply.sendResult(null);
  932. } catch (RemoteException e) {
  933. }
  934. wallpaper.connection.mReply = null;
  935. }
  936. if (wallpaper.connection.mEngine != null) {
  937. try {
  938. wallpaper.connection.mEngine.destroy();
  939. } catch (RemoteException e) {
  940. }
  941. }
  942. mContext.unbindService(wallpaper.connection);
  943. try {
  944. if (DEBUG)
  945. Slog.v(TAG, "Removing window token: " + wallpaper.connection.mToken);
  946. mIWindowManager.removeWindowToken(wallpaper.connection.mToken);
  947. } catch (RemoteException e) {
  948. }
  949. wallpaper.connection.mService = null;
  950. wallpaper.connection.mEngine = null;
  951. wallpaper.connection = null;
  952. }
  953. }
  954.  
  955. void clearWallpaperComponentLocked(WallpaperData wallpaper) {
  956. wallpaper.wallpaperComponent = null;
  957. detachWallpaperLocked(wallpaper);
  958. }
  959.  
  960. void attachServiceLocked(WallpaperConnection conn, WallpaperData wallpaper) {
  961. try {
  962. conn.mService.attach(conn, conn.mToken,
  963. WindowManager.LayoutParams.TYPE_WALLPAPER, false,
  964. wallpaper.width, wallpaper.height);
  965. } catch (RemoteException e) {
  966. Slog.w(TAG, "Failed attaching wallpaper; clearing", e);
  967. if (!wallpaper.wallpaperUpdating) {
  968. bindWallpaperComponentLocked(null, false, false, wallpaper, null);
  969. }
  970. }
  971. }
  972.  
  973. private void notifyCallbacksLocked(WallpaperData wallpaper) {
  974. final int n = wallpaper.callbacks.beginBroadcast();
  975. for (int i = 0; i < n; i++) {
  976. try {
  977. wallpaper.callbacks.getBroadcastItem(i).onWallpaperChanged();
  978. } catch (RemoteException e) {
  979.  
  980. // The RemoteCallbackList will take care of removing
  981. // the dead object for us.
  982. }
  983. }
  984. wallpaper.callbacks.finishBroadcast();
  985. final Intent intent = new Intent(Intent.ACTION_WALLPAPER_CHANGED);
  986. mContext.sendBroadcastAsUser(intent, new UserHandle(mCurrentUserId));
  987. }
  988.  
  989. private void checkPermission(String permission) {
  990. if (PackageManager.PERMISSION_GRANTED!= mContext.checkCallingOrSelfPermission(permission)) {
  991. throw new SecurityException("Access denied to process: " + Binder.getCallingPid()
  992. + ", must have permission " + permission);
  993. }
  994. }
  995.  
  996. private static JournaledFile makeJournaledFile(int userId) {
  997. final String base = new File(getWallpaperDir(userId), WALLPAPER_INFO).getAbsolutePath();
  998. return new JournaledFile(new File(base), new File(base + ".tmp"));
  999. }
  1000.  
  1001. private void saveSettingsLocked(WallpaperData wallpaper) {
  1002. JournaledFile journal = makeJournaledFile(wallpaper.userId);
  1003. FileOutputStream stream = null;
  1004. try {
  1005. stream = new FileOutputStream(journal.chooseForWrite(), false);
  1006. XmlSerializer out = new FastXmlSerializer();
  1007. out.setOutput(stream, "utf-8");
  1008. out.startDocument(null, true);
  1009.  
  1010. out.startTag(null, "wp");
  1011. out.attribute(null, "width", Integer.toString(wallpaper.width));
  1012. out.attribute(null, "height", Integer.toString(wallpaper.height));
  1013. out.attribute(null, "name", wallpaper.name);
  1014. if (wallpaper.wallpaperComponent != null
  1015. && !wallpaper.wallpaperComponent.equals(IMAGE_WALLPAPER)) {
  1016. out.attribute(null, "component",
  1017. wallpaper.wallpaperComponent.flattenToShortString());
  1018. }
  1019. out.endTag(null, "wp");
  1020.  
  1021. out.endDocument();
  1022. stream.close();
  1023. journal.commit();
  1024. } catch (IOException e) {
  1025. try {
  1026. if (stream != null) {
  1027. stream.close();
  1028. }
  1029. } catch (IOException ex) {
  1030. // Ignore
  1031. }
  1032. journal.rollback();
  1033. }
  1034. }
  1035.  
  1036. private void migrateFromOld() {
  1037. File oldWallpaper = new File(WallpaperBackupHelper.WALLPAPER_IMAGE_KEY);
  1038. File oldInfo = new File(WallpaperBackupHelper.WALLPAPER_INFO_KEY);
  1039. if (oldWallpaper.exists()) {
  1040. File newWallpaper = new File(getWallpaperDir(0), WALLPAPER);
  1041. oldWallpaper.renameTo(newWallpaper);
  1042. }
  1043. if (oldInfo.exists()) {
  1044. File newInfo = new File(getWallpaperDir(0), WALLPAPER_INFO);
  1045. oldInfo.renameTo(newInfo);
  1046. }
  1047. }
  1048.  
  1049. private void loadSettingsLocked(int userId) {
  1050. if (DEBUG) Slog.v(TAG, "loadSettingsLocked");
  1051.  
  1052. JournaledFile journal = makeJournaledFile(userId);
  1053. FileInputStream stream = null;
  1054. File file = journal.chooseForRead();
  1055. if (!file.exists()) {
  1056. // This should only happen one time, when upgrading from a legacy system
  1057. migrateFromOld();
  1058. }
  1059. WallpaperData wallpaper = mWallpaperMap.get(userId);
  1060. if (wallpaper == null) {
  1061. wallpaper = new WallpaperData(userId);
  1062. mWallpaperMap.put(userId, wallpaper);
  1063. }
  1064. boolean success = false;
  1065. try {
  1066. stream = new FileInputStream(file);
  1067. XmlPullParser parser = Xml.newPullParser();
  1068. parser.setInput(stream, null);
  1069.  
  1070. int type;
  1071. do {
  1072. type = parser.next();
  1073. if (type == XmlPullParser.START_TAG) {
  1074. String tag = parser.getName();
  1075. if ("wp".equals(tag)) {
  1076. wallpaper.width = Integer.parseInt(parser.getAttributeValue(null, "width"));
  1077. wallpaper.height = Integer.parseInt(parser
  1078. .getAttributeValue(null, "height"));
  1079. wallpaper.name = parser.getAttributeValue(null, "name");
  1080. String comp = parser.getAttributeValue(null, "component");
  1081. wallpaper.nextWallpaperComponent = comp != null
  1082. ? ComponentName.unflattenFromString(comp)
  1083. : null;
  1084. if (wallpaper.nextWallpaperComponent == null
  1085. || "android".equals(wallpaper.nextWallpaperComponent
  1086. .getPackageName())) {
  1087. wallpaper.nextWallpaperComponent = IMAGE_WALLPAPER;
  1088. }
  1089.  
  1090. if (DEBUG) {
  1091. Slog.v(TAG, "mWidth:" + wallpaper.width);
  1092. Slog.v(TAG, "mHeight:" + wallpaper.height);
  1093. Slog.v(TAG, "mName:" + wallpaper.name);
  1094. Slog.v(TAG, "mNextWallpaperComponent:"
  1095. + wallpaper.nextWallpaperComponent);
  1096. }
  1097. }
  1098. }
  1099. } while (type != XmlPullParser.END_DOCUMENT);
  1100. success = true;
  1101. } catch (FileNotFoundException e) {
  1102. Slog.w(TAG, "no current wallpaper -- first boot?");
  1103. } catch (NullPointerException e) {
  1104. Slog.w(TAG, "failed parsing " + file + " " + e);
  1105. } catch (NumberFormatException e) {
  1106. Slog.w(TAG, "failed parsing " + file + " " + e);
  1107. } catch (XmlPullParserException e) {
  1108. Slog.w(TAG, "failed parsing " + file + " " + e);
  1109. } catch (IOException e) {
  1110. Slog.w(TAG, "failed parsing " + file + " " + e);
  1111. Slog.w(TAG, "failed parsing " + file + " " + e);
  1112. }
  1113. try {
  1114. if (stream != null) {
  1115. stream.close();
  1116. }
  1117. } catch (IOException e) {
  1118. // Ignore
  1119. }
  1120.  
  1121. if (!success) {
  1122. wallpaper.width = -1;
  1123. wallpaper.height = -1;
  1124. wallpaper.name = "";
  1125. }
  1126.  
  1127. // We always want to have some reasonable width hint.
  1128. WindowManager wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
  1129. Display d = wm.getDefaultDisplay();
  1130. int baseSize = d.getMaximumSizeDimension();
  1131. if (wallpaper.width < baseSize) {
  1132. wallpaper.width = baseSize;
  1133. }
  1134. if (wallpaper.height < baseSize) {
  1135. wallpaper.height = baseSize;
  1136. }
  1137. }
  1138.  
  1139. // Called by SystemBackupAgent after files are restored to disk.
  1140. void settingsRestored() {
  1141. // TODO: If necessary, make it work for secondary users as well. This currently assumes
  1142. // restores only to the primary user
  1143. if (DEBUG) Slog.v(TAG, "settingsRestored");
  1144. WallpaperData wallpaper = null;
  1145. boolean success = false;
  1146. synchronized (mLock) {
  1147. loadSettingsLocked(0);
  1148. wallpaper = mWallpaperMap.get(0);
  1149. if (wallpaper.nextWallpaperComponent != null
  1150. && !wallpaper.nextWallpaperComponent.equals(IMAGE_WALLPAPER)) {
  1151. if (!bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
  1152. wallpaper, null)) {
  1153. // No such live wallpaper or other failure; fall back to the default
  1154. // live wallpaper (since the profile being restored indicated that the
  1155. // user had selected a live rather than static one).
  1156. bindWallpaperComponentLocked(null, false, false, wallpaper, null);
  1157. }
  1158. success = true;
  1159. } else {
  1160. // If there's a wallpaper name, we use that. If that can't be loaded, then we
  1161. // use the default.
  1162. if ("".equals(wallpaper.name)) {
  1163. if (DEBUG) Slog.v(TAG, "settingsRestored: name is empty");
  1164. success = true;
  1165. } else {
  1166. if (DEBUG) Slog.v(TAG, "settingsRestored: attempting to restore named resource");
  1167. success = restoreNamedResourceLocked(wallpaper);
  1168. }
  1169. if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success);
  1170. if (success) {
  1171. bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false,
  1172. wallpaper, null);
  1173. }
  1174. }
  1175. }
  1176.  
  1177. if (!success) {
  1178. Slog.e(TAG, "Failed to restore wallpaper: '" + wallpaper.name + "'");
  1179. wallpaper.name = "";
  1180. getWallpaperDir(0).delete();
  1181. }
  1182.  
  1183. synchronized (mLock) {
  1184. saveSettingsLocked(wallpaper);
  1185. }
  1186. }
  1187.  
  1188. boolean restoreNamedResourceLocked(WallpaperData wallpaper) {
  1189. if (wallpaper.name.length() > 4 && "res:".equals(wallpaper.name.substring(0, 4))) {
  1190. String resName = wallpaper.name.substring(4);
  1191.  
  1192. String pkg = null;
  1193. int colon = resName.indexOf(':');
  1194. if (colon > 0) {
  1195. pkg = resName.substring(0, colon);
  1196. }
  1197.  
  1198. String ident = null;
  1199. int slash = resName.lastIndexOf('/');
  1200. if (slash > 0) {
  1201. ident = resName.substring(slash+1);
  1202. }
  1203.  
  1204. String type = null;
  1205. if (colon > 0 && slash > 0 && (slash-colon) > 1) {
  1206. type = resName.substring(colon+1, slash);
  1207. }
  1208.  
  1209. if (pkg != null && ident != null && type != null) {
  1210. int resId = -1;
  1211. InputStream res = null;
  1212. FileOutputStream fos = null;
  1213. try {
  1214. Context c = mContext.createPackageContext(pkg, Context.CONTEXT_RESTRICTED);
  1215. Resources r = c.getResources();
  1216. resId = r.getIdentifier(resName, null, null);
  1217. if (resId == 0) {
  1218. Slog.e(TAG, "couldn't resolve identifier pkg=" + pkg + " type=" + type
  1219. + " ident=" + ident);
  1220. return false;
  1221. }
  1222.  
  1223. res = r.openRawResource(resId);
  1224. if (wallpaper.wallpaperFile.exists()) {
  1225. wallpaper.wallpaperFile.delete();
  1226. }
  1227. fos = new FileOutputStream(wallpaper.wallpaperFile);
  1228.  
  1229. byte[] buffer = new byte[32768];
  1230. int amt;
  1231. while ((amt=res.read(buffer)) > 0) {
  1232. fos.write(buffer, 0, amt);
  1233. }
  1234. // mWallpaperObserver will notice the close and send the change broadcast
  1235.  
  1236. Slog.v(TAG, "Restored wallpaper: " + resName);
  1237. return true;
  1238. } catch (NameNotFoundException e) {
  1239. Slog.e(TAG, "Package name " + pkg + " not found");
  1240. } catch (Resources.NotFoundException e) {
  1241. Slog.e(TAG, "Resource not found: " + resId);
  1242. } catch (IOException e) {
  1243. Slog.e(TAG, "IOException while restoring wallpaper ", e);
  1244. } finally {
  1245. if (res != null) {
  1246. try {
  1247. res.close();
  1248. } catch (IOException ex) {}
  1249. }
  1250. if (fos != null) {
  1251. FileUtils.sync(fos);
  1252. try {
  1253. fos.close();
  1254. } catch (IOException ex) {}
  1255. }
  1256. }
  1257. }
  1258. }
  1259. return false;
  1260. }
  1261.  
  1262. @Override
  1263. protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
  1264. if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
  1265. != PackageManager.PERMISSION_GRANTED) {
  1266.  
  1267. pw.println("Permission Denial: can't dump wallpaper service from from pid="
  1268. + Binder.getCallingPid()
  1269. + ", uid=" + Binder.getCallingUid());
  1270. return;
  1271. }
  1272.  
  1273. synchronized (mLock) {
  1274. pw.println("Current Wallpaper Service state:");
  1275. for (int i = 0; i < mWallpaperMap.size(); i++) {
  1276. WallpaperData wallpaper = mWallpaperMap.valueAt(i);
  1277. pw.println(" User " + wallpaper.userId + ":");
  1278. pw.print(" mWidth=");
  1279. pw.print(wallpaper.width);
  1280. pw.print(" mHeight=");
  1281. pw.println(wallpaper.height);
  1282. pw.print(" mName=");
  1283. pw.println(wallpaper.name);
  1284. pw.print(" mWallpaperComponent=");
  1285. pw.println(wallpaper.wallpaperComponent);
  1286. if (wallpaper.connection != null) {
  1287. WallpaperConnection conn = wallpaper.connection;
  1288. pw.print(" Wallpaper connection ");
  1289. pw.print(conn);
  1290. pw.println(":");
  1291. if (conn.mInfo != null) {
  1292. pw.print(" mInfo.component=");
  1293. pw.println(conn.mInfo.getComponent());
  1294. }
  1295. pw.print(" mToken=");
  1296. pw.println(conn.mToken);
  1297. pw.print(" mService=");
  1298. pw.println(conn.mService);
  1299. pw.print(" mEngine=");
  1300. pw.println(conn.mEngine);
  1301. pw.print(" mLastDiedTime=");
  1302. pw.println(wallpaper.lastDiedTime - SystemClock.uptimeMillis());
  1303. }
  1304. }
  1305. }
  1306. }
  1307. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
Main.java:19: error: package android.os does not exist
import static android.os.ParcelFileDescriptor.*;
                        ^
Main.java:21: error: package android.app does not exist
import android.app.ActivityManagerNative;
                  ^
Main.java:22: error: package android.app does not exist
import android.app.AppGlobals;
                  ^
Main.java:23: error: package android.app does not exist
import android.app.IUserSwitchObserver;
                  ^
Main.java:24: error: package android.app does not exist
import android.app.IWallpaperManager;
                  ^
Main.java:25: error: package android.app does not exist
import android.app.IWallpaperManagerCallback;
                  ^
Main.java:26: error: package android.app does not exist
import android.app.PendingIntent;
                  ^
Main.java:27: error: package android.app does not exist
import android.app.WallpaperInfo;
                  ^
Main.java:28: error: package android.app.backup does not exist
import android.app.backup.BackupManager;
                         ^
Main.java:29: error: package android.app.backup does not exist
import android.app.backup.WallpaperBackupHelper;
                         ^
Main.java:30: error: package android.content does not exist
import android.content.BroadcastReceiver;
                      ^
Main.java:31: error: package android.content does not exist
import android.content.ComponentName;
                      ^
Main.java:32: error: package android.content does not exist
import android.content.Context;
                      ^
Main.java:33: error: package android.content does not exist
import android.content.Intent;
                      ^
Main.java:34: error: package android.content does not exist
import android.content.IntentFilter;
                      ^
Main.java:35: error: package android.content does not exist
import android.content.ServiceConnection;
                      ^
Main.java:36: error: package android.content.pm does not exist
import android.content.pm.IPackageManager;
                         ^
Main.java:37: error: package android.content.pm does not exist
import android.content.pm.PackageManager;
                         ^
Main.java:38: error: package android.content.pm does not exist
import android.content.pm.ResolveInfo;
                         ^
Main.java:39: error: package android.content.pm does not exist
import android.content.pm.ServiceInfo;
                         ^
Main.java:40: error: package android.content.pm.PackageManager does not exist
import android.content.pm.PackageManager.NameNotFoundException;
                                        ^
Main.java:41: error: package android.content.pm does not exist
import android.content.pm.UserInfo;
                         ^
Main.java:42: error: package android.content.res does not exist
import android.content.res.Resources;
                          ^
Main.java:43: error: package android.os does not exist
import android.os.Binder;
                 ^
Main.java:44: error: package android.os does not exist
import android.os.Bundle;
                 ^
Main.java:45: error: package android.os does not exist
import android.os.Environment;
                 ^
Main.java:46: error: package android.os does not exist
import android.os.FileUtils;
                 ^
Main.java:47: error: package android.os does not exist
import android.os.IBinder;
                 ^
Main.java:48: error: package android.os does not exist
import android.os.IRemoteCallback;
                 ^
Main.java:49: error: package android.os does not exist
import android.os.RemoteException;
                 ^
Main.java:50: error: package android.os does not exist
import android.os.FileObserver;
                 ^
Main.java:51: error: package android.os does not exist
import android.os.ParcelFileDescriptor;
                 ^
Main.java:52: error: package android.os does not exist
import android.os.RemoteCallbackList;
                 ^
Main.java:53: error: package android.os does not exist
import android.os.SELinux;
                 ^
Main.java:54: error: package android.os does not exist
import android.os.ServiceManager;
                 ^
Main.java:55: error: package android.os does not exist
import android.os.SystemClock;
                 ^
Main.java:56: error: package android.os does not exist
import android.os.UserHandle;
                 ^
Main.java:57: error: package android.os does not exist
import android.os.UserManager;
                 ^
Main.java:58: error: package android.service.wallpaper does not exist
import android.service.wallpaper.IWallpaperConnection;
                                ^
Main.java:59: error: package android.service.wallpaper does not exist
import android.service.wallpaper.IWallpaperEngine;
                                ^
Main.java:60: error: package android.service.wallpaper does not exist
import android.service.wallpaper.IWallpaperService;
                                ^
Main.java:61: error: package android.service.wallpaper does not exist
import android.service.wallpaper.WallpaperService;
                                ^
Main.java:62: error: package android.util does not exist
import android.util.Slog;
                   ^
Main.java:63: error: package android.util does not exist
import android.util.SparseArray;
                   ^
Main.java:64: error: package android.util does not exist
import android.util.Xml;
                   ^
Main.java:65: error: package android.view does not exist
import android.view.Display;
                   ^
Main.java:66: error: package android.view does not exist
import android.view.IWindowManager;
                   ^
Main.java:67: error: package android.view does not exist
import android.view.WindowManager;
                   ^
Main.java:79: error: package org.xmlpull.v1 does not exist
import org.xmlpull.v1.XmlPullParser;
                     ^
Main.java:80: error: package org.xmlpull.v1 does not exist
import org.xmlpull.v1.XmlPullParserException;
                     ^
Main.java:81: error: package org.xmlpull.v1 does not exist
import org.xmlpull.v1.XmlSerializer;
                     ^
Main.java:83: error: package com.android.internal.content does not exist
import com.android.internal.content.PackageMonitor;
                                   ^
Main.java:84: error: package com.android.internal.util does not exist
import com.android.internal.util.FastXmlSerializer;
                                ^
Main.java:85: error: package com.android.internal.util does not exist
import com.android.internal.util.JournaledFile;
                                ^
Main.java:87: error: package IWallpaperManager does not exist
class WallpaperManagerService extends IWallpaperManager.Stub {
                                                       ^
Main.java:105: error: cannot find symbol
    static final ComponentName IMAGE_WALLPAPER = new ComponentName("com.android.systemui",
                 ^
  symbol:   class ComponentName
  location: class WallpaperManagerService
Main.java:157: error: cannot find symbol
    final Context mContext;
          ^
  symbol:   class Context
  location: class WallpaperManagerService
Main.java:158: error: cannot find symbol
    final IWindowManager mIWindowManager;
          ^
  symbol:   class IWindowManager
  location: class WallpaperManagerService
Main.java:159: error: cannot find symbol
    final IPackageManager mIPackageManager;
          ^
  symbol:   class IPackageManager
  location: class WallpaperManagerService
Main.java:298: error: cannot find symbol
    class MyPackageMonitor extends PackageMonitor {
                                   ^
  symbol:   class PackageMonitor
  location: class WallpaperManagerService
Main.java:163: error: cannot find symbol
    SparseArray<WallpaperData> mWallpaperMap = new SparseArray<WallpaperData>();
    ^
  symbol:   class SparseArray
  location: class WallpaperManagerService
Main.java:431: error: cannot find symbol
    public WallpaperManagerService(Context context) {
                                   ^
  symbol:   class Context
  location: class WallpaperManagerService
Main.java:532: error: cannot find symbol
    void switchUser(int userId, IRemoteCallback reply) {
                                ^
  symbol:   class IRemoteCallback
  location: class WallpaperManagerService
Main.java:550: error: cannot find symbol
    void switchWallpaper(WallpaperData wallpaper, IRemoteCallback reply) {
                                                  ^
  symbol:   class IRemoteCallback
  location: class WallpaperManagerService
Main.java:574: error: cannot find symbol
    void clearWallpaperLocked(boolean defaultFailed, int userId, IRemoteCallback reply) {
                                                                 ^
  symbol:   class IRemoteCallback
  location: class WallpaperManagerService
Main.java:634: error: cannot find symbol
    public void setDimensionHints(int width, int height) throws RemoteException {
                                                                ^
  symbol:   class RemoteException
  location: class WallpaperManagerService
Main.java:665: error: cannot find symbol
    public int getWidthHint() throws RemoteException {
                                     ^
  symbol:   class RemoteException
  location: class WallpaperManagerService
Main.java:672: error: cannot find symbol
    public int getHeightHint() throws RemoteException {
                                      ^
  symbol:   class RemoteException
  location: class WallpaperManagerService
Main.java:679: error: cannot find symbol
    public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
                                             ^
  symbol:   class IWallpaperManagerCallback
  location: class WallpaperManagerService
Main.java:680: error: cannot find symbol
            Bundle outParams) {
            ^
  symbol:   class Bundle
  location: class WallpaperManagerService
Main.java:679: error: cannot find symbol
    public ParcelFileDescriptor getWallpaper(IWallpaperManagerCallback cb,
           ^
  symbol:   class ParcelFileDescriptor
  location: class WallpaperManagerService
Main.java:711: error: cannot find symbol
    public WallpaperInfo getWallpaperInfo() {
           ^
  symbol:   class WallpaperInfo
  location: class WallpaperManagerService
Main.java:722: error: cannot find symbol
    public ParcelFileDescriptor setWallpaper(String name) {
           ^
  symbol:   class ParcelFileDescriptor
  location: class WallpaperManagerService
Main.java:744: error: cannot find symbol
    ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {
    ^
  symbol:   class ParcelFileDescriptor
  location: class WallpaperManagerService
Main.java:769: error: cannot find symbol
    public void setWallpaperComponent(ComponentName name) {
                                      ^
  symbol:   class ComponentName
  location: class WallpaperManagerService
Main.java:788: error: cannot find symbol
    boolean bindWallpaperComponentLocked(ComponentName componentName, boolean force,
                                         ^
  symbol:   class ComponentName
  location: class WallpaperManagerService
Main.java:789: error: cannot find symbol
            boolean fromUser, WallpaperData wallpaper, IRemoteCallback reply) {
                                                       ^
  symbol:   class IRemoteCallback
  location: class WallpaperManagerService
Main.java:213: error: package IWallpaperConnection does not exist
    class WallpaperConnection extends IWallpaperConnection.Stub
                                                          ^
Main.java:214: error: cannot find symbol
            implements ServiceConnection {
                       ^
  symbol:   class ServiceConnection
  location: class WallpaperManagerService
Main.java:998: error: cannot find symbol
    private static JournaledFile makeJournaledFile(int userId) {
                   ^
  symbol:   class JournaledFile
  location: class WallpaperManagerService
Main.java:356: error: cannot find symbol
        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
                                         ^
  symbol:   class Intent
  location: class WallpaperManagerService.MyPackageMonitor
Main.java:186: error: cannot find symbol
        ComponentName wallpaperComponent;
        ^
  symbol:   class ComponentName
  location: class WallpaperData
Main.java:191: error: cannot find symbol
        ComponentName nextWallpaperComponent;
        ^
  symbol:   class ComponentName
  location: class WallpaperData
Main.java:114: error: cannot find symbol
    private class WallpaperObserver extends FileObserver {
                                            ^
  symbol:   class FileObserver
  location: class WallpaperManagerService
Main.java:201: error: cannot find symbol
        private RemoteCallbackList<IWallpaperManagerCallback> callbacks
                ^
  symbol:   class RemoteCallbackList
  location: class WallpaperData
Main.java:201: error: cannot find symbol
        private RemoteCallbackList<IWallpaperManagerCallback> callbacks
                                   ^
  symbol:   class IWallpaperManagerCallback
  location: class WallpaperData
Main.java:215: error: cannot find symbol
        final WallpaperInfo mInfo;
              ^
  symbol:   class WallpaperInfo
  location: class WallpaperManagerService.WallpaperConnection
Main.java:216: error: cannot find symbol
        final Binder mToken = new Binder();
              ^
  symbol:   class Binder
  location: class WallpaperManagerService.WallpaperConnection
Main.java:217: error: cannot find symbol
        IWallpaperService mService;
        ^
  symbol:   class IWallpaperService
  location: class WallpaperManagerService.WallpaperConnection
Main.java:218: error: cannot find symbol
        IWallpaperEngine mEngine;
        ^
  symbol:   class IWallpaperEngine
  location: class WallpaperManagerService.WallpaperConnection
Main.java:220: error: cannot find symbol
        IRemoteCallback mReply;
        ^
  symbol:   class IRemoteCallback
  location: class WallpaperManagerService.WallpaperConnection
Main.java:222: error: cannot find symbol
        public WallpaperConnection(WallpaperInfo info, WallpaperData wallpaper) {
                                   ^
  symbol:   class WallpaperInfo
  location: class WallpaperManagerService.WallpaperConnection
Main.java:228: error: cannot find symbol
        public void onServiceConnected(ComponentName name, IBinder service) {
                                       ^
  symbol:   class ComponentName
  location: class WallpaperManagerService.WallpaperConnection
Main.java:228: error: cannot find symbol
        public void onServiceConnected(ComponentName name, IBinder service) {
                                                           ^
  symbol:   class IBinder
  location: class WallpaperManagerService.WallpaperConnection
Main.java:244: error: cannot find symbol
        public void onServiceDisconnected(ComponentName name) {
                                          ^
  symbol:   class ComponentName
  location: class WallpaperManagerService.WallpaperConnection
Main.java:266: error: cannot find symbol
        public void attachEngine(IWallpaperEngine engine) {
                                 ^
  symbol:   class IWallpaperEngine
  location: class WallpaperManagerService.WallpaperConnection
Main.java:273: error: cannot find symbol
        public void engineShown(IWallpaperEngine engine) {
                                ^
  symbol:   class IWallpaperEngine
  location: class WallpaperManagerService.WallpaperConnection
Main.java:288: error: cannot find symbol
        public ParcelFileDescriptor setWallpaper(String name) {
               ^
  symbol:   class ParcelFileDescriptor
  location: class WallpaperManagerService.WallpaperConnection
Main.java:105: error: cannot find symbol
    static final ComponentName IMAGE_WALLPAPER = new ComponentName("com.android.systemui",
                                                     ^
  symbol:   class ComponentName
  location: class WallpaperManagerService
Main.java:122: error: cannot find symbol
                    CLOSE_WRITE | DELETE | DELETE_SELF);
                    ^
  symbol:   variable CLOSE_WRITE
  location: class WallpaperManagerService.WallpaperObserver
100 errors
stdout
Standard output is empty