diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java
index 9311f25..629a05d 100644
--- a/services/core/java/com/android/server/am/TaskPersister.java
+++ b/services/core/java/com/android/server/am/TaskPersister.java
@@ -16,16 +16,27 @@
 
 package com.android.server.am;
 
+import android.app.ActivityManager;
+import android.app.AppGlobals;
+import android.content.ComponentName;
+import android.content.pm.IPackageManager;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Debug;
+import android.os.RemoteException;
 import android.os.SystemClock;
+import android.os.UserHandle;
+import android.text.format.DateUtils;
+import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.AtomicFile;
 import android.util.Slog;
+import android.util.SparseArray;
 import android.util.Xml;
+
 import com.android.internal.util.FastXmlSerializer;
 import com.android.internal.util.XmlUtils;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlSerializer;
@@ -38,11 +49,18 @@
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Comparator;
+import java.util.List;
+
+import libcore.io.IoUtils;
+
+import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
 
 public class TaskPersister {
     static final String TAG = "TaskPersister";
-    static final boolean DEBUG = false;
+    static final boolean DEBUG_PERSISTER = false;
+    static final boolean DEBUG_RESTORER = false;
 
     /** When not flushing don't write out files faster than this */
     private static final long INTER_WRITE_DELAY_MS = 500;
@@ -67,12 +85,17 @@
     // 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 = "restored_" + TASKS_DIRNAME;
+    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;
@@ -105,10 +128,20 @@
 
     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);
+
+    // 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) {
         sTasksDir = new File(systemDir, TASKS_DIRNAME);
         if (!sTasksDir.exists()) {
-            if (DEBUG) Slog.d(TAG, "Creating tasks directory " + sTasksDir);
+            if (DEBUG_PERSISTER) Slog.d(TAG, "Creating tasks directory " + sTasksDir);
             if (!sTasksDir.mkdir()) {
                 Slog.e(TAG, "Failure creating tasks directory " + sTasksDir);
             }
@@ -116,12 +149,14 @@
 
         sImagesDir = new File(systemDir, IMAGES_DIRNAME);
         if (!sImagesDir.exists()) {
-            if (DEBUG) Slog.d(TAG, "Creating images directory " + sTasksDir);
+            if (DEBUG_PERSISTER) 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;
 
@@ -138,8 +173,8 @@
             final WriteQueueItem item = mWriteQueue.get(queueNdx);
             if (item instanceof ImageWriteQueueItem &&
                     ((ImageWriteQueueItem) item).mFilename.startsWith(taskString)) {
-                if (DEBUG) Slog.d(TAG, "Removing " + ((ImageWriteQueueItem) item).mFilename +
-                        " from write queue");
+                if (DEBUG_PERSISTER) Slog.d(TAG, "Removing "
+                        + ((ImageWriteQueueItem) item).mFilename + " from write queue");
                 mWriteQueue.remove(queueNdx);
             }
         }
@@ -184,9 +219,9 @@
             } else if (mNextWriteTime == 0) {
                 mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS;
             }
-            if (DEBUG) Slog.d(TAG, "wakeup: task=" + task + " flush=" + flush + " mNextWriteTime="
-                    + mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size()
-                    + " Callers=" + Debug.getCallers(4));
+            if (DEBUG_PERSISTER) Slog.d(TAG, "wakeup: task=" + task + " flush=" + flush
+                    + " mNextWriteTime=" + mNextWriteTime + " mWriteQueue.size="
+                    + mWriteQueue.size() + " Callers=" + Debug.getCallers(4));
             notifyAll();
         }
 
@@ -228,7 +263,7 @@
             } else if (mNextWriteTime == 0) {
                 mNextWriteTime = SystemClock.uptimeMillis() + PRE_TASK_DELAY_MS;
             }
-            if (DEBUG) Slog.d(TAG, "saveImage: filename=" + filename + " now=" +
+            if (DEBUG_PERSISTER) Slog.d(TAG, "saveImage: filename=" + filename + " now=" +
                     SystemClock.uptimeMillis() + " mNextWriteTime=" +
                     mNextWriteTime + " Callers=" + Debug.getCallers(4));
             notifyAll();
@@ -262,12 +297,12 @@
     }
 
     private StringWriter saveToXml(TaskRecord task) throws IOException, XmlPullParserException {
-        if (DEBUG) Slog.d(TAG, "saveToXml: task=" + task);
+        if (DEBUG_PERSISTER) Slog.d(TAG, "saveToXml: task=" + task);
         final XmlSerializer xmlSerializer = new FastXmlSerializer();
         StringWriter stringWriter = new StringWriter();
         xmlSerializer.setOutput(stringWriter);
 
-        if (DEBUG) xmlSerializer.setFeature(
+        if (DEBUG_PERSISTER) xmlSerializer.setFeature(
                     "http://xmlpull.org/v1/doc/features.html#indent-output", true);
 
         // save task
@@ -326,7 +361,7 @@
 
         for (int taskNdx = 0; taskNdx < recentFiles.length; ++taskNdx) {
             File taskFile = recentFiles[taskNdx];
-            if (DEBUG) Slog.d(TAG, "restoreTasksLocked: taskFile=" + taskFile.getName());
+            if (DEBUG_PERSISTER) Slog.d(TAG, "restoreTasksLocked: taskFile=" + taskFile.getName());
             BufferedReader reader = null;
             boolean deleteFile = false;
             try {
@@ -339,11 +374,12 @@
                         event != XmlPullParser.END_TAG) {
                     final String name = in.getName();
                     if (event == XmlPullParser.START_TAG) {
-                        if (DEBUG) Slog.d(TAG, "restoreTasksLocked: START_TAG name=" + name);
+                        if (DEBUG_PERSISTER)
+                                Slog.d(TAG, "restoreTasksLocked: START_TAG name=" + name);
                         if (TAG_TASK.equals(name)) {
                             final TaskRecord task =
                                     TaskRecord.restoreFromXml(in, mStackSupervisor);
-                            if (DEBUG) Slog.d(TAG, "restoreTasksLocked: restored task=" +
+                            if (DEBUG_PERSISTER) Slog.d(TAG, "restoreTasksLocked: restored task=" +
                                     task);
                             if (task != null) {
                                 task.isPersistable = true;
@@ -371,20 +407,16 @@
                 Slog.e(TAG, "Failing file: " + fileToString(taskFile));
                 deleteFile = true;
             } finally {
-                if (reader != null) {
-                    try {
-                        reader.close();
-                    } catch (IOException e) {
-                    }
-                }
-                if (!DEBUG && deleteFile) {
-                    if (true || DEBUG) Slog.d(TAG, "Deleting file=" + taskFile.getName());
+                IoUtils.closeQuietly(reader);
+                if (!DEBUG_PERSISTER && deleteFile) {
+                    if (true || DEBUG_PERSISTER)
+                            Slog.d(TAG, "Deleting file=" + taskFile.getName());
                     taskFile.delete();
                 }
             }
         }
 
-        if (!DEBUG) {
+        if (!DEBUG_PERSISTER) {
             removeObsoleteFiles(recoveredTaskIds);
         }
 
@@ -415,8 +447,8 @@
     }
 
     private static void removeObsoleteFiles(ArraySet<Integer> persistentTaskIds, File[] files) {
-        if (DEBUG) Slog.d(TAG, "removeObsoleteFile: persistentTaskIds=" + persistentTaskIds +
-                " files=" + files);
+        if (DEBUG_PERSISTER) Slog.d(TAG, "removeObsoleteFile: persistentTaskIds="
+                    + persistentTaskIds + " files=" + files);
         if (files == null) {
             Slog.e(TAG, "File error accessing recents directory (too many files open?).");
             return;
@@ -429,14 +461,14 @@
                 final int taskId;
                 try {
                     taskId = Integer.valueOf(filename.substring(0, taskIdEnd));
-                    if (DEBUG) Slog.d(TAG, "removeObsoleteFile: Found taskId=" + taskId);
+                    if (DEBUG_PERSISTER) 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) Slog.d(TAG, "removeObsoleteFile: deleting file=" +
+                    if (true || DEBUG_PERSISTER) Slog.d(TAG, "removeObsoleteFile: deleting file=" +
                             file.getName());
                     file.delete();
                 }
@@ -450,10 +482,363 @@
     }
 
     static Bitmap restoreImage(String filename) {
-        if (DEBUG) Slog.d(TAG, "restoreImage: restoring " + filename);
+        if (DEBUG_PERSISTER) 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();
+            if (mOtherDeviceTasksMap.isEmpty() || now < mExpiredTasksCleanupTime) {
+                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));
+            }
+        }
+    }
+
+    /**
+     * 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()
+                            - mService.mRecentTasks.size();
+                    if (spaceLeft >= tasks.size()) {
+                        mService.mRecentTasks.addAll(mService.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;
+                        } 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.
+     */
+    private boolean canAddOtherDeviceTaskChain(List<OtherDeviceTask> chain) {
+
+        // Get component names of all the tasks in the chain.
+        // Mainly doing this to reduce checking for a component twice if two or more
+        // affiliations belong to the same component which is highly likely.
+        ArraySet<ComponentName> componentsToCheck = new ArraySet<>();
+        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;
+            }
+            componentsToCheck.add(task.mComponentName);
+        }
+
+        boolean canAdd = true;
+        try {
+            // Check to see if all the components for this task chain are installed.
+            final IPackageManager pm = AppGlobals.getPackageManager();
+            for (int i = 0; canAdd && i < componentsToCheck.size(); i++) {
+                ComponentName cn = componentsToCheck.valueAt(i);
+                canAdd &= pm.getActivityInfo(cn, 0, UserHandle.USER_OWNER) != null;
+                if (DEBUG_RESTORER) Slog.d(TAG, "ComponentName=" + cn + " installed=" + canAdd);
+            }
+        } catch (RemoteException e) {
+            // Should not happen???
+            canAdd = false;
+        }
+
+        if (DEBUG_RESTORER) Slog.d(TAG, "canAdd=" + canAdd);
+        return canAdd;
+    }
+
     private class LazyTaskWriterThread extends Thread {
 
         LazyTaskWriterThread(String name) {
@@ -472,21 +857,22 @@
                     probablyDone = mWriteQueue.isEmpty();
                 }
                 if (probablyDone) {
-                    if (DEBUG) Slog.d(TAG, "Looking for obsolete files.");
+                    if (DEBUG_PERSISTER) Slog.d(TAG, "Looking for obsolete files.");
                     persistentTaskIds.clear();
                     synchronized (mService) {
                         final ArrayList<TaskRecord> tasks = mService.mRecentTasks;
-                        if (DEBUG) Slog.d(TAG, "mRecents=" + tasks);
+                        if (DEBUG_PERSISTER) Slog.d(TAG, "mRecents=" + tasks);
                         for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) {
                             final TaskRecord task = tasks.get(taskNdx);
-                            if (DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task +
+                            if (DEBUG_PERSISTER) Slog.d(TAG, "LazyTaskWriter: task=" + task +
                                     " persistable=" + task.isPersistable);
                             if ((task.isPersistable || task.inRecents)
-                                    && !task.stack.isHomeStack()) {
-                                if (DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task);
+                                    && (task.stack == null || !task.stack.isHomeStack())) {
+                                if (DEBUG_PERSISTER)
+                                        Slog.d(TAG, "adding to persistentTaskIds task=" + task);
                                 persistentTaskIds.add(task.taskId);
                             } else {
-                                if (DEBUG) Slog.d(TAG,
+                                if (DEBUG_PERSISTER) Slog.d(TAG,
                                         "omitting from persistentTaskIds task=" + task);
                             }
                         }
@@ -500,7 +886,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) Slog.d(TAG, "Next write time may be in " +
+                        if (DEBUG_PERSISTER) Slog.d(TAG, "Next write time may be in " +
                                 INTER_WRITE_DELAY_MS + " msec. (" + mNextWriteTime + ")");
                     }
 
@@ -510,8 +896,13 @@
                             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) Slog.d(TAG, "LazyTaskWriter: waiting indefinitely.");
+                            if (DEBUG_PERSISTER)
+                                    Slog.d(TAG, "LazyTaskWriter: waiting indefinitely.");
                             TaskPersister.this.wait();
                         } catch (InterruptedException e) {
                         }
@@ -521,11 +912,12 @@
                     item = mWriteQueue.remove(0);
 
                     long now = SystemClock.uptimeMillis();
-                    if (DEBUG) Slog.d(TAG, "LazyTaskWriter: now=" + now + " mNextWriteTime=" +
-                            mNextWriteTime + " mWriteQueue.size=" + mWriteQueue.size());
+                    if (DEBUG_PERSISTER) Slog.d(TAG, "LazyTaskWriter: now=" + now
+                                + " mNextWriteTime=" + mNextWriteTime + " mWriteQueue.size="
+                                + mWriteQueue.size());
                     while (now < mNextWriteTime) {
                         try {
-                            if (DEBUG) Slog.d(TAG, "LazyTaskWriter: waiting " +
+                            if (DEBUG_PERSISTER) Slog.d(TAG, "LazyTaskWriter: waiting " +
                                     (mNextWriteTime - now));
                             TaskPersister.this.wait(mNextWriteTime - now);
                         } catch (InterruptedException e) {
@@ -540,7 +932,7 @@
                     ImageWriteQueueItem imageWriteQueueItem = (ImageWriteQueueItem) item;
                     final String filename = imageWriteQueueItem.mFilename;
                     final Bitmap bitmap = imageWriteQueueItem.mImage;
-                    if (DEBUG) Slog.d(TAG, "writing bitmap: filename=" + filename);
+                    if (DEBUG_PERSISTER) Slog.d(TAG, "writing bitmap: filename=" + filename);
                     FileOutputStream imageFile = null;
                     try {
                         imageFile = new FileOutputStream(new File(sImagesDir, filename));
@@ -548,23 +940,18 @@
                     } catch (Exception e) {
                         Slog.e(TAG, "saveImage: unable to save " + filename, e);
                     } finally {
-                        if (imageFile != null) {
-                            try {
-                                imageFile.close();
-                            } catch (IOException e) {
-                            }
-                        }
+                        IoUtils.closeQuietly(imageFile);
                     }
                 } else if (item instanceof TaskWriteQueueItem) {
                     // Write out one task.
                     StringWriter stringWriter = null;
                     TaskRecord task = ((TaskWriteQueueItem) item).mTask;
-                    if (DEBUG) Slog.d(TAG, "Writing task=" + task);
+                    if (DEBUG_PERSISTER) Slog.d(TAG, "Writing task=" + task);
                     synchronized (mService) {
                         if (task.inRecents) {
                             // Still there.
                             try {
-                                if (DEBUG) Slog.d(TAG, "Saving task=" + task);
+                                if (DEBUG_PERSISTER) Slog.d(TAG, "Saving task=" + task);
                                 stringWriter = saveToXml(task);
                             } catch (IOException e) {
                             } catch (XmlPullParserException e) {
@@ -594,4 +981,100 @@
             }
         }
     }
+
+    /**
+     * 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;
+
+        private OtherDeviceTask(
+                File file, ComponentName componentName, int taskId, int affiliatedTaskId) {
+            mFile = file;
+            mComponentName = componentName;
+            mTaskId = taskId;
+            mAffiliatedTaskId = (affiliatedTaskId == INVALID_TASK_ID) ? taskId: affiliatedTaskId;
+        }
+
+        @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)) {
+                        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;
+                        }
+                        if (DEBUG_RESTORER) Slog.d(TAG, "creating OtherDeviceTask from file="
+                                + file.getName() + " componentName=" + componentName
+                                + " taskId=" + taskId);
+                        return new OtherDeviceTask(file, componentName, taskId, taskAffiliation);
+                    } 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;
+        }
+    }
 }
