diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 318cd45..ef1559a 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -59,8 +59,7 @@
 
 public class TaskPersister {
     static final String TAG = "TaskPersister";
-    static final boolean DEBUG_PERSISTER = false;
-    static final boolean DEBUG_RESTORER = false;
+    static final boolean DEBUG = false;
 
     /** When not flushing don't write out files faster than this */
     private static final long INTER_WRITE_DELAY_MS = 500;
@@ -81,21 +80,10 @@
     private static final String IMAGES_DIRNAME = "recent_images";
     static final String IMAGE_EXTENSION = ".png";
 
-    // Directory where restored historical task XML/PNG files are placed.  This directory
-    // contains subdirs named after TASKS_DIRNAME and IMAGES_DIRNAME mirroring the
-    // ancestral device's dataset.  This needs to match the RECENTS_TASK_RESTORE_DIR
-    // value in RecentsBackupHelper.
-    private static final String RESTORED_TASKS_DIRNAME = "restored_" + TASKS_DIRNAME;
-
-    // Max time to wait for the application/package of a restored task to be installed
-    // before giving up.
-    private static final long MAX_INSTALL_WAIT_TIME = DateUtils.DAY_IN_MILLIS;
-
     private static final String TAG_TASK = "task";
 
     static File sImagesDir;
     static File sTasksDir;
-    static File sRestoredTasksDir;
 
     private final ActivityManagerService mService;
     private final ActivityStackSupervisor mStackSupervisor;
@@ -129,23 +117,11 @@
 
     ArrayList<WriteQueueItem> mWriteQueue = new ArrayList<WriteQueueItem>();
 
-    // Map of tasks that were backed-up on a different device that can be restored on this device.
-    // Data organization: <packageNameOfAffiliateTask, listOfAffiliatedTasksChains>
-    private ArrayMap<String, List<List<OtherDeviceTask>>> mOtherDeviceTasksMap =
-                new ArrayMap<>(10);
-    // Local cache of package names to uid used when restoring a task from another device.
-    private ArrayMap<String, Integer> mPackageUidMap;
-
-    // The next time in milliseconds we will remove expired task from
-    // {@link #mOtherDeviceTasksMap} and disk. Set to {@link Long.MAX_VALUE} to never clean-up
-    // tasks.
-    private long mExpiredTasksCleanupTime = Long.MAX_VALUE;
-
     TaskPersister(File systemDir, ActivityStackSupervisor stackSupervisor,
             RecentTasks recentTasks) {
         sTasksDir = new File(systemDir, TASKS_DIRNAME);
         if (!sTasksDir.exists()) {
-            if (DEBUG_PERSISTER) Slog.d(TAG, "Creating tasks directory " + sTasksDir);
+            if (DEBUG) Slog.d(TAG, "Creating tasks directory " + sTasksDir);
             if (!sTasksDir.mkdir()) {
                 Slog.e(TAG, "Failure creating tasks directory " + sTasksDir);
             }
@@ -153,14 +129,12 @@
 
         sImagesDir = new File(systemDir, IMAGES_DIRNAME);
         if (!sImagesDir.exists()) {
-            if (DEBUG_PERSISTER) Slog.d(TAG, "Creating images directory " + sTasksDir);
+            if (DEBUG) Slog.d(TAG, "Creating images directory " + sTasksDir);
             if (!sImagesDir.mkdir()) {
                 Slog.e(TAG, "Failure creating images directory " + sImagesDir);
             }
         }
 
-        sRestoredTasksDir = new File(systemDir, RESTORED_TASKS_DIRNAME);
-
         mStackSupervisor = stackSupervisor;
         mService = stackSupervisor.mService;
         mRecentTasks = recentTasks;
@@ -179,8 +153,8 @@
             final WriteQueueItem item = mWriteQueue.get(queueNdx);
             if (item instanceof ImageWriteQueueItem &&
                     ((ImageWriteQueueItem) item).mFilename.startsWith(taskString)) {
-                if (DEBUG_PERSISTER) Slog.d(TAG, "Removing "
-                        + ((ImageWriteQueueItem) item).mFilename + " from write queue");
+                if (DEBUG) Slog.d(TAG, "Removing " + ((ImageWriteQueueItem) item).mFilename +
+                        " from write queue");
                 mWriteQueue.remove(queueNdx);
             }
         }
@@ -225,9 +199,9 @@
             } else if (mNextWriteTime == 0) {
                 mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS;
             }
-            if (DEBUG_PERSISTER) Slog.d(TAG, "wakeup: task=" + task + " flush=" + flush
-                    + " mNextWriteTime=" + mNextWriteTime + " mWriteQueue.size="
-                    + mWriteQueue.size() + " Callers=" + Debug.getCallers(4));
+            if (DEBUG) Slog.d(TAG, "wakeup: task=" + task + " flush=" + flush + " mNextWriteTime="
+                    + mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size()
+                    + " Callers=" + Debug.getCallers(4));
             notifyAll();
         }
 
@@ -269,7 +243,7 @@
             } else if (mNextWriteTime == 0) {
                 mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS;
             }
-            if (DEBUG_PERSISTER) Slog.d(TAG, "saveImage: filename=" + filename + " now=" +
+            if (DEBUG) Slog.d(TAG, "saveImage: filename=" + filename + " now=" +
                     SystemClock.uptimeMillis() + " mNextWriteTime=" +
                     mNextWriteTime + " Callers=" + Debug.getCallers(4));
             notifyAll();
@@ -303,12 +277,12 @@
     }
 
     private StringWriter saveToXml(TaskRecord task) throws IOException, XmlPullParserException {
-        if (DEBUG_PERSISTER) Slog.d(TAG, "saveToXml: task=" + task);
+        if (DEBUG) Slog.d(TAG, "saveToXml: task=" + task);
         final XmlSerializer xmlSerializer = new FastXmlSerializer();
         StringWriter stringWriter = new StringWriter();
         xmlSerializer.setOutput(stringWriter);
 
-        if (DEBUG_PERSISTER) xmlSerializer.setFeature(
+        if (DEBUG) xmlSerializer.setFeature(
                     "http://xmlpull.org/v1/doc/features.html#indent-output", true);
 
         // save task
@@ -367,7 +341,7 @@
 
         for (int taskNdx = 0; taskNdx < recentFiles.length; ++taskNdx) {
             File taskFile = recentFiles[taskNdx];
-            if (DEBUG_PERSISTER) Slog.d(TAG, "restoreTasksLocked: taskFile=" + taskFile.getName());
+            if (DEBUG) Slog.d(TAG, "restoreTasksLocked: taskFile=" + taskFile.getName());
             BufferedReader reader = null;
             boolean deleteFile = false;
             try {
@@ -380,12 +354,11 @@
                         event != XmlPullParser.END_TAG) {
                     final String name = in.getName();
                     if (event == XmlPullParser.START_TAG) {
-                        if (DEBUG_PERSISTER)
-                                Slog.d(TAG, "restoreTasksLocked: START_TAG name=" + name);
+                        if (DEBUG) Slog.d(TAG, "restoreTasksLocked: START_TAG name=" + name);
                         if (TAG_TASK.equals(name)) {
                             final TaskRecord task =
                                     TaskRecord.restoreFromXml(in, mStackSupervisor);
-                            if (DEBUG_PERSISTER) Slog.d(TAG, "restoreTasksLocked: restored task=" +
+                            if (DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task=" +
                                     task);
                             if (task != null) {
                                 task.isPersistable = true;
@@ -414,15 +387,14 @@
                 deleteFile = true;
             } finally {
                 IoUtils.closeQuietly(reader);
-                if (!DEBUG_PERSISTER && deleteFile) {
-                    if (true || DEBUG_PERSISTER)
-                            Slog.d(TAG, "Deleting file=" + taskFile.getName());
+                if (deleteFile) {
+                    if (DEBUG) Slog.d(TAG, "Deleting file=" + taskFile.getName());
                     taskFile.delete();
                 }
             }
         }
 
-        if (!DEBUG_PERSISTER) {
+        if (!DEBUG) {
             removeObsoleteFiles(recoveredTaskIds);
         }
 
@@ -453,8 +425,8 @@
     }
 
     private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) {
-        if (DEBUG_PERSISTER) Slog.d(TAG, "removeObsoleteFile: persistentTaskIds="
-                    + persistentTaskIds + " files=" + files);
+        if (DEBUG) Slog.d(TAG, "removeObsoleteFile: persistentTaskIds=" + persistentTaskIds +
+                " files=" + files);
         if (files == null) {
             Slog.e(TAG, "File error accessing recents directory (too many files open?).");
             return;
@@ -467,15 +439,14 @@
                 final int taskId;
                 try {
                     taskId = Integer.valueOf(filename.substring(0, taskIdEnd));
-                    if (DEBUG_PERSISTER) Slog.d(TAG, "removeObsoleteFile: Found taskId=" + taskId);
+                    if (DEBUG) Slog.d(TAG, "removeObsoleteFile: Found taskId=" + taskId);
                 } catch (Exception e) {
                     Slog.wtf(TAG, "removeObsoleteFile: Can't parse file=" + file.getName());
                     file.delete();
                     continue;
                 }
                 if (!persistentTaskIds.contains(taskId)) {
-                    if (true || DEBUG_PERSISTER) Slog.d(TAG, "removeObsoleteFile: deleting file=" +
-                            file.getName());
+                    if (DEBUG) Slog.d(TAG, "removeObsoleteFile: deleting file=" + file.getName());
                     file.delete();
                 }
             }
@@ -488,441 +459,10 @@
     }
 
     static Bitmap restoreImage(String filename) {
-        if (DEBUG_PERSISTER) Slog.d(TAG, "restoreImage: restoring " + filename);
+        if (DEBUG) Slog.d(TAG, "restoreImage: restoring " + filename);
         return BitmapFactory.decodeFile(sImagesDir + File.separator + filename);
     }
 
-    /**
-     * Tries to restore task that were backed-up on a different device onto this device.
-     */
-    void restoreTasksFromOtherDeviceLocked() {
-        readOtherDeviceTasksFromDisk();
-        addOtherDeviceTasksToRecentsLocked();
-    }
-
-    /**
-     * Read the tasks that were backed-up on a different device and can be restored to this device
-     * from disk and populated {@link #mOtherDeviceTasksMap} with the information. Also sets up
-     * time to clear out other device tasks that have not been restored on this device
-     * within the allotted time.
-     */
-    private void readOtherDeviceTasksFromDisk() {
-        synchronized (mOtherDeviceTasksMap) {
-            // Clear out current map and expiration time.
-            mOtherDeviceTasksMap.clear();
-            mExpiredTasksCleanupTime = Long.MAX_VALUE;
-
-            final File[] taskFiles;
-            if (!sRestoredTasksDir.exists()
-                    || (taskFiles = sRestoredTasksDir.listFiles()) == null) {
-                // Nothing to do if there are no tasks to restore.
-                return;
-            }
-
-            long earliestMtime = System.currentTimeMillis();
-            SparseArray<List<OtherDeviceTask>> tasksByAffiliateIds =
-                        new SparseArray<>(taskFiles.length);
-
-            // Read new tasks from disk
-            for (int i = 0; i < taskFiles.length; ++i) {
-                final File taskFile = taskFiles[i];
-                if (DEBUG_RESTORER) Slog.d(TAG, "readOtherDeviceTasksFromDisk: taskFile="
-                            + taskFile.getName());
-
-                final OtherDeviceTask task = OtherDeviceTask.createFromFile(taskFile);
-
-                if (task == null) {
-                    // Go ahead and remove the file on disk if we are unable to create a task from
-                    // it.
-                    if (DEBUG_RESTORER) Slog.e(TAG, "Unable to create task for file="
-                                + taskFile.getName() + "...deleting file.");
-                    taskFile.delete();
-                    continue;
-                }
-
-                List<OtherDeviceTask> tasks = tasksByAffiliateIds.get(task.mAffiliatedTaskId);
-                if (tasks == null) {
-                    tasks = new ArrayList<>();
-                    tasksByAffiliateIds.put(task.mAffiliatedTaskId, tasks);
-                }
-                tasks.add(task);
-                final long taskMtime = taskFile.lastModified();
-                if (earliestMtime > taskMtime) {
-                    earliestMtime = taskMtime;
-                }
-            }
-
-            if (tasksByAffiliateIds.size() > 0) {
-                // Sort each affiliated tasks chain by taskId which is the order they were created
-                // that should always be correct...Then add to task map.
-                for (int i = 0; i < tasksByAffiliateIds.size(); i++) {
-                    List<OtherDeviceTask> chain = tasksByAffiliateIds.valueAt(i);
-                    Collections.sort(chain);
-                    // Package name of the root task in the affiliate chain.
-                    final String packageName =
-                            chain.get(chain.size()-1).mComponentName.getPackageName();
-                    List<List<OtherDeviceTask>> chains = mOtherDeviceTasksMap.get(packageName);
-                    if (chains == null) {
-                        chains = new ArrayList<>();
-                        mOtherDeviceTasksMap.put(packageName, chains);
-                    }
-                    chains.add(chain);
-                }
-
-                // Set expiration time.
-                mExpiredTasksCleanupTime = earliestMtime + MAX_INSTALL_WAIT_TIME;
-                if (DEBUG_RESTORER) Slog.d(TAG, "Set Expiration time to "
-                            + DateUtils.formatDateTime(mService.mContext, mExpiredTasksCleanupTime,
-                            DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME));
-            }
-        }
-    }
-
-    /**
-     * Removed any expired tasks from {@link #mOtherDeviceTasksMap} and disk if their expiration
-     * time is less than or equal to {@link #mExpiredTasksCleanupTime}.
-     */
-    private void removeExpiredTasksIfNeeded() {
-        synchronized (mOtherDeviceTasksMap) {
-            final long now = System.currentTimeMillis();
-            final boolean noMoreTasks = mOtherDeviceTasksMap.isEmpty();
-            if (noMoreTasks || now < mExpiredTasksCleanupTime) {
-                if (noMoreTasks && mPackageUidMap != null) {
-                    // All done! package->uid map no longer needed.
-                    mPackageUidMap = null;
-                }
-                return;
-            }
-
-            long earliestNonExpiredMtime = now;
-            mExpiredTasksCleanupTime = Long.MAX_VALUE;
-
-            // Remove expired backed-up tasks that have not been restored. We only want to
-            // remove task if it is safe to remove all tasks in the affiliation chain.
-            for (int i = mOtherDeviceTasksMap.size() - 1; i >= 0 ; i--) {
-
-                List<List<OtherDeviceTask>> chains = mOtherDeviceTasksMap.valueAt(i);
-                for (int j = chains.size() - 1; j >= 0 ; j--) {
-
-                    List<OtherDeviceTask> chain = chains.get(j);
-                    boolean removeChain = true;
-                    for (int k = chain.size() - 1; k >= 0 ; k--) {
-                        OtherDeviceTask task = chain.get(k);
-                        final long taskLastModified = task.mFile.lastModified();
-                        if ((taskLastModified + MAX_INSTALL_WAIT_TIME) > now) {
-                            // File has not expired yet...but we keep looping to get the earliest
-                            // mtime.
-                            if (earliestNonExpiredMtime > taskLastModified) {
-                                earliestNonExpiredMtime = taskLastModified;
-                            }
-                            removeChain = false;
-                        }
-                    }
-                    if (removeChain) {
-                        for (int k = chain.size() - 1; k >= 0; k--) {
-                            final File file = chain.get(k).mFile;
-                            if (DEBUG_RESTORER) Slog.d(TAG, "Deleting expired file="
-                                    + file.getName() + " mapped to not installed component="
-                                    + chain.get(k).mComponentName);
-                            file.delete();
-                        }
-                        chains.remove(j);
-                    }
-                }
-                if (chains.isEmpty()) {
-                    final String packageName = mOtherDeviceTasksMap.keyAt(i);
-                    mOtherDeviceTasksMap.removeAt(i);
-                    if (DEBUG_RESTORER) Slog.d(TAG, "Removed package=" + packageName
-                                + " from task map");
-                }
-            }
-
-            // Reset expiration time if there is any task remaining.
-            if (!mOtherDeviceTasksMap.isEmpty()) {
-                mExpiredTasksCleanupTime = earliestNonExpiredMtime + MAX_INSTALL_WAIT_TIME;
-                if (DEBUG_RESTORER) Slog.d(TAG, "Reset expiration time to "
-                            + DateUtils.formatDateTime(mService.mContext, mExpiredTasksCleanupTime,
-                            DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME));
-            } else {
-                // All done! package->uid map no longer needed.
-                mPackageUidMap = null;
-            }
-        }
-    }
-
-    /**
-     * Removes the input package name from the local package->uid map.
-     */
-    void removeFromPackageCache(String packageName) {
-        synchronized (mOtherDeviceTasksMap) {
-            if (mPackageUidMap != null) {
-                mPackageUidMap.remove(packageName);
-            }
-        }
-    }
-
-    /**
-     * Tries to add all backed-up tasks from another device to this device recent's list.
-     */
-    private void addOtherDeviceTasksToRecentsLocked() {
-        synchronized (mOtherDeviceTasksMap) {
-            for (int i = mOtherDeviceTasksMap.size() - 1; i >= 0; i--) {
-                addOtherDeviceTasksToRecentsLocked(mOtherDeviceTasksMap.keyAt(i));
-            }
-        }
-    }
-
-    /**
-     * Tries to add backed-up tasks that are associated with the input package from
-     * another device to this device recent's list.
-     */
-    void addOtherDeviceTasksToRecentsLocked(String packageName) {
-        synchronized (mOtherDeviceTasksMap) {
-            List<List<OtherDeviceTask>> chains = mOtherDeviceTasksMap.get(packageName);
-            if (chains == null) {
-                return;
-            }
-
-            for (int i = chains.size() - 1; i >= 0; i--) {
-                List<OtherDeviceTask> chain = chains.get(i);
-                if (!canAddOtherDeviceTaskChain(chain)) {
-                    if (DEBUG_RESTORER) Slog.d(TAG, "Can't add task chain at index=" + i
-                            + " for package=" + packageName);
-                    continue;
-                }
-
-                // Generate task records for this chain.
-                List<TaskRecord> tasks = new ArrayList<>();
-                TaskRecord prev = null;
-                for (int j = chain.size() - 1; j >= 0; j--) {
-                    TaskRecord task = createTaskRecordLocked(chain.get(j));
-                    if (task == null) {
-                        // There was a problem in creating one of this task records in this chain.
-                        // There is no way we can continue...
-                        if (DEBUG_RESTORER) Slog.d(TAG, "Can't create task record for file="
-                                + chain.get(j).mFile + " for package=" + packageName);
-                        break;
-                    }
-
-                    // Wire-up affiliation chain.
-                    if (prev == null) {
-                        task.mPrevAffiliate = null;
-                        task.mPrevAffiliateTaskId = INVALID_TASK_ID;
-                        task.mAffiliatedTaskId = task.taskId;
-                    } else {
-                        prev.mNextAffiliate = task;
-                        prev.mNextAffiliateTaskId = task.taskId;
-                        task.mAffiliatedTaskId = prev.mAffiliatedTaskId;
-                        task.mPrevAffiliate = prev;
-                        task.mPrevAffiliateTaskId = prev.taskId;
-                    }
-                    prev = task;
-                    tasks.add(0, task);
-                }
-
-                // Add tasks to recent's if we were able to create task records for all the tasks
-                // in the chain.
-                if (tasks.size() == chain.size()) {
-                    // Make sure there is space in recent's to add the new task. If there is space
-                    // to the to the back.
-                    // TODO: Would be more fancy to interleave the new tasks into recent's based on
-                    // {@link TaskRecord.mLastTimeMoved} and drop the oldest recent's vs. just
-                    // adding to the back of the list.
-                    int spaceLeft =
-                            ActivityManager.getMaxRecentTasksStatic() - mRecentTasks.size();
-                    if (spaceLeft >= tasks.size()) {
-                        mRecentTasks.addAll(mRecentTasks.size(), tasks);
-                        for (int k = tasks.size() - 1; k >= 0; k--) {
-                            // Persist new tasks.
-                            wakeup(tasks.get(k), false);
-                        }
-
-                        if (DEBUG_RESTORER) Slog.d(TAG, "Added " + tasks.size()
-                                    + " tasks to recent's for" + " package=" + packageName);
-                    } else {
-                        if (DEBUG_RESTORER) Slog.d(TAG, "Didn't add to recents. tasks.size("
-                                    + tasks.size() + ") != chain.size(" + chain.size()
-                                    + ") for package=" + packageName);
-                    }
-                } else {
-                    if (DEBUG_RESTORER) Slog.v(TAG, "Unable to add restored tasks to recents "
-                            + tasks.size() + " tasks for package=" + packageName);
-                }
-
-                // Clean-up structures
-                for (int j = chain.size() - 1; j >= 0; j--) {
-                    chain.get(j).mFile.delete();
-                }
-                chains.remove(i);
-                if (chains.isEmpty()) {
-                    // The fate of all backed-up tasks associated with this package has been
-                    // determine. Go ahead and remove it from the to-process list.
-                    mOtherDeviceTasksMap.remove(packageName);
-                    if (DEBUG_RESTORER)
-                            Slog.d(TAG, "Removed package=" + packageName + " from restore map");
-                }
-            }
-        }
-    }
-
-    /**
-     * Creates and returns {@link TaskRecord} for the task from another device that can be used on
-     * this device. Returns null if the operation failed.
-     */
-    private TaskRecord createTaskRecordLocked(OtherDeviceTask other) {
-        File file = other.mFile;
-        BufferedReader reader = null;
-        TaskRecord task = null;
-        if (DEBUG_RESTORER) Slog.d(TAG, "createTaskRecordLocked: file=" + file.getName());
-
-        try {
-            reader = new BufferedReader(new FileReader(file));
-            final XmlPullParser in = Xml.newPullParser();
-            in.setInput(reader);
-
-            int event;
-            while (((event = in.next()) != XmlPullParser.END_DOCUMENT)
-                    && event != XmlPullParser.END_TAG) {
-                final String name = in.getName();
-                if (event == XmlPullParser.START_TAG) {
-
-                    if (TAG_TASK.equals(name)) {
-                        // Create a task record using a task id that is valid for this device.
-                        task = TaskRecord.restoreFromXml(
-                                in, mStackSupervisor, mStackSupervisor.getNextTaskId());
-                        if (DEBUG_RESTORER)
-                                Slog.d(TAG, "createTaskRecordLocked: restored task=" + task);
-
-                        if (task != null) {
-                            task.isPersistable = true;
-                            task.inRecents = true;
-                            // Task can/should only be backed-up/restored for device owner.
-                            task.userId = UserHandle.USER_OWNER;
-                            // Clear out affiliated ids that are no longer valid on this device.
-                            task.mAffiliatedTaskId = INVALID_TASK_ID;
-                            task.mPrevAffiliateTaskId = INVALID_TASK_ID;
-                            task.mNextAffiliateTaskId = INVALID_TASK_ID;
-                            // Set up uids valid for this device.
-                            Integer uid = mPackageUidMap.get(task.realActivity.getPackageName());
-                            if (uid == null) {
-                                // How did this happen???
-                                Slog.wtf(TAG, "Can't find uid for task=" + task
-                                        + " in mPackageUidMap=" + mPackageUidMap);
-                                return null;
-                            }
-                            task.effectiveUid = task.mCallingUid = uid;
-                            for (int i = task.mActivities.size() - 1; i >= 0; --i) {
-                                final ActivityRecord activity = task.mActivities.get(i);
-                                uid = mPackageUidMap.get(activity.launchedFromPackage);
-                                if (uid == null) {
-                                    // How did this happen??
-                                    Slog.wtf(TAG, "Can't find uid for activity=" + activity
-                                            + " in mPackageUidMap=" + mPackageUidMap);
-                                    return null;
-                                }
-                                activity.launchedFromUid = uid;
-                            }
-
-                        } else {
-                            Slog.e(TAG, "Unable to create task for backed-up file=" + file + ": "
-                                        + fileToString(file));
-                        }
-                    } else {
-                        Slog.wtf(TAG, "createTaskRecordLocked Unknown xml event=" + event
-                                    + " name=" + name);
-                    }
-                }
-                XmlUtils.skipCurrentTag(in);
-            }
-        } catch (Exception e) {
-            Slog.wtf(TAG, "Unable to parse " + file + ". Error ", e);
-            Slog.e(TAG, "Failing file: " + fileToString(file));
-        } finally {
-            IoUtils.closeQuietly(reader);
-        }
-
-        return task;
-    }
-
-    /**
-     * Returns true if the input task chain backed-up from another device can be restored on this
-     * device. Also, sets the {@link OtherDeviceTask#mUid} on the input tasks if they can be
-     * restored.
-     */
-    private boolean canAddOtherDeviceTaskChain(List<OtherDeviceTask> chain) {
-
-        final ArraySet<ComponentName> validComponents = new ArraySet<>();
-        final IPackageManager pm = AppGlobals.getPackageManager();
-        for (int i = 0; i < chain.size(); i++) {
-
-            OtherDeviceTask task = chain.get(i);
-            // Quick check, we can't add the task chain if any of its task files don't exist.
-            if (!task.mFile.exists()) {
-                if (DEBUG_RESTORER) Slog.d(TAG,
-                        "Can't add chain due to missing file=" + task.mFile);
-                return false;
-            }
-
-            // Verify task package is installed.
-            if (!isPackageInstalled(task.mComponentName.getPackageName())) {
-                return false;
-            }
-            // Verify that all the launch packages are installed.
-            if (task.mLaunchPackages != null) {
-                for (int j = task.mLaunchPackages.size() - 1; j >= 0; --j) {
-                    if (!isPackageInstalled(task.mLaunchPackages.valueAt(j))) {
-                        return false;
-                    }
-                }
-            }
-
-            if (validComponents.contains(task.mComponentName)) {
-                // Existance of component has already been verified.
-                continue;
-            }
-
-            // Check to see if the specific component is installed.
-            try {
-                if (pm.getActivityInfo(task.mComponentName, 0, UserHandle.USER_OWNER) == null) {
-                    // Component isn't installed...
-                    return false;
-                }
-                validComponents.add(task.mComponentName);
-            } catch (RemoteException e) {
-                // Should not happen???
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns true if the input package name is installed. If the package is installed, an entry
-     * for the package is added to {@link #mPackageUidMap}.
-     */
-    private boolean isPackageInstalled(final String packageName) {
-        if (mPackageUidMap != null && mPackageUidMap.containsKey(packageName)) {
-            return true;
-        }
-        try {
-            int uid = AppGlobals.getPackageManager().getPackageUid(
-                    packageName, UserHandle.USER_OWNER);
-            if (uid == -1) {
-                // package doesn't exist...
-                return false;
-            }
-            if (mPackageUidMap == null) {
-                mPackageUidMap = new ArrayMap<>();
-            }
-            mPackageUidMap.put(packageName, uid);
-            return true;
-        } catch (RemoteException e) {
-            // Should not happen???
-            return false;
-        }
-    }
-
     private class LazyTaskWriterThread extends Thread {
 
         LazyTaskWriterThread(String name) {
@@ -941,21 +481,20 @@
                     probablyDone = mWriteQueue.isEmpty();
                 }
                 if (probablyDone) {
-                    if (DEBUG_PERSISTER) Slog.d(TAG, "Looking for obsolete files.");
+                    if (DEBUG) Slog.d(TAG, "Looking for obsolete files.");
                     persistentTaskIds.clear();
                     synchronized (mService) {
-                        if (DEBUG_PERSISTER) Slog.d(TAG, "mRecents=" + mRecentTasks);
+                        if (DEBUG) Slog.d(TAG, "mRecents=" + mRecentTasks);
                         for (int taskNdx = mRecentTasks.size() - 1; taskNdx >= 0; --taskNdx) {
                             final TaskRecord task = mRecentTasks.get(taskNdx);
-                            if (DEBUG_PERSISTER) Slog.d(TAG, "LazyTaskWriter: task=" + task +
+                            if (DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task +
                                     " persistable=" + task.isPersistable);
                             if ((task.isPersistable || task.inRecents)
                                     && (task.stack == null || !task.stack.isHomeStack())) {
-                                if (DEBUG_PERSISTER)
-                                        Slog.d(TAG, "adding to persistentTaskIds task=" + task);
+                                if (DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task);
                                 persistentTaskIds.add(task.taskId);
                             } else {
-                                if (DEBUG_PERSISTER) Slog.d(TAG,
+                                if (DEBUG) Slog.d(TAG,
                                         "omitting from persistentTaskIds task=" + task);
                             }
                         }
@@ -969,7 +508,7 @@
                     if (mNextWriteTime != FLUSH_QUEUE) {
                         // The next write we don't have to wait so long.
                         mNextWriteTime = SystemClock.uptimeMillis() + INTER_WRITE_DELAY_MS;
-                        if (DEBUG_PERSISTER) Slog.d(TAG, "Next write time may be in " +
+                        if (DEBUG) Slog.d(TAG, "Next write time may be in " +
                                 INTER_WRITE_DELAY_MS + " msec. (" + mNextWriteTime + ")");
                     }
 
@@ -979,13 +518,8 @@
                             mNextWriteTime = 0; // idle.
                             TaskPersister.this.notifyAll(); // wake up flush() if needed.
                         }
-
-                        // See if we need to remove any expired back-up tasks before waiting.
-                        removeExpiredTasksIfNeeded();
-
                         try {
-                            if (DEBUG_PERSISTER)
-                                    Slog.d(TAG, "LazyTaskWriter: waiting indefinitely.");
+                            if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting indefinitely.");
                             TaskPersister.this.wait();
                         } catch (InterruptedException e) {
                         }
@@ -995,12 +529,11 @@
                     item = mWriteQueue.remove(0);
 
                     long now = SystemClock.uptimeMillis();
-                    if (DEBUG_PERSISTER) Slog.d(TAG, "LazyTaskWriter: now=" + now
-                                + " mNextWriteTime=" + mNextWriteTime + " mWriteQueue.size="
-                                + mWriteQueue.size());
+                    if (DEBUG) Slog.d(TAG, "LazyTaskWriter: now=" + now + " mNextWriteTime=" +
+                            mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size());
                     while (now < mNextWriteTime) {
                         try {
-                            if (DEBUG_PERSISTER) Slog.d(TAG, "LazyTaskWriter: waiting " +
+                            if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting " +
                                     (mNextWriteTime - now));
                             TaskPersister.this.wait(mNextWriteTime - now);
                         } catch (InterruptedException e) {
@@ -1015,7 +548,7 @@
                     ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item;
                     final String filename = imageWriteQueueItem.mFilename;
                     final Bitmap bitmap = imageWriteQueueItem.mImage;
-                    if (DEBUG_PERSISTER) Slog.d(TAG, "writing bitmap: filename=" + filename);
+                    if (DEBUG) Slog.d(TAG, "writing bitmap: filename=" + filename);
                     FileOutputStream imageFile = null;
                     try {
                         imageFile = new FileOutputStream(new File(sImagesDir, filename));
@@ -1029,12 +562,12 @@
                     // Write out one task.
                     StringWriter stringWriter = null;
                     TaskRecord task = ((TaskWriteQueueItem) item).mTask;
-                    if (DEBUG_PERSISTER) Slog.d(TAG, "Writing task=" + task);
+                    if (DEBUG) Slog.d(TAG, "Writing task=" + task);
                     synchronized (mService) {
                         if (task.inRecents) {
                             // Still there.
                             try {
-                                if (DEBUG_PERSISTER) Slog.d(TAG, "Saving task=" + task);
+                                if (DEBUG) Slog.d(TAG, "Saving task=" + task);
                                 stringWriter = saveToXml(task);
                             } catch (IOException e) {
                             } catch (XmlPullParserException e) {
@@ -1064,127 +597,4 @@
             }
         }
     }
-
-    /**
-     * Helper class for holding essential information about task that were backed-up on a different
-     * device that can be restored on this device.
-     */
-    private static class OtherDeviceTask implements Comparable<OtherDeviceTask> {
-        final File mFile;
-        // See {@link TaskRecord} for information on the fields below.
-        final ComponentName mComponentName;
-        final int mTaskId;
-        final int mAffiliatedTaskId;
-
-        // Names of packages that launched activities in this task. All packages listed here need
-        // to be installed on the current device in order for the task to be restored successfully.
-        final ArraySet<String> mLaunchPackages;
-
-        private OtherDeviceTask(File file, ComponentName componentName, int taskId,
-                int affiliatedTaskId, ArraySet<String> launchPackages) {
-            mFile = file;
-            mComponentName = componentName;
-            mTaskId = taskId;
-            mAffiliatedTaskId = (affiliatedTaskId == INVALID_TASK_ID) ? taskId: affiliatedTaskId;
-            mLaunchPackages = launchPackages;
-        }
-
-        @Override
-        public int compareTo(OtherDeviceTask another) {
-            return mTaskId - another.mTaskId;
-        }
-
-        /**
-         * Creates a new {@link OtherDeviceTask} object based on the contents of the input file.
-         *
-         * @param file input file that contains the complete task information.
-         * @return new {@link OtherDeviceTask} object or null if we failed to create the object.
-         */
-        static OtherDeviceTask createFromFile(File file) {
-            if (file == null || !file.exists()) {
-                if (DEBUG_RESTORER)
-                    Slog.d(TAG, "createFromFile: file=" + file + " doesn't exist.");
-                return null;
-            }
-
-            BufferedReader reader = null;
-
-            try {
-                reader = new BufferedReader(new FileReader(file));
-                final XmlPullParser in = Xml.newPullParser();
-                in.setInput(reader);
-
-                int event;
-                while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
-                        event != XmlPullParser.START_TAG) {
-                    // Skip to the start tag or end of document
-                }
-
-                if (event == XmlPullParser.START_TAG) {
-                    final String name = in.getName();
-
-                    if (TAG_TASK.equals(name)) {
-                        final int outerDepth = in.getDepth();
-                        ComponentName componentName = null;
-                        int taskId = INVALID_TASK_ID;
-                        int taskAffiliation = INVALID_TASK_ID;
-                        for (int j = in.getAttributeCount() - 1; j >= 0; --j) {
-                            final String attrName = in.getAttributeName(j);
-                            final String attrValue = in.getAttributeValue(j);
-                            if (TaskRecord.ATTR_REALACTIVITY.equals(attrName)) {
-                                componentName = ComponentName.unflattenFromString(attrValue);
-                            } else if (TaskRecord.ATTR_TASKID.equals(attrName)) {
-                                taskId = Integer.valueOf(attrValue);
-                            } else if (TaskRecord.ATTR_TASK_AFFILIATION.equals(attrName)) {
-                                taskAffiliation = Integer.valueOf(attrValue);
-                            }
-                        }
-                        if (componentName == null || taskId == INVALID_TASK_ID) {
-                            if (DEBUG_RESTORER) Slog.e(TAG,
-                                    "createFromFile: FAILED componentName=" + componentName
-                                    + " taskId=" + taskId + " file=" + file);
-                            return null;
-                        }
-
-                        ArraySet<String> launchPackages = null;
-                        while (((event = in.next()) != XmlPullParser.END_DOCUMENT) &&
-                                (event != XmlPullParser.END_TAG || in.getDepth() < outerDepth)) {
-                            if (event == XmlPullParser.START_TAG) {
-                                if (TaskRecord.TAG_ACTIVITY.equals(in.getName())) {
-                                    for (int j = in.getAttributeCount() - 1; j >= 0; --j) {
-                                        if (ActivityRecord.ATTR_LAUNCHEDFROMPACKAGE.equals(
-                                                in.getAttributeName(j))) {
-                                            if (launchPackages == null) {
-                                                launchPackages = new ArraySet();
-                                            }
-                                            launchPackages.add(in.getAttributeValue(j));
-                                        }
-                                    }
-                                } else {
-                                    XmlUtils.skipCurrentTag(in);
-                                }
-                            }
-                        }
-                        if (DEBUG_RESTORER) Slog.d(TAG, "creating OtherDeviceTask from file="
-                                + file.getName() + " componentName=" + componentName
-                                + " taskId=" + taskId + " launchPackages=" + launchPackages);
-                        return new OtherDeviceTask(file, componentName, taskId,
-                                taskAffiliation, launchPackages);
-                    } else {
-                        Slog.wtf(TAG,
-                                "createFromFile: Unknown xml event=" + event + " name=" + name);
-                    }
-                } else {
-                    Slog.wtf(TAG, "createFromFile: Unable to find start tag in file=" + file);
-                }
-            } catch (IOException | XmlPullParserException e) {
-                Slog.wtf(TAG, "Unable to parse " + file + ". Error ", e);
-            } finally {
-                IoUtils.closeQuietly(reader);
-            }
-
-            // Something went wrong...
-            return null;
-        }
-    }
 }
