@Override
 public void writeToParcel(Parcel out, int flags) {
   out.writeInt(action);
   out.writeInt(userMode);
   out.writeStringArray(acceptMimes);
   out.writeInt(userSortOrder);
   out.writeInt(allowMultiple ? 1 : 0);
   out.writeInt(showSize ? 1 : 0);
   out.writeInt(localOnly ? 1 : 0);
   out.writeInt(forceAdvanced ? 1 : 0);
   out.writeInt(showAdvanced ? 1 : 0);
   out.writeInt(stackTouched ? 1 : 0);
   out.writeInt(restored ? 1 : 0);
   DurableUtils.writeToParcel(out, stack);
   out.writeString(currentSearch);
   out.writeMap(dirState);
 }
 @Override
 public State createFromParcel(Parcel in) {
   final State state = new State();
   state.action = in.readInt();
   state.userMode = in.readInt();
   state.acceptMimes = in.readStringArray();
   state.userSortOrder = in.readInt();
   state.allowMultiple = in.readInt() != 0;
   state.showSize = in.readInt() != 0;
   state.localOnly = in.readInt() != 0;
   state.forceAdvanced = in.readInt() != 0;
   state.showAdvanced = in.readInt() != 0;
   state.stackTouched = in.readInt() != 0;
   state.restored = in.readInt() != 0;
   DurableUtils.readFromParcel(in, state.stack);
   state.currentSearch = in.readString();
   in.readMap(state.dirState, null);
   return state;
 }
  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 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;
 }