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 
17 package com.android.documentsui.base;
18 
19 import android.annotation.IntDef;
20 import android.content.Intent;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.provider.DocumentsContract;
24 import android.util.SparseArray;
25 
26 import com.android.documentsui.services.FileOperationService;
27 import com.android.documentsui.services.FileOperationService.OpType;
28 import com.android.documentsui.sorting.SortModel;
29 
30 import java.lang.annotation.Retention;
31 import java.lang.annotation.RetentionPolicy;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 
36 public class State implements android.os.Parcelable {
37 
38     private static final String TAG = "State";
39 
40     @IntDef(flag = true, value = {
41             ACTION_BROWSE,
42             ACTION_PICK_COPY_DESTINATION,
43             ACTION_OPEN,
44             ACTION_CREATE,
45             ACTION_GET_CONTENT,
46             ACTION_OPEN_TREE
47     })
48     @Retention(RetentionPolicy.SOURCE)
49     public @interface ActionType {}
50     // File manager and related private picking activity.
51     public static final int ACTION_BROWSE = 1;
52     public static final int ACTION_PICK_COPY_DESTINATION = 2;
53     // All public picking activities
54     public static final int ACTION_OPEN = 3;
55     public static final int ACTION_CREATE = 4;
56     public static final int ACTION_GET_CONTENT = 5;
57     public static final int ACTION_OPEN_TREE = 6;
58 
59     @IntDef(flag = true, value = {
60             MODE_UNKNOWN,
61             MODE_LIST,
62             MODE_GRID
63     })
64     @Retention(RetentionPolicy.SOURCE)
65     public @interface ViewMode {}
66     public static final int MODE_UNKNOWN = 0;
67     public static final int MODE_LIST = 1;
68     public static final int MODE_GRID = 2;
69 
70     public @ActionType int action;
71     public String[] acceptMimes;
72 
73     /** Derived from local preferences */
74     public @ViewMode int derivedMode = MODE_GRID;
75 
76     public boolean debugMode = false;
77 
78     /** Current sort state */
79     public SortModel sortModel;
80 
81     public boolean allowMultiple;
82     public boolean localOnly;
83     public boolean showDeviceStorageOption;
84     public boolean showAdvanced;
85 
86     // Indicates that a copy operation (or move) includes a directory.
87     // Why? Directory creation isn't supported by some roots (like Downloads).
88     // This allows us to restrict available roots to just those with support.
89     public boolean directoryCopy;
90     public boolean openableOnly;
91 
92     /**
93      * This is basically a sub-type for the copy operation. It can be either COPY,
94      * COMPRESS, EXTRACT or MOVE.
95      * The only legal values, if set, are: OPERATION_COPY, OPERATION_COMPRESS,
96      * OPERATION_EXTRACT and OPERATION_MOVE. Other pick
97      * operations don't use this. In those cases OPERATION_UNKNOWN is also legal.
98      */
99     public @OpType int copyOperationSubType = FileOperationService.OPERATION_UNKNOWN;
100 
101     /** Current user navigation stack; empty implies recents. */
102     public final DocumentStack stack = new DocumentStack();
103 
104     /** Instance configs for every shown directory */
105     public HashMap<String, SparseArray<Parcelable>> dirConfigs = new HashMap<>();
106 
107     /** Name of the package that started DocsUI */
108     public List<String> excludedAuthorities = new ArrayList<>();
109 
initAcceptMimes(Intent intent, String defaultAcceptMimeType)110     public void initAcceptMimes(Intent intent, String defaultAcceptMimeType) {
111         if (intent.hasExtra(Intent.EXTRA_MIME_TYPES)) {
112             acceptMimes = intent.getStringArrayExtra(Intent.EXTRA_MIME_TYPES);
113         } else {
114             acceptMimes = new String[] { defaultAcceptMimeType };
115         }
116     }
117 
118     @Override
describeContents()119     public int describeContents() {
120         return 0;
121     }
122 
123     @Override
writeToParcel(Parcel out, int flags)124     public void writeToParcel(Parcel out, int flags) {
125         out.writeInt(action);
126         out.writeStringArray(acceptMimes);
127         out.writeInt(allowMultiple ? 1 : 0);
128         out.writeInt(localOnly ? 1 : 0);
129         out.writeInt(showDeviceStorageOption ? 1 : 0);
130         out.writeInt(showAdvanced ? 1 : 0);
131         DurableUtils.writeToParcel(out, stack);
132         out.writeMap(dirConfigs);
133         out.writeList(excludedAuthorities);
134         out.writeInt(openableOnly ? 1 : 0);
135         out.writeParcelable(sortModel, 0);
136     }
137 
138     public static final ClassLoaderCreator<State> CREATOR = new ClassLoaderCreator<State>() {
139         @Override
140         public State createFromParcel(Parcel in) {
141             return createFromParcel(in, null);
142         }
143 
144         @Override
145         public State createFromParcel(Parcel in, ClassLoader loader) {
146             final State state = new State();
147             state.action = in.readInt();
148             state.acceptMimes = in.readStringArray();
149             state.allowMultiple = in.readInt() != 0;
150             state.localOnly = in.readInt() != 0;
151             state.showDeviceStorageOption = in.readInt() != 0;
152             state.showAdvanced = in.readInt() != 0;
153             DurableUtils.readFromParcel(in, state.stack);
154             in.readMap(state.dirConfigs, loader);
155             in.readList(state.excludedAuthorities, loader);
156             state.openableOnly = in.readInt() != 0;
157             state.sortModel = in.readParcelable(loader);
158             return state;
159         }
160 
161         @Override
162         public State[] newArray(int size) {
163             return new State[size];
164         }
165     };
166 }
167