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.base;
18
19import android.annotation.IntDef;
20import android.content.Intent;
21import android.os.Parcel;
22import android.os.Parcelable;
23import android.provider.DocumentsContract;
24import android.util.SparseArray;
25
26import com.android.documentsui.services.FileOperationService;
27import com.android.documentsui.services.FileOperationService.OpType;
28import com.android.documentsui.sorting.SortModel;
29
30import java.lang.annotation.Retention;
31import java.lang.annotation.RetentionPolicy;
32import java.util.ArrayList;
33import java.util.HashMap;
34import java.util.List;
35
36public 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
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
119    public int describeContents() {
120        return 0;
121    }
122
123    @Override
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    @Override
139    public String toString() {
140        return "State{"
141                + "action=" + action
142                + ", acceptMimes=" + acceptMimes
143                + ", allowMultiple=" + allowMultiple
144                + ", localOnly=" + localOnly
145                + ", showDeviceStorageOption=" + showDeviceStorageOption
146                + ", showAdvanced=" + showAdvanced
147                + ", stack=" + stack
148                + ", dirConfigs=" + dirConfigs
149                + ", excludedAuthorities=" + excludedAuthorities
150                + ", openableOnly=" + openableOnly
151                + ", sortModel=" + sortModel
152                + "}";
153    }
154
155    public static final ClassLoaderCreator<State> CREATOR = new ClassLoaderCreator<State>() {
156        @Override
157        public State createFromParcel(Parcel in) {
158            return createFromParcel(in, null);
159        }
160
161        @Override
162        public State createFromParcel(Parcel in, ClassLoader loader) {
163            final State state = new State();
164            state.action = in.readInt();
165            state.acceptMimes = in.readStringArray();
166            state.allowMultiple = in.readInt() != 0;
167            state.localOnly = in.readInt() != 0;
168            state.showDeviceStorageOption = in.readInt() != 0;
169            state.showAdvanced = in.readInt() != 0;
170            DurableUtils.readFromParcel(in, state.stack);
171            in.readMap(state.dirConfigs, loader);
172            in.readList(state.excludedAuthorities, loader);
173            state.openableOnly = in.readInt() != 0;
174            state.sortModel = in.readParcelable(loader);
175            return state;
176        }
177
178        @Override
179        public State[] newArray(int size) {
180            return new State[size];
181        }
182    };
183}
184