/services/java/com/android/server/BackupManagerService.java

https://github.com/aizuzi/platform_frameworks_base · Java · 6288 lines · 4725 code · 698 blank · 865 comment · 1000 complexity · 7a00f18c337f24c4bb4331b40a664d70 MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  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. package com.android.server;
  17. import android.app.ActivityManagerNative;
  18. import android.app.AlarmManager;
  19. import android.app.AppGlobals;
  20. import android.app.IActivityManager;
  21. import android.app.IApplicationThread;
  22. import android.app.IBackupAgent;
  23. import android.app.PendingIntent;
  24. import android.app.backup.BackupAgent;
  25. import android.app.backup.BackupDataOutput;
  26. import android.app.backup.FullBackup;
  27. import android.app.backup.RestoreSet;
  28. import android.app.backup.IBackupManager;
  29. import android.app.backup.IFullBackupRestoreObserver;
  30. import android.app.backup.IRestoreObserver;
  31. import android.app.backup.IRestoreSession;
  32. import android.content.ActivityNotFoundException;
  33. import android.content.BroadcastReceiver;
  34. import android.content.ComponentName;
  35. import android.content.ContentResolver;
  36. import android.content.Context;
  37. import android.content.Intent;
  38. import android.content.IntentFilter;
  39. import android.content.ServiceConnection;
  40. import android.content.pm.ApplicationInfo;
  41. import android.content.pm.IPackageDataObserver;
  42. import android.content.pm.IPackageDeleteObserver;
  43. import android.content.pm.IPackageInstallObserver;
  44. import android.content.pm.IPackageManager;
  45. import android.content.pm.PackageInfo;
  46. import android.content.pm.PackageManager;
  47. import android.content.pm.ResolveInfo;
  48. import android.content.pm.ServiceInfo;
  49. import android.content.pm.Signature;
  50. import android.content.pm.PackageManager.NameNotFoundException;
  51. import android.database.ContentObserver;
  52. import android.net.Uri;
  53. import android.os.Binder;
  54. import android.os.Build;
  55. import android.os.Bundle;
  56. import android.os.Environment;
  57. import android.os.Handler;
  58. import android.os.HandlerThread;
  59. import android.os.IBinder;
  60. import android.os.Looper;
  61. import android.os.Message;
  62. import android.os.ParcelFileDescriptor;
  63. import android.os.PowerManager;
  64. import android.os.Process;
  65. import android.os.RemoteException;
  66. import android.os.SELinux;
  67. import android.os.ServiceManager;
  68. import android.os.SystemClock;
  69. import android.os.UserHandle;
  70. import android.os.WorkSource;
  71. import android.os.Environment.UserEnvironment;
  72. import android.os.storage.IMountService;
  73. import android.provider.Settings;
  74. import android.util.EventLog;
  75. import android.util.Log;
  76. import android.util.Slog;
  77. import android.util.SparseArray;
  78. import android.util.StringBuilderPrinter;
  79. import com.android.internal.backup.BackupConstants;
  80. import com.android.internal.backup.IBackupTransport;
  81. import com.android.internal.backup.IObbBackupService;
  82. import com.android.server.EventLogTags;
  83. import com.android.server.PackageManagerBackupAgent.Metadata;
  84. import java.io.BufferedInputStream;
  85. import java.io.BufferedOutputStream;
  86. import java.io.ByteArrayOutputStream;
  87. import java.io.DataInputStream;
  88. import java.io.DataOutputStream;
  89. import java.io.EOFException;
  90. import java.io.File;
  91. import java.io.FileDescriptor;
  92. import java.io.FileInputStream;
  93. import java.io.FileNotFoundException;
  94. import java.io.FileOutputStream;
  95. import java.io.IOException;
  96. import java.io.InputStream;
  97. import java.io.OutputStream;
  98. import java.io.PrintWriter;
  99. import java.io.RandomAccessFile;
  100. import java.security.InvalidAlgorithmParameterException;
  101. import java.security.InvalidKeyException;
  102. import java.security.Key;
  103. import java.security.NoSuchAlgorithmException;
  104. import java.security.SecureRandom;
  105. import java.security.spec.InvalidKeySpecException;
  106. import java.security.spec.KeySpec;
  107. import java.text.SimpleDateFormat;
  108. import java.util.ArrayList;
  109. import java.util.Arrays;
  110. import java.util.Date;
  111. import java.util.HashMap;
  112. import java.util.HashSet;
  113. import java.util.List;
  114. import java.util.Map;
  115. import java.util.Random;
  116. import java.util.Set;
  117. import java.util.concurrent.atomic.AtomicBoolean;
  118. import java.util.zip.Deflater;
  119. import java.util.zip.DeflaterOutputStream;
  120. import java.util.zip.InflaterInputStream;
  121. import javax.crypto.BadPaddingException;
  122. import javax.crypto.Cipher;
  123. import javax.crypto.CipherInputStream;
  124. import javax.crypto.CipherOutputStream;
  125. import javax.crypto.IllegalBlockSizeException;
  126. import javax.crypto.NoSuchPaddingException;
  127. import javax.crypto.SecretKey;
  128. import javax.crypto.SecretKeyFactory;
  129. import javax.crypto.spec.IvParameterSpec;
  130. import javax.crypto.spec.PBEKeySpec;
  131. import javax.crypto.spec.SecretKeySpec;
  132. class BackupManagerService extends IBackupManager.Stub {
  133. private static final String TAG = "BackupManagerService";
  134. private static final boolean DEBUG = true;
  135. private static final boolean MORE_DEBUG = false;
  136. // Historical and current algorithm names
  137. static final String PBKDF_CURRENT = "PBKDF2WithHmacSHA1";
  138. static final String PBKDF_FALLBACK = "PBKDF2WithHmacSHA1And8bit";
  139. // Name and current contents version of the full-backup manifest file
  140. static final String BACKUP_MANIFEST_FILENAME = "_manifest";
  141. static final int BACKUP_MANIFEST_VERSION = 1;
  142. static final String BACKUP_FILE_HEADER_MAGIC = "ANDROID BACKUP\n";
  143. static final int BACKUP_FILE_VERSION = 2;
  144. static final int BACKUP_PW_FILE_VERSION = 2;
  145. static final boolean COMPRESS_FULL_BACKUPS = true; // should be true in production
  146. static final String SHARED_BACKUP_AGENT_PACKAGE = "com.android.sharedstoragebackup";
  147. static final String SERVICE_ACTION_TRANSPORT_HOST = "android.backup.TRANSPORT_HOST";
  148. // How often we perform a backup pass. Privileged external callers can
  149. // trigger an immediate pass.
  150. private static final long BACKUP_INTERVAL = AlarmManager.INTERVAL_HOUR;
  151. // Random variation in backup scheduling time to avoid server load spikes
  152. private static final int FUZZ_MILLIS = 5 * 60 * 1000;
  153. // The amount of time between the initial provisioning of the device and
  154. // the first backup pass.
  155. private static final long FIRST_BACKUP_INTERVAL = 12 * AlarmManager.INTERVAL_HOUR;
  156. // Retry interval for clear/init when the transport is unavailable
  157. private static final long TRANSPORT_RETRY_INTERVAL = 1 * AlarmManager.INTERVAL_HOUR;
  158. private static final String RUN_BACKUP_ACTION = "android.app.backup.intent.RUN";
  159. private static final String RUN_INITIALIZE_ACTION = "android.app.backup.intent.INIT";
  160. private static final String RUN_CLEAR_ACTION = "android.app.backup.intent.CLEAR";
  161. private static final int MSG_RUN_BACKUP = 1;
  162. private static final int MSG_RUN_FULL_BACKUP = 2;
  163. private static final int MSG_RUN_RESTORE = 3;
  164. private static final int MSG_RUN_CLEAR = 4;
  165. private static final int MSG_RUN_INITIALIZE = 5;
  166. private static final int MSG_RUN_GET_RESTORE_SETS = 6;
  167. private static final int MSG_TIMEOUT = 7;
  168. private static final int MSG_RESTORE_TIMEOUT = 8;
  169. private static final int MSG_FULL_CONFIRMATION_TIMEOUT = 9;
  170. private static final int MSG_RUN_FULL_RESTORE = 10;
  171. private static final int MSG_RETRY_INIT = 11;
  172. private static final int MSG_RETRY_CLEAR = 12;
  173. // backup task state machine tick
  174. static final int MSG_BACKUP_RESTORE_STEP = 20;
  175. static final int MSG_OP_COMPLETE = 21;
  176. // Timeout interval for deciding that a bind or clear-data has taken too long
  177. static final long TIMEOUT_INTERVAL = 10 * 1000;
  178. // Timeout intervals for agent backup & restore operations
  179. static final long TIMEOUT_BACKUP_INTERVAL = 30 * 1000;
  180. static final long TIMEOUT_FULL_BACKUP_INTERVAL = 5 * 60 * 1000;
  181. static final long TIMEOUT_SHARED_BACKUP_INTERVAL = 30 * 60 * 1000;
  182. static final long TIMEOUT_RESTORE_INTERVAL = 60 * 1000;
  183. // User confirmation timeout for a full backup/restore operation. It's this long in
  184. // order to give them time to enter the backup password.
  185. static final long TIMEOUT_FULL_CONFIRMATION = 60 * 1000;
  186. private Context mContext;
  187. private PackageManager mPackageManager;
  188. IPackageManager mPackageManagerBinder;
  189. private IActivityManager mActivityManager;
  190. private PowerManager mPowerManager;
  191. private AlarmManager mAlarmManager;
  192. private IMountService mMountService;
  193. IBackupManager mBackupManagerBinder;
  194. boolean mEnabled; // access to this is synchronized on 'this'
  195. boolean mProvisioned;
  196. boolean mAutoRestore;
  197. PowerManager.WakeLock mWakelock;
  198. HandlerThread mHandlerThread;
  199. BackupHandler mBackupHandler;
  200. PendingIntent mRunBackupIntent, mRunInitIntent;
  201. BroadcastReceiver mRunBackupReceiver, mRunInitReceiver;
  202. // map UIDs to the set of participating packages under that UID
  203. final SparseArray<HashSet<String>> mBackupParticipants
  204. = new SparseArray<HashSet<String>>();
  205. // set of backup services that have pending changes
  206. class BackupRequest {
  207. public String packageName;
  208. BackupRequest(String pkgName) {
  209. packageName = pkgName;
  210. }
  211. public String toString() {
  212. return "BackupRequest{pkg=" + packageName + "}";
  213. }
  214. }
  215. // Backups that we haven't started yet. Keys are package names.
  216. HashMap<String,BackupRequest> mPendingBackups
  217. = new HashMap<String,BackupRequest>();
  218. // Pseudoname that we use for the Package Manager metadata "package"
  219. static final String PACKAGE_MANAGER_SENTINEL = "@pm@";
  220. // locking around the pending-backup management
  221. final Object mQueueLock = new Object();
  222. // The thread performing the sequence of queued backups binds to each app's agent
  223. // in succession. Bind notifications are asynchronously delivered through the
  224. // Activity Manager; use this lock object to signal when a requested binding has
  225. // completed.
  226. final Object mAgentConnectLock = new Object();
  227. IBackupAgent mConnectedAgent;
  228. volatile boolean mBackupRunning;
  229. volatile boolean mConnecting;
  230. volatile long mLastBackupPass;
  231. volatile long mNextBackupPass;
  232. // For debugging, we maintain a progress trace of operations during backup
  233. static final boolean DEBUG_BACKUP_TRACE = true;
  234. final List<String> mBackupTrace = new ArrayList<String>();
  235. // A similar synchronization mechanism around clearing apps' data for restore
  236. final Object mClearDataLock = new Object();
  237. volatile boolean mClearingData;
  238. // Transport bookkeeping
  239. final HashMap<String,String> mTransportNames
  240. = new HashMap<String,String>(); // component name -> registration name
  241. final HashMap<String,IBackupTransport> mTransports
  242. = new HashMap<String,IBackupTransport>(); // registration name -> binder
  243. final ArrayList<TransportConnection> mTransportConnections
  244. = new ArrayList<TransportConnection>();
  245. String mCurrentTransport;
  246. ActiveRestoreSession mActiveRestoreSession;
  247. // Watch the device provisioning operation during setup
  248. ContentObserver mProvisionedObserver;
  249. class ProvisionedObserver extends ContentObserver {
  250. public ProvisionedObserver(Handler handler) {
  251. super(handler);
  252. }
  253. public void onChange(boolean selfChange) {
  254. final boolean wasProvisioned = mProvisioned;
  255. final boolean isProvisioned = deviceIsProvisioned();
  256. // latch: never unprovision
  257. mProvisioned = wasProvisioned || isProvisioned;
  258. if (MORE_DEBUG) {
  259. Slog.d(TAG, "Provisioning change: was=" + wasProvisioned
  260. + " is=" + isProvisioned + " now=" + mProvisioned);
  261. }
  262. synchronized (mQueueLock) {
  263. if (mProvisioned && !wasProvisioned && mEnabled) {
  264. // we're now good to go, so start the backup alarms
  265. if (MORE_DEBUG) Slog.d(TAG, "Now provisioned, so starting backups");
  266. startBackupAlarmsLocked(FIRST_BACKUP_INTERVAL);
  267. }
  268. }
  269. }
  270. }
  271. class RestoreGetSetsParams {
  272. public IBackupTransport transport;
  273. public ActiveRestoreSession session;
  274. public IRestoreObserver observer;
  275. RestoreGetSetsParams(IBackupTransport _transport, ActiveRestoreSession _session,
  276. IRestoreObserver _observer) {
  277. transport = _transport;
  278. session = _session;
  279. observer = _observer;
  280. }
  281. }
  282. class RestoreParams {
  283. public IBackupTransport transport;
  284. public String dirName;
  285. public IRestoreObserver observer;
  286. public long token;
  287. public PackageInfo pkgInfo;
  288. public int pmToken; // in post-install restore, the PM's token for this transaction
  289. public boolean needFullBackup;
  290. public String[] filterSet;
  291. RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
  292. long _token, PackageInfo _pkg, int _pmToken, boolean _needFullBackup) {
  293. transport = _transport;
  294. dirName = _dirName;
  295. observer = _obs;
  296. token = _token;
  297. pkgInfo = _pkg;
  298. pmToken = _pmToken;
  299. needFullBackup = _needFullBackup;
  300. filterSet = null;
  301. }
  302. RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
  303. long _token, boolean _needFullBackup) {
  304. transport = _transport;
  305. dirName = _dirName;
  306. observer = _obs;
  307. token = _token;
  308. pkgInfo = null;
  309. pmToken = 0;
  310. needFullBackup = _needFullBackup;
  311. filterSet = null;
  312. }
  313. RestoreParams(IBackupTransport _transport, String _dirName, IRestoreObserver _obs,
  314. long _token, String[] _filterSet, boolean _needFullBackup) {
  315. transport = _transport;
  316. dirName = _dirName;
  317. observer = _obs;
  318. token = _token;
  319. pkgInfo = null;
  320. pmToken = 0;
  321. needFullBackup = _needFullBackup;
  322. filterSet = _filterSet;
  323. }
  324. }
  325. class ClearParams {
  326. public IBackupTransport transport;
  327. public PackageInfo packageInfo;
  328. ClearParams(IBackupTransport _transport, PackageInfo _info) {
  329. transport = _transport;
  330. packageInfo = _info;
  331. }
  332. }
  333. class ClearRetryParams {
  334. public String transportName;
  335. public String packageName;
  336. ClearRetryParams(String transport, String pkg) {
  337. transportName = transport;
  338. packageName = pkg;
  339. }
  340. }
  341. class FullParams {
  342. public ParcelFileDescriptor fd;
  343. public final AtomicBoolean latch;
  344. public IFullBackupRestoreObserver observer;
  345. public String curPassword; // filled in by the confirmation step
  346. public String encryptPassword;
  347. FullParams() {
  348. latch = new AtomicBoolean(false);
  349. }
  350. }
  351. class FullBackupParams extends FullParams {
  352. public boolean includeApks;
  353. public boolean includeObbs;
  354. public boolean includeShared;
  355. public boolean allApps;
  356. public boolean includeSystem;
  357. public String[] packages;
  358. FullBackupParams(ParcelFileDescriptor output, boolean saveApks, boolean saveObbs,
  359. boolean saveShared, boolean doAllApps, boolean doSystem, String[] pkgList) {
  360. fd = output;
  361. includeApks = saveApks;
  362. includeObbs = saveObbs;
  363. includeShared = saveShared;
  364. allApps = doAllApps;
  365. includeSystem = doSystem;
  366. packages = pkgList;
  367. }
  368. }
  369. class FullRestoreParams extends FullParams {
  370. FullRestoreParams(ParcelFileDescriptor input) {
  371. fd = input;
  372. }
  373. }
  374. // Bookkeeping of in-flight operations for timeout etc. purposes. The operation
  375. // token is the index of the entry in the pending-operations list.
  376. static final int OP_PENDING = 0;
  377. static final int OP_ACKNOWLEDGED = 1;
  378. static final int OP_TIMEOUT = -1;
  379. class Operation {
  380. public int state;
  381. public BackupRestoreTask callback;
  382. Operation(int initialState, BackupRestoreTask callbackObj) {
  383. state = initialState;
  384. callback = callbackObj;
  385. }
  386. }
  387. final SparseArray<Operation> mCurrentOperations = new SparseArray<Operation>();
  388. final Object mCurrentOpLock = new Object();
  389. final Random mTokenGenerator = new Random();
  390. final SparseArray<FullParams> mFullConfirmations = new SparseArray<FullParams>();
  391. // Where we keep our journal files and other bookkeeping
  392. File mBaseStateDir;
  393. File mDataDir;
  394. File mJournalDir;
  395. File mJournal;
  396. // Backup password, if any, and the file where it's saved. What is stored is not the
  397. // password text itself; it's the result of a PBKDF2 hash with a randomly chosen (but
  398. // persisted) salt. Validation is performed by running the challenge text through the
  399. // same PBKDF2 cycle with the persisted salt; if the resulting derived key string matches
  400. // the saved hash string, then the challenge text matches the originally supplied
  401. // password text.
  402. private final SecureRandom mRng = new SecureRandom();
  403. private String mPasswordHash;
  404. private File mPasswordHashFile;
  405. private int mPasswordVersion;
  406. private File mPasswordVersionFile;
  407. private byte[] mPasswordSalt;
  408. // Configuration of PBKDF2 that we use for generating pw hashes and intermediate keys
  409. static final int PBKDF2_HASH_ROUNDS = 10000;
  410. static final int PBKDF2_KEY_SIZE = 256; // bits
  411. static final int PBKDF2_SALT_SIZE = 512; // bits
  412. static final String ENCRYPTION_ALGORITHM_NAME = "AES-256";
  413. // Keep a log of all the apps we've ever backed up, and what the
  414. // dataset tokens are for both the current backup dataset and
  415. // the ancestral dataset.
  416. private File mEverStored;
  417. HashSet<String> mEverStoredApps = new HashSet<String>();
  418. static final int CURRENT_ANCESTRAL_RECORD_VERSION = 1; // increment when the schema changes
  419. File mTokenFile;
  420. Set<String> mAncestralPackages = null;
  421. long mAncestralToken = 0;
  422. long mCurrentToken = 0;
  423. // Persistently track the need to do a full init
  424. static final String INIT_SENTINEL_FILE_NAME = "_need_init_";
  425. HashSet<String> mPendingInits = new HashSet<String>(); // transport names
  426. // Utility: build a new random integer token
  427. int generateToken() {
  428. int token;
  429. do {
  430. synchronized (mTokenGenerator) {
  431. token = mTokenGenerator.nextInt();
  432. }
  433. } while (token < 0);
  434. return token;
  435. }
  436. // ----- Asynchronous backup/restore handler thread -----
  437. private class BackupHandler extends Handler {
  438. public BackupHandler(Looper looper) {
  439. super(looper);
  440. }
  441. public void handleMessage(Message msg) {
  442. switch (msg.what) {
  443. case MSG_RUN_BACKUP:
  444. {
  445. mLastBackupPass = System.currentTimeMillis();
  446. mNextBackupPass = mLastBackupPass + BACKUP_INTERVAL;
  447. IBackupTransport transport = getTransport(mCurrentTransport);
  448. if (transport == null) {
  449. Slog.v(TAG, "Backup requested but no transport available");
  450. synchronized (mQueueLock) {
  451. mBackupRunning = false;
  452. }
  453. mWakelock.release();
  454. break;
  455. }
  456. // snapshot the pending-backup set and work on that
  457. ArrayList<BackupRequest> queue = new ArrayList<BackupRequest>();
  458. File oldJournal = mJournal;
  459. synchronized (mQueueLock) {
  460. // Do we have any work to do? Construct the work queue
  461. // then release the synchronization lock to actually run
  462. // the backup.
  463. if (mPendingBackups.size() > 0) {
  464. for (BackupRequest b: mPendingBackups.values()) {
  465. queue.add(b);
  466. }
  467. if (DEBUG) Slog.v(TAG, "clearing pending backups");
  468. mPendingBackups.clear();
  469. // Start a new backup-queue journal file too
  470. mJournal = null;
  471. }
  472. }
  473. // At this point, we have started a new journal file, and the old
  474. // file identity is being passed to the backup processing task.
  475. // When it completes successfully, that old journal file will be
  476. // deleted. If we crash prior to that, the old journal is parsed
  477. // at next boot and the journaled requests fulfilled.
  478. boolean staged = true;
  479. if (queue.size() > 0) {
  480. // Spin up a backup state sequence and set it running
  481. try {
  482. String dirName = transport.transportDirName();
  483. PerformBackupTask pbt = new PerformBackupTask(transport, dirName,
  484. queue, oldJournal);
  485. Message pbtMessage = obtainMessage(MSG_BACKUP_RESTORE_STEP, pbt);
  486. sendMessage(pbtMessage);
  487. } catch (RemoteException e) {
  488. // unable to ask the transport its dir name -- transient failure, since
  489. // the above check succeeded. Try again next time.
  490. Slog.e(TAG, "Transport became unavailable attempting backup");
  491. staged = false;
  492. }
  493. } else {
  494. Slog.v(TAG, "Backup requested but nothing pending");
  495. staged = false;
  496. }
  497. if (!staged) {
  498. // if we didn't actually hand off the wakelock, rewind until next time
  499. synchronized (mQueueLock) {
  500. mBackupRunning = false;
  501. }
  502. mWakelock.release();
  503. }
  504. break;
  505. }
  506. case MSG_BACKUP_RESTORE_STEP:
  507. {
  508. try {
  509. BackupRestoreTask task = (BackupRestoreTask) msg.obj;
  510. if (MORE_DEBUG) Slog.v(TAG, "Got next step for " + task + ", executing");
  511. task.execute();
  512. } catch (ClassCastException e) {
  513. Slog.e(TAG, "Invalid backup task in flight, obj=" + msg.obj);
  514. }
  515. break;
  516. }
  517. case MSG_OP_COMPLETE:
  518. {
  519. try {
  520. BackupRestoreTask task = (BackupRestoreTask) msg.obj;
  521. task.operationComplete();
  522. } catch (ClassCastException e) {
  523. Slog.e(TAG, "Invalid completion in flight, obj=" + msg.obj);
  524. }
  525. break;
  526. }
  527. case MSG_RUN_FULL_BACKUP:
  528. {
  529. // TODO: refactor full backup to be a looper-based state machine
  530. // similar to normal backup/restore.
  531. FullBackupParams params = (FullBackupParams)msg.obj;
  532. PerformFullBackupTask task = new PerformFullBackupTask(params.fd,
  533. params.observer, params.includeApks, params.includeObbs,
  534. params.includeShared, params.curPassword, params.encryptPassword,
  535. params.allApps, params.includeSystem, params.packages, params.latch);
  536. (new Thread(task)).start();
  537. break;
  538. }
  539. case MSG_RUN_RESTORE:
  540. {
  541. RestoreParams params = (RestoreParams)msg.obj;
  542. Slog.d(TAG, "MSG_RUN_RESTORE observer=" + params.observer);
  543. PerformRestoreTask task = new PerformRestoreTask(
  544. params.transport, params.dirName, params.observer,
  545. params.token, params.pkgInfo, params.pmToken,
  546. params.needFullBackup, params.filterSet);
  547. Message restoreMsg = obtainMessage(MSG_BACKUP_RESTORE_STEP, task);
  548. sendMessage(restoreMsg);
  549. break;
  550. }
  551. case MSG_RUN_FULL_RESTORE:
  552. {
  553. // TODO: refactor full restore to be a looper-based state machine
  554. // similar to normal backup/restore.
  555. FullRestoreParams params = (FullRestoreParams)msg.obj;
  556. PerformFullRestoreTask task = new PerformFullRestoreTask(params.fd,
  557. params.curPassword, params.encryptPassword,
  558. params.observer, params.latch);
  559. (new Thread(task)).start();
  560. break;
  561. }
  562. case MSG_RUN_CLEAR:
  563. {
  564. ClearParams params = (ClearParams)msg.obj;
  565. (new PerformClearTask(params.transport, params.packageInfo)).run();
  566. break;
  567. }
  568. case MSG_RETRY_CLEAR:
  569. {
  570. // reenqueues if the transport remains unavailable
  571. ClearRetryParams params = (ClearRetryParams)msg.obj;
  572. clearBackupData(params.transportName, params.packageName);
  573. break;
  574. }
  575. case MSG_RUN_INITIALIZE:
  576. {
  577. HashSet<String> queue;
  578. // Snapshot the pending-init queue and work on that
  579. synchronized (mQueueLock) {
  580. queue = new HashSet<String>(mPendingInits);
  581. mPendingInits.clear();
  582. }
  583. (new PerformInitializeTask(queue)).run();
  584. break;
  585. }
  586. case MSG_RETRY_INIT:
  587. {
  588. synchronized (mQueueLock) {
  589. recordInitPendingLocked(msg.arg1 != 0, (String)msg.obj);
  590. mAlarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
  591. mRunInitIntent);
  592. }
  593. break;
  594. }
  595. case MSG_RUN_GET_RESTORE_SETS:
  596. {
  597. // Like other async operations, this is entered with the wakelock held
  598. RestoreSet[] sets = null;
  599. RestoreGetSetsParams params = (RestoreGetSetsParams)msg.obj;
  600. try {
  601. sets = params.transport.getAvailableRestoreSets();
  602. // cache the result in the active session
  603. synchronized (params.session) {
  604. params.session.mRestoreSets = sets;
  605. }
  606. if (sets == null) EventLog.writeEvent(EventLogTags.RESTORE_TRANSPORT_FAILURE);
  607. } catch (Exception e) {
  608. Slog.e(TAG, "Error from transport getting set list");
  609. } finally {
  610. if (params.observer != null) {
  611. try {
  612. params.observer.restoreSetsAvailable(sets);
  613. } catch (RemoteException re) {
  614. Slog.e(TAG, "Unable to report listing to observer");
  615. } catch (Exception e) {
  616. Slog.e(TAG, "Restore observer threw", e);
  617. }
  618. }
  619. // Done: reset the session timeout clock
  620. removeMessages(MSG_RESTORE_TIMEOUT);
  621. sendEmptyMessageDelayed(MSG_RESTORE_TIMEOUT, TIMEOUT_RESTORE_INTERVAL);
  622. mWakelock.release();
  623. }
  624. break;
  625. }
  626. case MSG_TIMEOUT:
  627. {
  628. handleTimeout(msg.arg1, msg.obj);
  629. break;
  630. }
  631. case MSG_RESTORE_TIMEOUT:
  632. {
  633. synchronized (BackupManagerService.this) {
  634. if (mActiveRestoreSession != null) {
  635. // Client app left the restore session dangling. We know that it
  636. // can't be in the middle of an actual restore operation because
  637. // the timeout is suspended while a restore is in progress. Clean
  638. // up now.
  639. Slog.w(TAG, "Restore session timed out; aborting");
  640. post(mActiveRestoreSession.new EndRestoreRunnable(
  641. BackupManagerService.this, mActiveRestoreSession));
  642. }
  643. }
  644. }
  645. case MSG_FULL_CONFIRMATION_TIMEOUT:
  646. {
  647. synchronized (mFullConfirmations) {
  648. FullParams params = mFullConfirmations.get(msg.arg1);
  649. if (params != null) {
  650. Slog.i(TAG, "Full backup/restore timed out waiting for user confirmation");
  651. // Release the waiter; timeout == completion
  652. signalFullBackupRestoreCompletion(params);
  653. // Remove the token from the set
  654. mFullConfirmations.delete(msg.arg1);
  655. // Report a timeout to the observer, if any
  656. if (params.observer != null) {
  657. try {
  658. params.observer.onTimeout();
  659. } catch (RemoteException e) {
  660. /* don't care if the app has gone away */
  661. }
  662. }
  663. } else {
  664. Slog.d(TAG, "couldn't find params for token " + msg.arg1);
  665. }
  666. }
  667. break;
  668. }
  669. }
  670. }
  671. }
  672. // ----- Debug-only backup operation trace -----
  673. void addBackupTrace(String s) {
  674. if (DEBUG_BACKUP_TRACE) {
  675. synchronized (mBackupTrace) {
  676. mBackupTrace.add(s);
  677. }
  678. }
  679. }
  680. void clearBackupTrace() {
  681. if (DEBUG_BACKUP_TRACE) {
  682. synchronized (mBackupTrace) {
  683. mBackupTrace.clear();
  684. }
  685. }
  686. }
  687. // ----- Main service implementation -----
  688. public BackupManagerService(Context context) {
  689. mContext = context;
  690. mPackageManager = context.getPackageManager();
  691. mPackageManagerBinder = AppGlobals.getPackageManager();
  692. mActivityManager = ActivityManagerNative.getDefault();
  693. mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
  694. mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
  695. mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
  696. mBackupManagerBinder = asInterface(asBinder());
  697. // spin up the backup/restore handler thread
  698. mHandlerThread = new HandlerThread("backup", Process.THREAD_PRIORITY_BACKGROUND);
  699. mHandlerThread.start();
  700. mBackupHandler = new BackupHandler(mHandlerThread.getLooper());
  701. // Set up our bookkeeping
  702. final ContentResolver resolver = context.getContentResolver();
  703. boolean areEnabled = Settings.Secure.getInt(resolver,
  704. Settings.Secure.BACKUP_ENABLED, 0) != 0;
  705. mProvisioned = Settings.Global.getInt(resolver,
  706. Settings.Global.DEVICE_PROVISIONED, 0) != 0;
  707. mAutoRestore = Settings.Secure.getInt(resolver,
  708. Settings.Secure.BACKUP_AUTO_RESTORE, 1) != 0;
  709. mProvisionedObserver = new ProvisionedObserver(mBackupHandler);
  710. resolver.registerContentObserver(
  711. Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
  712. false, mProvisionedObserver);
  713. // If Encrypted file systems is enabled or disabled, this call will return the
  714. // correct directory.
  715. mBaseStateDir = new File(Environment.getSecureDataDirectory(), "backup");
  716. mBaseStateDir.mkdirs();
  717. if (!SELinux.restorecon(mBaseStateDir)) {
  718. Slog.e(TAG, "SELinux restorecon failed on " + mBaseStateDir);
  719. }
  720. mDataDir = Environment.getDownloadCacheDirectory();
  721. mPasswordVersion = 1; // unless we hear otherwise
  722. mPasswordVersionFile = new File(mBaseStateDir, "pwversion");
  723. if (mPasswordVersionFile.exists()) {
  724. FileInputStream fin = null;
  725. DataInputStream in = null;
  726. try {
  727. fin = new FileInputStream(mPasswordVersionFile);
  728. in = new DataInputStream(fin);
  729. mPasswordVersion = in.readInt();
  730. } catch (IOException e) {
  731. Slog.e(TAG, "Unable to read backup pw version");
  732. } finally {
  733. try {
  734. if (in != null) in.close();
  735. if (fin != null) fin.close();
  736. } catch (IOException e) {
  737. Slog.w(TAG, "Error closing pw version files");
  738. }
  739. }
  740. }
  741. mPasswordHashFile = new File(mBaseStateDir, "pwhash");
  742. if (mPasswordHashFile.exists()) {
  743. FileInputStream fin = null;
  744. DataInputStream in = null;
  745. try {
  746. fin = new FileInputStream(mPasswordHashFile);
  747. in = new DataInputStream(new BufferedInputStream(fin));
  748. // integer length of the salt array, followed by the salt,
  749. // then the hex pw hash string
  750. int saltLen = in.readInt();
  751. byte[] salt = new byte[saltLen];
  752. in.readFully(salt);
  753. mPasswordHash = in.readUTF();
  754. mPasswordSalt = salt;
  755. } catch (IOException e) {
  756. Slog.e(TAG, "Unable to read saved backup pw hash");
  757. } finally {
  758. try {
  759. if (in != null) in.close();
  760. if (fin != null) fin.close();
  761. } catch (IOException e) {
  762. Slog.w(TAG, "Unable to close streams");
  763. }
  764. }
  765. }
  766. // Alarm receivers for scheduled backups & initialization operations
  767. mRunBackupReceiver = new RunBackupReceiver();
  768. IntentFilter filter = new IntentFilter();
  769. filter.addAction(RUN_BACKUP_ACTION);
  770. context.registerReceiver(mRunBackupReceiver, filter,
  771. android.Manifest.permission.BACKUP, null);
  772. mRunInitReceiver = new RunInitializeReceiver();
  773. filter = new IntentFilter();
  774. filter.addAction(RUN_INITIALIZE_ACTION);
  775. context.registerReceiver(mRunInitReceiver, filter,
  776. android.Manifest.permission.BACKUP, null);
  777. Intent backupIntent = new Intent(RUN_BACKUP_ACTION);
  778. backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
  779. mRunBackupIntent = PendingIntent.getBroadcast(context, MSG_RUN_BACKUP, backupIntent, 0);
  780. Intent initIntent = new Intent(RUN_INITIALIZE_ACTION);
  781. backupIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
  782. mRunInitIntent = PendingIntent.getBroadcast(context, MSG_RUN_INITIALIZE, initIntent, 0);
  783. // Set up the backup-request journaling
  784. mJournalDir = new File(mBaseStateDir, "pending");
  785. mJournalDir.mkdirs(); // creates mBaseStateDir along the way
  786. mJournal = null; // will be created on first use
  787. // Set up the various sorts of package tracking we do
  788. initPackageTracking();
  789. // Build our mapping of uid to backup client services. This implicitly
  790. // schedules a backup pass on the Package Manager metadata the first
  791. // time anything needs to be backed up.
  792. synchronized (mBackupParticipants) {
  793. addPackageParticipantsLocked(null);
  794. }
  795. // Set up our transport options and initialize the default transport
  796. // TODO: Don't create transports that we don't need to?
  797. mCurrentTransport = Settings.Secure.getString(context.getContentResolver(),
  798. Settings.Secure.BACKUP_TRANSPORT);
  799. if ("".equals(mCurrentTransport)) {
  800. mCurrentTransport = null;
  801. }
  802. if (DEBUG) Slog.v(TAG, "Starting with transport " + mCurrentTransport);
  803. // Find transport hosts and bind to their services
  804. Intent transportServiceIntent = new Intent(SERVICE_ACTION_TRANSPORT_HOST);
  805. List<ResolveInfo> hosts = mPackageManager.queryIntentServicesAsUser(
  806. transportServiceIntent, 0, UserHandle.USER_OWNER);
  807. if (DEBUG) {
  808. Slog.v(TAG, "Found transports: " + ((hosts == null) ? "null" : hosts.size()));
  809. }
  810. if (hosts != null) {
  811. if (MORE_DEBUG) {
  812. for (int i = 0; i < hosts.size(); i++) {
  813. ServiceInfo info = hosts.get(i).serviceInfo;
  814. Slog.v(TAG, " " + info.packageName + "/" + info.name);
  815. }
  816. }
  817. for (int i = 0; i < hosts.size(); i++) {
  818. try {
  819. ServiceInfo info = hosts.get(i).serviceInfo;
  820. PackageInfo packInfo = mPackageManager.getPackageInfo(info.packageName, 0);
  821. if ((packInfo.applicationInfo.flags & ApplicationInfo.FLAG_PRIVILEGED) != 0) {
  822. ComponentName svcName = new ComponentName(info.packageName, info.name);
  823. if (DEBUG) {
  824. Slog.i(TAG, "Binding to transport host " + svcName);
  825. }
  826. Intent intent = new Intent(transportServiceIntent);
  827. intent.setComponent(svcName);
  828. TransportConnection connection = new TransportConnection();
  829. mTransportConnections.add(connection);
  830. context.bindServiceAsUser(intent,
  831. connection, Context.BIND_AUTO_CREATE,
  832. UserHandle.OWNER);
  833. } else {
  834. Slog.w(TAG, "Transport package not privileged: " + info.packageName);
  835. }
  836. } catch (Exception e) {
  837. Slog.e(TAG, "Problem resolving transport service: " + e.getMessage());
  838. }
  839. }
  840. }
  841. // Now that we know about valid backup participants, parse any
  842. // leftover journal files into the pending backup set
  843. parseLeftoverJournals();
  844. // Power management
  845. mWakelock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*backup*");
  846. // Start the backup passes going
  847. setBackupEnabled(areEnabled);
  848. }
  849. private class RunBackupReceiver extends BroadcastReceiver {
  850. public void onReceive(Context context, Intent intent) {
  851. if (RUN_BACKUP_ACTION.equals(intent.getAction())) {
  852. synchronized (mQueueLock) {
  853. if (mPendingInits.size() > 0) {
  854. // If there are pending init operations, we process those
  855. // and then settle into the usual periodic backup schedule.
  856. if (DEBUG) Slog.v(TAG, "Init pending at scheduled backup");
  857. try {
  858. mAlarmManager.cancel(mRunInitIntent);
  859. mRunInitIntent.send();
  860. } catch (PendingIntent.CanceledException ce) {
  861. Slog.e(TAG, "Run init intent cancelled");
  862. // can't really do more than bail here
  863. }
  864. } else {
  865. // Don't run backups now if we're disabled or not yet
  866. // fully set up.
  867. if (mEnabled && mProvisioned) {
  868. if (!mBackupRunning) {
  869. if (DEBUG) Slog.v(TAG, "Running a backup pass");
  870. // Acquire the wakelock and pass it to the backup thread. it will
  871. // be released once backup concludes.
  872. mBackupRunning = true;
  873. mWakelock.acquire();
  874. Message msg = mBackupHandler.obtainMessage(MSG_RUN_BACKUP);
  875. mBackupHandler.sendMessage(msg);
  876. } else {
  877. Slog.i(TAG, "Backup time but one already running");
  878. }
  879. } else {
  880. Slog.w(TAG, "Backup pass but e=" + mEnabled + " p=" + mProvisioned);
  881. }
  882. }
  883. }
  884. }
  885. }
  886. }
  887. private class RunInitializeReceiver extends BroadcastReceiver {
  888. public void onReceive(Context context, Intent intent) {
  889. if (RUN_INITIALIZE_ACTION.equals(intent.getAction())) {
  890. synchronized (mQueueLock) {
  891. if (DEBUG) Slog.v(TAG, "Running a device init");
  892. // Acquire the wakelock and pass it to the init thread. it will
  893. // be released once init concludes.
  894. mWakelock.acquire();
  895. Message msg = mBackupHandler.obtainMessage(MSG_RUN_INITIALIZE);
  896. mBackupHandler.sendMessage(msg);
  897. }
  898. }
  899. }
  900. }
  901. private void initPackageTracking() {
  902. if (DEBUG) Slog.v(TAG, "Initializing package tracking");
  903. // Remember our ancestral dataset
  904. mTokenFile = new File(mBaseStateDir, "ancestral");
  905. try {
  906. RandomAccessFile tf = new RandomAccessFile(mTokenFile, "r");
  907. int version = tf.readInt();
  908. if (version == CURRENT_ANCESTRAL_RECORD_VERSION) {
  909. mAncestralToken = tf.readLong();
  910. mCurrentToken = tf.readLong();
  911. int numPackages = tf.readInt();
  912. if (numPackages >= 0) {
  913. mAncestralPackages = new HashSet<String>();
  914. for (int i = 0; i < numPackages; i++) {
  915. String pkgName = tf.readUTF();
  916. mAncestralPackages.add(pkgName);
  917. }
  918. }
  919. }
  920. tf.close();
  921. } catch (FileNotFoundException fnf) {
  922. // Probably innocuous
  923. Slog.v(TAG, "No ancestral data");
  924. } catch (IOException e) {
  925. Slog.w(TAG, "Unable to read token file", e);
  926. }
  927. // Keep a log of what apps we've ever backed up. Because we might have
  928. // rebooted in the middle of an operation that was removing something from
  929. // this log, we sanity-check its contents here and reconstruct it.
  930. mEverStored = new File(mBaseStateDir, "processed");
  931. File tempProcessedFile = new File(mBaseStateDir, "processed.new");
  932. // If we were in the middle of removing something from the ever-backed-up
  933. // file, there might be a transient "processed.new" file still present.
  934. // Ignore it -- we'll validate "processed" against the current package set.
  935. if (tempProcessedFile.exists()) {
  936. tempProcessedFile.delete();
  937. }
  938. // If there are previous contents, parse them out then start a new
  939. // file to continue the recordkeeping.
  940. if (mEverStored.exists()) {
  941. RandomAccessFile temp = null;
  942. RandomAccessFile in = null;
  943. try {
  944. temp = new RandomAccessFile(tempProcessedFile, "rws");
  945. in = new RandomAccessFile(mEverStored, "r");
  946. while (true) {
  947. PackageInfo info;
  948. String pkg = in.readUTF();
  949. try {
  950. info = mPackageManager.getPackageInfo(pkg, 0);
  951. mEverStoredApps.add(pkg);
  952. temp.writeUTF(pkg);
  953. if (MORE_DEBUG) Slog.v(TAG, " + " + pkg);
  954. } catch (NameNotFoundException e) {
  955. // nope, this package was uninstalled; don't include it
  956. if (MORE_DEBUG) Slog.v(TAG, " - " + pkg);
  957. }
  958. }
  959. } catch (EOFException e) {
  960. // Once we've rewritten the backup history log, atomically replace the
  961. // old one with the new one then reopen the file for continuing use.
  962. if (!tempProcessedFile.renameTo(mEverStored)) {
  963. Slog.e(TAG, "Error renaming " + tempProcessedFile + " to " + mEverStored);
  964. }
  965. } catch (IOException e) {
  966. Slog.e(TAG, "Error in processed file", e);
  967. } finally {
  968. try { if (temp != null) temp.close(); } catch (IOException e) {}
  969. try { if (in != null) in.close(); } catch (IOException e) {}
  970. }
  971. }
  972. // Register for broadcasts about package install, etc., so we can
  973. // update the provider list.
  974. IntentFilter filter = new IntentFilter();
  975. filter.addAction(Intent.ACTION_PACKAGE_ADDED);
  976. filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
  977. filter.addDataScheme("package");
  978. mContext.registerReceiver(mBroadcastReceiver, filter);
  979. // Register for events related to sdcard installation.
  980. IntentFilter sdFilter = new IntentFilter();
  981. sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
  982. sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
  983. mContext.registerReceiver(mBroadcastReceiver, sdFilter);
  984. }
  985. private void parseLeftoverJournals() {
  986. for (File f : mJournalDir.listFiles()) {
  987. if (mJournal == null || f.compareTo(mJournal) != 0) {
  988. // This isn't the current journal, so it must be a leftover. Read
  989. // out the package names mentioned there and schedule them for
  990. // backup.
  991. RandomAccessFile in = null;
  992. try {
  993. Slog.i(TAG, "Found stale backup journal, scheduling");
  994. in = new RandomAccessFile(f, "r");
  995. while (true) {
  996. String packageName = in.readUTF();
  997. Slog.i(TAG, " " + packageName);
  998. dataChangedImpl(packageName);
  999. }
  1000. } catch (EOFException e) {
  1001. // no more data; we're done
  1002. } catch (Exception e) {
  1003. Slog.e(TAG, "Can't read " + f, e);
  1004. } finally {
  1005. // close/delete the file
  1006. try { if (in != null) in.close(); } catch (IOException e) {}
  1007. f.delete();
  1008. }
  1009. }
  1010. }
  1011. }
  1012. private SecretKey buildPasswordKey(String algorithm, String pw, byte[] salt, int rounds) {
  1013. return buildCharArrayKey(algorithm, pw.toCharArray(), salt, rounds);
  1014. }
  1015. private SecretKey buildCharArrayKey(String algorithm, char[] pwArray, byte[] salt, int rounds) {
  1016. try {
  1017. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(algorithm);
  1018. KeySpec ks = new PBEKeySpec(pwArray, salt, rounds, PBKDF2_KEY_SIZE);
  1019. return keyFactory.generateSecret(ks);
  1020. } catch (InvalidKeySpecException e) {
  1021. Slog.e(TAG, "Invalid key spec for PBKDF2!");
  1022. } catch (NoSuchAlgorithmException e) {
  1023. Slog.e(TAG, "PBKDF2 unavailable!");
  1024. }
  1025. return null;
  1026. }
  1027. private String buildPasswordHash(String algorithm, String pw, byte[] salt, int rounds) {
  1028. SecretKey key = buildPasswordKey(algorithm, pw, salt, rounds);
  1029. if (key != null) {
  1030. return byteArrayToHex(key.getEncoded());
  1031. }
  1032. return null;
  1033. }
  1034. private String byteArrayToHex(byte[] data) {
  1035. StringBuilder buf = new StringBuilder(data.length * 2);
  1036. for (int i = 0; i < data.length; i++) {
  1037. buf.append(Byte.toHexString(data[i], true));
  1038. }
  1039. return buf.toString();
  1040. }
  1041. private byte[] hexToByteArray(String digits) {
  1042. final int bytes = digits.length() / 2;
  1043. if (2*bytes != digits.length()) {
  1044. throw new IllegalArgumentException("Hex string must have an even number of digits");
  1045. }
  1046. byte[] result = new byte[bytes];
  1047. for (int i = 0; i < digits.length(); i += 2) {
  1048. result[i/2] = (byte) Integer.parseInt(digits.substring(i, i+2), 16);
  1049. }
  1050. return result;
  1051. }
  1052. private byte[] makeKeyChecksum(String algorithm, byte[] pwBytes, byte[] salt, int rounds) {
  1053. char[] mkAsChar = new char[pwBytes.length];
  1054. for (int i = 0; i < pwBytes.length; i++) {
  1055. mkAsChar[i] = (char) pwBytes[i];
  1056. }
  1057. Key checksum = buildCharArrayKey(algorithm, mkAsChar, salt, rounds);
  1058. return checksum.getEncoded();
  1059. }
  1060. // Used for generating random salts or passwords
  1061. private byte[] randomBytes(int bits) {
  1062. byte[] array = new byte[bits / 8];
  1063. mRng.nextBytes(array);
  1064. return array;
  1065. }
  1066. // Backup password management
  1067. boolean passwordMatchesSaved(String algorithm, String candidatePw, int rounds) {
  1068. // First, on an encrypted device we require matching the device pw
  1069. final boolean isEncrypted;
  1070. try {
  1071. isEncrypted = (mMountService.getEncryptionState() != MountService.ENCRYPTION_STATE_NONE);