blob: b3db037697f35a09af190ca24912350e82d3f3ae [file] [log] [blame]
Jeff Sharkey669f8e72014-08-08 15:10:03 -07001/*
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
Steve McKay3eb2d072016-01-25 19:00:22 -080019import static com.android.documentsui.State.MODE_UNKNOWN;
Steve McKay3eb2d072016-01-25 19:00:22 -080020
Felipe Lemeadccb992016-03-09 17:40:49 -080021import android.annotation.IntDef;
22import android.annotation.Nullable;
Jeff Sharkey669f8e72014-08-08 15:10:03 -070023import android.content.Context;
Felipe Lemeadccb992016-03-09 17:40:49 -080024import android.content.SharedPreferences;
Felipe Leme7e455412016-08-17 13:39:10 -070025import android.content.SharedPreferences.Editor;
Felipe Lemeadccb992016-03-09 17:40:49 -080026import android.os.UserHandle;
Jeff Sharkey669f8e72014-08-08 15:10:03 -070027import android.preference.PreferenceManager;
28
Steve McKaydd274442016-06-20 11:46:56 -070029import com.android.documentsui.State.ActionType;
Steve McKay3eb2d072016-01-25 19:00:22 -080030import com.android.documentsui.State.ViewMode;
31import com.android.documentsui.model.RootInfo;
32
Steve McKaydd274442016-06-20 11:46:56 -070033import java.lang.annotation.Retention;
34import java.lang.annotation.RetentionPolicy;
35
Jeff Sharkey669f8e72014-08-08 15:10:03 -070036public class LocalPreferences {
Jeff Sharkey669f8e72014-08-08 15:10:03 -070037 private static final String KEY_FILE_SIZE = "fileSize";
Steve McKaydd274442016-06-20 11:46:56 -070038 private static final String INCLUDE_DEVICE_ROOT = "includeDeviceRoot-";
Steve McKay3eb2d072016-01-25 19:00:22 -080039 private static final String ROOT_VIEW_MODE_PREFIX = "rootViewMode-";
Jeff Sharkey669f8e72014-08-08 15:10:03 -070040
Jeff Sharkey669f8e72014-08-08 15:10:03 -070041 public static boolean getDisplayFileSize(Context context) {
Felipe Lemeadccb992016-03-09 17:40:49 -080042 return getPrefs(context).getBoolean(KEY_FILE_SIZE, false);
Jeff Sharkey669f8e72014-08-08 15:10:03 -070043 }
44
Felipe Lemeadccb992016-03-09 17:40:49 -080045 public static @ViewMode int getViewMode(Context context, RootInfo root,
46 @ViewMode int fallback) {
47 return getPrefs(context).getInt(createKey(root), fallback);
Steve McKay3eb2d072016-01-25 19:00:22 -080048 }
49
Jeff Sharkey669f8e72014-08-08 15:10:03 -070050 public static void setDisplayFileSize(Context context, boolean display) {
Felipe Lemeadccb992016-03-09 17:40:49 -080051 getPrefs(context).edit().putBoolean(KEY_FILE_SIZE, display).apply();
Jeff Sharkey669f8e72014-08-08 15:10:03 -070052 }
Steve McKay3eb2d072016-01-25 19:00:22 -080053
Steve McKaydd274442016-06-20 11:46:56 -070054 public static boolean getShowDeviceRoot(Context context, @ActionType int action) {
55 return getPrefs(context).getBoolean(INCLUDE_DEVICE_ROOT + action, false);
56 }
57
58 public static void setShowDeviceRoot(
59 Context context, @ActionType int action, boolean display) {
60 getPrefs(context).edit().putBoolean(INCLUDE_DEVICE_ROOT + action, display).apply();
61 }
62
Steve McKay3eb2d072016-01-25 19:00:22 -080063 public static void setViewMode(Context context, RootInfo root, @ViewMode int viewMode) {
Steve McKaya1f76802016-02-25 13:34:03 -080064 assert(viewMode != MODE_UNKNOWN);
Felipe Lemeadccb992016-03-09 17:40:49 -080065 getPrefs(context).edit().putInt(createKey(root), viewMode).apply();
66 }
67
68 private static SharedPreferences getPrefs(Context context) {
69 return PreferenceManager.getDefaultSharedPreferences(context);
Steve McKay3eb2d072016-01-25 19:00:22 -080070 }
71
72 private static String createKey(RootInfo root) {
73 return ROOT_VIEW_MODE_PREFIX + root.authority + root.rootId;
74 }
Felipe Lemeadccb992016-03-09 17:40:49 -080075
76 public static final int PERMISSION_ASK = 0;
77 public static final int PERMISSION_ASK_AGAIN = 1;
78 public static final int PERMISSION_NEVER_ASK = -1;
79
80 @IntDef(flag = true, value = {
81 PERMISSION_ASK,
82 PERMISSION_ASK_AGAIN,
83 PERMISSION_NEVER_ASK,
84 })
85 @Retention(RetentionPolicy.SOURCE)
86 public @interface PermissionStatus {}
87
88 /**
Felipe Leme7e455412016-08-17 13:39:10 -070089 * Clears all preferences associated with a given package.
90 *
91 * <p>Typically called when a package is removed or when user asked to clear its data.
92 */
93 static void clearPackagePreferences(Context context, String packageName) {
94 clearScopedAccessPreferences(context, packageName);
95 }
96
97 /**
Felipe Lemeadccb992016-03-09 17:40:49 -080098 * Methods below are used to keep track of denied user requests on scoped directory access so
99 * the dialog is not offered when user checked the 'Do not ask again' box
100 *
101 * <p>It uses a shared preferences, whose key is:
102 * <ol>
103 * <li>{@code USER_ID|PACKAGE_NAME|VOLUME_UUID|DIRECTORY} for storage volumes that have a UUID
104 * (typically physical volumes like SD cards).
105 * <li>{@code USER_ID|PACKAGE_NAME||DIRECTORY} for storage volumes that do not have a UUID
106 * (typically the emulated volume used for primary storage
107 * </ol>
108 */
109 static @PermissionStatus int getScopedAccessPermissionStatus(Context context,
110 String packageName, @Nullable String uuid, String directory) {
111 final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
112 return getPrefs(context).getInt(key, PERMISSION_ASK);
113 }
114
115 static void setScopedAccessPermissionStatus(Context context, String packageName,
116 @Nullable String uuid, String directory, @PermissionStatus int status) {
117 final String key = getScopedAccessDenialsKey(packageName, uuid, directory);
118 getPrefs(context).edit().putInt(key, status).apply();
119 }
120
Felipe Leme7e455412016-08-17 13:39:10 -0700121 private static void clearScopedAccessPreferences(Context context, String packageName) {
122 final String keySubstring = "|" + packageName + "|";
123 final SharedPreferences prefs = getPrefs(context);
124 Editor editor = null;
125 for (final String key : prefs.getAll().keySet()) {
126 if (key.contains(keySubstring)) {
127 if (editor == null) {
128 editor = prefs.edit();
129 }
130 editor.remove(key);
131 }
132 }
133 if (editor != null) {
134 editor.apply();
135 }
136 }
137
Felipe Lemeadccb992016-03-09 17:40:49 -0800138 private static String getScopedAccessDenialsKey(String packageName, String uuid,
139 String directory) {
140 final int userId = UserHandle.myUserId();
141 return uuid == null
142 ? userId + "|" + packageName + "||" + directory
143 : userId + "|" + packageName + "|" + uuid + "|" + directory;
144 }
Jeff Sharkey669f8e72014-08-08 15:10:03 -0700145}