blob: 07c3cdbcbec03d5f7b556cbdaebe7b229d05d825 [file] [log] [blame]
Steve McKayfefcd702015-08-20 16:19:38 +00001/*
2 * Copyright (C) 2015 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
Steve McKay17f7e582016-04-04 15:26:48 -070019import android.app.AlertDialog;
Ben Kwa91923182015-08-27 16:06:33 -070020import android.content.Context;
Steve McKay17f7e582016-04-04 15:26:48 -070021import android.content.Intent;
Aga Wronska741ac6f2016-03-02 16:00:22 -080022import android.content.res.Configuration;
Steve McKay17f7e582016-04-04 15:26:48 -070023import android.provider.DocumentsContract;
Steve McKay55c00e72016-02-18 15:32:16 -080024import android.text.TextUtils;
Ben Kwa8e3fd762015-12-17 10:37:00 -080025import android.text.format.DateUtils;
26import android.text.format.Time;
Aga Wronska741ac6f2016-03-02 16:00:22 -080027import android.view.WindowManager;
Aga Wronska6d50bcc2016-03-28 17:27:02 -070028
Steve McKay55c00e72016-02-18 15:32:16 -080029import java.text.Collator;
Steve McKayc83baa02016-01-06 18:32:13 -080030import java.util.ArrayList;
31import java.util.List;
32
Steve McKay4d0255f2015-09-25 16:02:56 -070033/** @hide */
Steve McKayfefcd702015-08-20 16:19:38 +000034public final class Shared {
Steve McKay55c00e72016-02-18 15:32:16 -080035
Steve McKay0af8afd2016-02-25 13:34:03 -080036 public static final String TAG = "Documents";
37
Ben Kwa543a2922016-03-22 11:11:46 -070038 public static final boolean DEBUG = false;
Steve McKay0af8afd2016-02-25 13:34:03 -080039
Ben Kwaae967802015-09-25 14:48:29 -070040 /** Intent action name to pick a copy destination. */
41 public static final String ACTION_PICK_COPY_DESTINATION =
42 "com.android.documentsui.PICK_COPY_DESTINATION";
43
44 /**
Steve McKay17f7e582016-04-04 15:26:48 -070045 * Extra flag allowing app to be opened in productivity mode (less downloadsy).
46 * Useful developers and the likes. When set to true overrides the default
47 * config value of productivity_device.
48 */
49 public static final String EXTRA_PRODUCTIVITY_MODE = "com.android.documentsui.PRODUCTIVITY";
50
51 /**
Ben Kwaae967802015-09-25 14:48:29 -070052 * Extra boolean flag for {@link ACTION_PICK_COPY_DESTINATION}, which
53 * specifies if the destination directory needs to create new directory or not.
54 */
55 public static final String EXTRA_DIRECTORY_COPY = "com.android.documentsui.DIRECTORY_COPY";
Steve McKay17f7e582016-04-04 15:26:48 -070056
57 /**
58 * Extra flag used to store the current stack so user opens in right spot.
59 */
Aga Wronskaaf5ace52016-02-17 13:50:42 -080060 public static final String EXTRA_STACK = "com.android.documentsui.STACK";
61
62 /**
63 * Extra flag used to store query of type String in the bundle.
64 */
65 public static final String EXTRA_QUERY = "query";
66
67 /**
68 * Extra flag used to store state of type State in the bundle.
69 */
70 public static final String EXTRA_STATE = "state";
71
72 /**
73 * Extra flag used to store type of DirectoryFragment's type ResultType type in the bundle.
74 */
75 public static final String EXTRA_TYPE = "type";
76
77 /**
78 * Extra flag used to store root of type RootInfo in the bundle.
79 */
80 public static final String EXTRA_ROOT = "root";
81
82 /**
83 * Extra flag used to store document of DocumentInfo type in the bundle.
84 */
85 public static final String EXTRA_DOC = "document";
86
87 /**
88 * Extra flag used to store DirectoryFragment's selection of Selection type in the bundle.
89 */
90 public static final String EXTRA_SELECTION = "selection";
91
92 /**
93 * Extra flag used to store DirectoryFragment's search mode of boolean type in the bundle.
94 */
95 public static final String EXTRA_SEARCH_MODE = "searchMode";
96
97 /**
98 * Extra flag used to store DirectoryFragment's ignore state of boolean type in the bundle.
99 */
100 public static final String EXTRA_IGNORE_STATE = "ignoreState";
Ben Kwaae967802015-09-25 14:48:29 -0700101
Tomasz Mikolajewskib8373c22016-03-15 17:41:31 +0900102 /**
103 * Extra for an Intent for enabling performance benchmark. Used only by tests.
104 */
105 public static final String EXTRA_BENCHMARK = "com.android.documentsui.benchmark";
106
Tomasz Mikolajewski2ccad1e2016-04-11 11:06:16 +0900107 /**
108 * Maximum number of items in a Binder transaction packet.
109 */
110 public static final int MAX_DOCS_IN_INTENT = 1000;
111
Steve McKay55c00e72016-02-18 15:32:16 -0800112 private static final Collator sCollator;
113
114 static {
115 sCollator = Collator.getInstance();
116 sCollator.setStrength(Collator.SECONDARY);
117 }
118
Ben Kwa91923182015-08-27 16:06:33 -0700119 /**
120 * Generates a formatted quantity string.
121 */
122 public static final String getQuantityString(Context context, int resourceId, int quantity) {
123 return context.getResources().getQuantityString(resourceId, quantity, quantity);
124 }
Ben Kwa8e3fd762015-12-17 10:37:00 -0800125
126 public static String formatTime(Context context, long when) {
127 // TODO: DateUtils should make this easier
128 Time then = new Time();
129 then.set(when);
130 Time now = new Time();
131 now.setToNow();
132
133 int flags = DateUtils.FORMAT_NO_NOON | DateUtils.FORMAT_NO_MIDNIGHT
134 | DateUtils.FORMAT_ABBREV_ALL;
135
136 if (then.year != now.year) {
137 flags |= DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_SHOW_DATE;
138 } else if (then.yearDay != now.yearDay) {
139 flags |= DateUtils.FORMAT_SHOW_DATE;
140 } else {
141 flags |= DateUtils.FORMAT_SHOW_TIME;
142 }
143
144 return DateUtils.formatDateTime(context, when, flags);
145 }
146
Steve McKayc83baa02016-01-06 18:32:13 -0800147 /**
148 * A convenient way to transform any list into a (parcelable) ArrayList.
149 * Uses cast if possible, else creates a new list with entries from {@code list}.
150 */
151 public static <T> ArrayList<T> asArrayList(List<T> list) {
152 return list instanceof ArrayList
153 ? (ArrayList<T>) list
154 : new ArrayList<T>(list);
155 }
Steve McKay55c00e72016-02-18 15:32:16 -0800156
157 /**
158 * Compare two strings against each other using system default collator in a
Tomasz Mikolajewski16da9b32016-03-16 11:02:06 +0900159 * case-insensitive mode.
Steve McKay55c00e72016-02-18 15:32:16 -0800160 */
161 public static int compareToIgnoreCaseNullable(String lhs, String rhs) {
162 final boolean leftEmpty = TextUtils.isEmpty(lhs);
163 final boolean rightEmpty = TextUtils.isEmpty(rhs);
164
165 if (leftEmpty && rightEmpty) return 0;
166 if (leftEmpty) return -1;
167 if (rightEmpty) return 1;
168
Steve McKay55c00e72016-02-18 15:32:16 -0800169 return sCollator.compare(lhs, rhs);
170 }
Aga Wronska741ac6f2016-03-02 16:00:22 -0800171
Tomasz Mikolajewski985df3d2016-03-15 15:38:54 +0900172 /**
173 * Compare two strings against each other using system default collator in a
174 * case-insensitive mode.
175 */
176 public static int compareToIgnoreCase(String lhs, String rhs) {
177 return sCollator.compare(lhs, rhs);
178 }
179
Aga Wronska741ac6f2016-03-02 16:00:22 -0800180 public static boolean isHardwareKeyboardAvailable(Context context) {
181 return context.getResources().getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS;
182 }
183
184 public static void ensureKeyboardPresent(Context context, AlertDialog dialog) {
185 if (!isHardwareKeyboardAvailable(context)) {
186 dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
187 }
188 }
189
Aga Wronska64ae1f42016-03-22 14:18:43 -0700190 /*
Steve McKay17f7e582016-04-04 15:26:48 -0700191 * Returns true if app is running in "productivity mode".
Aga Wronska64ae1f42016-03-22 14:18:43 -0700192 */
Steve McKay17f7e582016-04-04 15:26:48 -0700193 public static boolean productivityMode(Context context) {
194 return context.getResources().getBoolean(R.bool.productivity_device);
Aga Wronska64ae1f42016-03-22 14:18:43 -0700195 }
196
Steve McKay17f7e582016-04-04 15:26:48 -0700197 /*
198 * Returns true if app is running in "productivity mode".
199 */
200 private static boolean isProductivityMode(Context context, Intent intent) {
201 return intent.getBooleanExtra(
202 Shared.EXTRA_PRODUCTIVITY_MODE,
203 context.getResources().getBoolean(R.bool.productivity_device));
204 }
205
206 /*
207 * Returns true if "Documents" root should be shown.
208 */
209 public static boolean shouldShowDocumentsRoot(Context context, Intent intent) {
210 return isProductivityMode(context, intent);
211 }
212
213 /*
214 * Returns true if device root should be shown.
215 */
216 public static boolean shouldShowDeviceRoot(Context context, Intent intent) {
217 return isProductivityMode(context, intent)
218 || intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false);
219 }
Steve McKayfefcd702015-08-20 16:19:38 +0000220}