private void saveStackBlocking() {
    final ContentResolver resolver = getContentResolver();
    final ContentValues values = new ContentValues();

    final byte[] rawStack = DurableUtils.writeToArrayOrNull(mState.stack);
    if (mState.action == ACTION_CREATE || mState.action == ACTION_OPEN_TREE) {
      // Remember stack for last create
      values.clear();
      values.put(RecentColumns.KEY, mState.stack.buildKey());
      values.put(RecentColumns.STACK, rawStack);
      resolver.insert(RecentsProvider.buildRecent(), values);
    }

    // Remember location for next app launch
    final String packageName = getCallingPackageMaybeExtra();
    values.clear();
    values.put(ResumeColumns.STACK, rawStack);
    values.put(ResumeColumns.EXTERNAL, 0);
    resolver.insert(RecentsProvider.buildResume(packageName), values);
  }
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d(TAG, "onActivityResult() resultCode=" + resultCode + ", data=" + data);

    // Only relay back results when not canceled; otherwise stick around to
    // let the user pick another app/backend.
    if (requestCode == CODE_FORWARD && resultCode != RESULT_CANCELED) {

      // Remember that we last picked via external app
      final String packageName = getCallingPackageMaybeExtra();
      final ContentValues values = new ContentValues();
      values.put(ResumeColumns.EXTERNAL, 1);
      getContentResolver().insert(RecentsProvider.buildResume(packageName), values);

      // Pass back result to original caller
      setResult(resultCode, data);
      finish();
    } else {
      super.onActivityResult(requestCode, resultCode, data);
    }
  }
 @Override
 protected Void doInBackground(Void... params) {
   // Restore last stack for calling package
   final String packageName = getCallingPackageMaybeExtra();
   final Cursor cursor =
       getContentResolver()
           .query(RecentsProvider.buildResume(packageName), null, null, null, null);
   try {
     if (cursor.moveToFirst()) {
       mExternal = cursor.getInt(cursor.getColumnIndex(ResumeColumns.EXTERNAL)) != 0;
       final byte[] rawStack = cursor.getBlob(cursor.getColumnIndex(ResumeColumns.STACK));
       /// M: modify stack on UI thread @{
       DurableUtils.readFromArray(rawStack, mStack);
       mRestoredStack = true;
       mShouldReset = true;
       /// @}
     }
   } catch (IOException e) {
     Log.w(TAG, "Failed to resume: " + e);
   } finally {
     IoUtils.closeQuietly(cursor);
   }
   /// M: modify stack on UI thread @{
   if (mRestoredStack) {
     // Update the restored stack to ensure we have freshest data
     final Collection<RootInfo> matchingRoots = mRoots.getMatchingRootsBlocking(mState);
     try {
       mStack.updateRoot(matchingRoots);
       mStack.updateDocuments(getContentResolver());
     } catch (FileNotFoundException e) {
       Log.w(TAG, "Failed to restore stack: " + e);
       mStack.reset();
       mRestoredStack = false;
     }
   }
   /// @}
   return null;
 }