Shared.java revision af5ace5d5e3a273b151e012206efd029c2872b59
1fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay/*
2fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay * Copyright (C) 2015 The Android Open Source Project
3fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay *
4fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay * Licensed under the Apache License, Version 2.0 (the "License");
5fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay * you may not use this file except in compliance with the License.
6fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay * You may obtain a copy of the License at
7fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay *
8fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay *      http://www.apache.org/licenses/LICENSE-2.0
9fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay *
10fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay * Unless required by applicable law or agreed to in writing, software
11fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay * distributed under the License is distributed on an "AS IS" BASIS,
12fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay * See the License for the specific language governing permissions and
14fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay * limitations under the License.
15fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay */
16fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay
17fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKaypackage com.android.documentsui;
18fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay
19919231857d2add3afe51f06aaf41663a252c3e0eBen Kwaimport android.content.Context;
2055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKayimport android.text.TextUtils;
218e3fd7676023738c04d099f2940a635ff0699717Ben Kwaimport android.text.format.DateUtils;
228e3fd7676023738c04d099f2940a635ff0699717Ben Kwaimport android.text.format.Time;
23919231857d2add3afe51f06aaf41663a252c3e0eBen Kwa
2455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKayimport java.text.Collator;
25c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKayimport java.util.ArrayList;
26c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKayimport java.util.List;
27c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay
284d0255f79cc92a5675d14b20f9cdf06ecb8d7109Steve McKay/** @hide */
29fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKaypublic final class Shared {
3055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
31ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa    /** Intent action name to pick a copy destination. */
32ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa    public static final String ACTION_PICK_COPY_DESTINATION =
33ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa            "com.android.documentsui.PICK_COPY_DESTINATION";
34ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa
35ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa    /**
36ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa     * Extra boolean flag for {@link ACTION_PICK_COPY_DESTINATION}, which
37ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa     * specifies if the destination directory needs to create new directory or not.
38ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa     */
39ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa    public static final String EXTRA_DIRECTORY_COPY = "com.android.documentsui.DIRECTORY_COPY";
40af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    public static final String EXTRA_STACK = "com.android.documentsui.STACK";
41af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska
42af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    /**
43af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     * Extra flag used to store query of type String in the bundle.
44af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     */
45af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    public static final String EXTRA_QUERY = "query";
46af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska
47af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    /**
48af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     * Extra flag used to store state of type State in the bundle.
49af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     */
50af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    public static final String EXTRA_STATE = "state";
51af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska
52af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    /**
53af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     * Extra flag used to store type of DirectoryFragment's type ResultType type in the bundle.
54af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     */
55af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    public static final String EXTRA_TYPE = "type";
56af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska
57af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    /**
58af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     * Extra flag used to store root of type RootInfo in the bundle.
59af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     */
60af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    public static final String EXTRA_ROOT = "root";
61af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska
62af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    /**
63af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     * Extra flag used to store document of DocumentInfo type in the bundle.
64af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     */
65af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    public static final String EXTRA_DOC = "document";
66af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska
67af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    /**
68af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     * Extra flag used to store DirectoryFragment's selection of Selection type in the bundle.
69af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     */
70af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    public static final String EXTRA_SELECTION = "selection";
71af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska
72af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    /**
73af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     * Extra flag used to store DirectoryFragment's search mode of boolean type in the bundle.
74af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     */
75af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    public static final String EXTRA_SEARCH_MODE = "searchMode";
76af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska
77af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    /**
78af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     * Extra flag used to store DirectoryFragment's ignore state of boolean type in the bundle.
79af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska     */
80af5ace5d5e3a273b151e012206efd029c2872b59Aga Wronska    public static final String EXTRA_IGNORE_STATE = "ignoreState";
81ae96780a8909476dca709b88dbae5ec9a2f0632cBen Kwa
82459bc2b19ae24e3ad09b2945f21c8397177d5720Steve McKay    public static final boolean DEBUG = true;
83fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay    public static final String TAG = "Documents";
84919231857d2add3afe51f06aaf41663a252c3e0eBen Kwa
8555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
8655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay    /**
8755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay     * String prefix used to indicate the document is a directory.
8855c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay     */
8955c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay    public static final char DIR_PREFIX = '\001';
9055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
9155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay    private static final Collator sCollator;
9255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
9355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay    static {
9455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        sCollator = Collator.getInstance();
9555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        sCollator.setStrength(Collator.SECONDARY);
9655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay    }
9755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
98919231857d2add3afe51f06aaf41663a252c3e0eBen Kwa    /**
99919231857d2add3afe51f06aaf41663a252c3e0eBen Kwa     * Generates a formatted quantity string.
100919231857d2add3afe51f06aaf41663a252c3e0eBen Kwa     */
101919231857d2add3afe51f06aaf41663a252c3e0eBen Kwa    public static final String getQuantityString(Context context, int resourceId, int quantity) {
102919231857d2add3afe51f06aaf41663a252c3e0eBen Kwa        return context.getResources().getQuantityString(resourceId, quantity, quantity);
103919231857d2add3afe51f06aaf41663a252c3e0eBen Kwa    }
1048e3fd7676023738c04d099f2940a635ff0699717Ben Kwa
1058e3fd7676023738c04d099f2940a635ff0699717Ben Kwa    public static String formatTime(Context context, long when) {
1068e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        // TODO: DateUtils should make this easier
1078e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        Time then = new Time();
1088e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        then.set(when);
1098e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        Time now = new Time();
1108e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        now.setToNow();
1118e3fd7676023738c04d099f2940a635ff0699717Ben Kwa
1128e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT
1138e3fd7676023738c04d099f2940a635ff0699717Ben Kwa                | DateUtils.FORMAT_ABBREV_ALL;
1148e3fd7676023738c04d099f2940a635ff0699717Ben Kwa
1158e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        if (then.year != now.year) {
1168e3fd7676023738c04d099f2940a635ff0699717Ben Kwa            flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
1178e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        } else if (then.yearDay != now.yearDay) {
1188e3fd7676023738c04d099f2940a635ff0699717Ben Kwa            flags |= DateUtils.FORMAT_SHOW_DATE;
1198e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        } else {
1208e3fd7676023738c04d099f2940a635ff0699717Ben Kwa            flags |= DateUtils.FORMAT_SHOW_TIME;
1218e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        }
1228e3fd7676023738c04d099f2940a635ff0699717Ben Kwa
1238e3fd7676023738c04d099f2940a635ff0699717Ben Kwa        return DateUtils.formatDateTime(context, when, flags);
1248e3fd7676023738c04d099f2940a635ff0699717Ben Kwa    }
1258e3fd7676023738c04d099f2940a635ff0699717Ben Kwa
126c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay    /**
127c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay     * A convenient way to transform any list into a (parcelable) ArrayList.
128c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay     * Uses cast if possible, else creates a new list with entries from {@code list}.
129c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay     */
130c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay    public static <T> ArrayList<T> asArrayList(List<T> list) {
131c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay        return list instanceof ArrayList
132c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay            ? (ArrayList<T>) list
133c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay            : new ArrayList<T>(list);
134c83baa0574ee9e34c0e06bda1ff08928d880ee36Steve McKay    }
13555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
13655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay    /**
13755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay     * Compare two strings against each other using system default collator in a
13855c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay     * case-insensitive mode. Clusters strings prefixed with {@link DIR_PREFIX}
13955c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay     * before other items.
14055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay     */
14155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay    public static int compareToIgnoreCaseNullable(String lhs, String rhs) {
14255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        final boolean leftEmpty = TextUtils.isEmpty(lhs);
14355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        final boolean rightEmpty = TextUtils.isEmpty(rhs);
14455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
14555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        if (leftEmpty && rightEmpty) return 0;
14655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        if (leftEmpty) return -1;
14755c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        if (rightEmpty) return 1;
14855c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
14955c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        final boolean leftDir = (lhs.charAt(0) == DIR_PREFIX);
15055c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        final boolean rightDir = (rhs.charAt(0) == DIR_PREFIX);
15155c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
15255c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        if (leftDir && !rightDir) return -1;
15355c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        if (rightDir && !leftDir) return 1;
15455c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay
15555c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay        return sCollator.compare(lhs, rhs);
15655c00e7356d9f76e7378cf7c701b9a41cb7be6daSteve McKay    }
157fefcd700d6b4cf1c4402af74c50fb0e762472901Steve McKay}
158