State.java revision 82ae18c87784b5989c1529b97214d63e5d9d3742
1/* 2 * Copyright (C) 2013 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 17package com.android.documentsui; 18 19import static com.android.documentsui.Shared.DEBUG; 20 21import android.annotation.IntDef; 22import android.content.Intent; 23import android.os.Parcel; 24import android.os.Parcelable; 25import android.util.Log; 26import android.util.SparseArray; 27 28import com.android.documentsui.dirlist.MultiSelectManager.Selection; 29import com.android.documentsui.model.DocumentInfo; 30import com.android.documentsui.model.DocumentStack; 31import com.android.documentsui.model.DurableUtils; 32import com.android.documentsui.model.RootInfo; 33import com.android.documentsui.services.FileOperationService; 34import com.android.documentsui.services.FileOperationService.OpType; 35 36import java.lang.annotation.Retention; 37import java.lang.annotation.RetentionPolicy; 38import java.util.ArrayList; 39import java.util.HashMap; 40import java.util.List; 41 42public class State implements android.os.Parcelable { 43 44 private static final String TAG = "State"; 45 46 // File manager and related private picking activity. 47 public static final int ACTION_BROWSE = 1; 48 public static final int ACTION_PICK_COPY_DESTINATION = 2; 49 50 // All public picking activities 51 public static final int ACTION_OPEN = 3; 52 public static final int ACTION_CREATE = 4; 53 public static final int ACTION_GET_CONTENT = 5; 54 public static final int ACTION_OPEN_TREE = 6; 55 56 @IntDef(flag = true, value = { 57 MODE_UNKNOWN, 58 MODE_LIST, 59 MODE_GRID 60 }) 61 @Retention(RetentionPolicy.SOURCE) 62 public @interface ViewMode {} 63 public static final int MODE_UNKNOWN = 0; 64 public static final int MODE_LIST = 1; 65 public static final int MODE_GRID = 2; 66 67 public static final int SORT_ORDER_UNKNOWN = 0; 68 public static final int SORT_ORDER_DISPLAY_NAME = 1; 69 public static final int SORT_ORDER_LAST_MODIFIED = 2; 70 public static final int SORT_ORDER_SIZE = 3; 71 72 public int action; 73 public String[] acceptMimes; 74 75 /** Derived from local preferences */ 76 public @ViewMode int derivedMode = MODE_GRID; 77 78 /** Explicit user choice */ 79 public int userSortOrder = SORT_ORDER_UNKNOWN; 80 /** Derived after loader */ 81 public int derivedSortOrder = SORT_ORDER_DISPLAY_NAME; 82 83 public boolean allowMultiple; 84 public boolean forceSize; 85 public boolean showSize; 86 public boolean localOnly; 87 public boolean restored; 88 89 // Indicates that a copy operation (or move) includes a directory. 90 // Why? Directory creation isn't supported by some roots (like Downloads). 91 // This allows us to restrict available roots to just those with support. 92 public boolean directoryCopy; 93 public boolean openableOnly; 94 95 /** 96 * This is basically a sub-type for the copy operation. It can be either COPY or MOVE. 97 * The only legal values, if set, are: OPERATION_COPY, OPERATION_MOVE. Other pick 98 * operations don't use this. In those cases OPERATION_UNKNOWN is also legal. 99 */ 100 public @OpType int copyOperationSubType = FileOperationService.OPERATION_UNKNOWN; 101 102 /** Current user navigation stack; empty implies recents. */ 103 public DocumentStack stack = new DocumentStack(); 104 private boolean mStackTouched; 105 private boolean mInitialRootChanged; 106 private boolean mInitialDocChanged; 107 108 /** Instance state for every shown directory */ 109 public HashMap<String, SparseArray<Parcelable>> dirState = new HashMap<>(); 110 111 /** UI selection */ 112 public Selection selectedDocuments = new Selection(); 113 114 /** Currently copying file */ 115 public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<>(); 116 117 /** Name of the package that started DocsUI */ 118 public List<String> excludedAuthorities = new ArrayList<>(); 119 120 public void initAcceptMimes(Intent intent) { 121 if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) { 122 acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES); 123 } else { 124 String glob = intent.getType(); 125 acceptMimes = new String[] { glob != null ? glob : "*/*" }; 126 } 127 } 128 129 public void onRootChanged(RootInfo root) { 130 if (DEBUG) Log.d(TAG, "Root changed to: " + root); 131 if (!mInitialRootChanged && stack.root != null && !root.equals(stack.root)) { 132 mInitialRootChanged = true; 133 } 134 stack.root = root; 135 stack.clear(); 136 mStackTouched = true; 137 } 138 139 public void pushDocument(DocumentInfo info) { 140 if (DEBUG) Log.d(TAG, "Adding doc to stack: " + info); 141 if (!mInitialDocChanged && stack.size() > 0 && !info.equals(stack.peek())) { 142 mInitialDocChanged = true; 143 } 144 stack.push(info); 145 mStackTouched = true; 146 } 147 148 public void popDocument() { 149 if (DEBUG) Log.d(TAG, "Popping doc off stack."); 150 stack.pop(); 151 mStackTouched = true; 152 } 153 154 public void setStack(DocumentStack stack) { 155 if (DEBUG) Log.d(TAG, "Setting the whole darn stack to: " + stack); 156 this.stack = stack; 157 mStackTouched = true; 158 } 159 160 // This will return true even when the initial location is set. 161 // To get a read on if the user has changed something, use #hasInitialLocationChanged. 162 public boolean hasLocationChanged() { 163 return mStackTouched; 164 } 165 166 public boolean hasInitialLocationChanged() { 167 return mInitialRootChanged || mInitialDocChanged; 168 } 169 170 @Override 171 public int describeContents() { 172 return 0; 173 } 174 175 @Override 176 public void writeToParcel(Parcel out, int flags) { 177 out.writeInt(action); 178 out.writeStringArray(acceptMimes); 179 out.writeInt(userSortOrder); 180 out.writeInt(allowMultiple ? 1 : 0); 181 out.writeInt(forceSize ? 1 : 0); 182 out.writeInt(showSize ? 1 : 0); 183 out.writeInt(localOnly ? 1 : 0); 184 out.writeInt(restored ? 1 : 0); 185 DurableUtils.writeToParcel(out, stack); 186 out.writeMap(dirState); 187 out.writeParcelable(selectedDocuments, 0); 188 out.writeList(selectedDocumentsForCopy); 189 out.writeList(excludedAuthorities); 190 out.writeInt(openableOnly ? 1 : 0); 191 out.writeInt(mStackTouched ? 1 : 0); 192 out.writeInt(mInitialRootChanged ? 1 : 0); 193 out.writeInt(mInitialDocChanged ? 1 : 0); 194 } 195 196 public static final ClassLoaderCreator<State> CREATOR = new ClassLoaderCreator<State>() { 197 @Override 198 public State createFromParcel(Parcel in) { 199 return createFromParcel(in, null); 200 } 201 202 @Override 203 public State createFromParcel(Parcel in, ClassLoader loader) { 204 final State state = new State(); 205 state.action = in.readInt(); 206 state.acceptMimes = in.readStringArray(); 207 state.userSortOrder = in.readInt(); 208 state.allowMultiple = in.readInt() != 0; 209 state.forceSize = in.readInt() != 0; 210 state.showSize = in.readInt() != 0; 211 state.localOnly = in.readInt() != 0; 212 state.restored = in.readInt() != 0; 213 DurableUtils.readFromParcel(in, state.stack); 214 in.readMap(state.dirState, loader); 215 state.selectedDocuments = in.readParcelable(loader); 216 in.readList(state.selectedDocumentsForCopy, loader); 217 in.readList(state.excludedAuthorities, loader); 218 state.openableOnly = in.readInt() != 0; 219 state.mStackTouched = in.readInt() != 0; 220 state.mInitialRootChanged = in.readInt() != 0; 221 state.mInitialDocChanged = in.readInt() != 0; 222 return state; 223 } 224 225 @Override 226 public State[] newArray(int size) { 227 return new State[size]; 228 } 229 }; 230} 231