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; 18 19 import static com.android.documentsui.State.MODE_UNKNOWN; 20 21 import android.annotation.IntDef; 22 import android.annotation.Nullable; 23 import android.content.Context; 24 import android.content.SharedPreferences; 25 import android.os.UserHandle; 26 import android.preference.PreferenceManager; 27 28 import com.android.documentsui.State.ActionType; 29 import com.android.documentsui.State.ViewMode; 30 import com.android.documentsui.model.RootInfo; 31 32 import java.lang.annotation.Retention; 33 import java.lang.annotation.RetentionPolicy; 34 35 public class LocalPreferences { 36 private static final String KEY_FILE_SIZE = "fileSize"; 37 private static final String INCLUDE_DEVICE_ROOT = "includeDeviceRoot-"; 38 private static final String ROOT_VIEW_MODE_PREFIX = "rootViewMode-"; 39 getDisplayFileSize(Context context)40 public static boolean getDisplayFileSize(Context context) { 41 return getPrefs(context).getBoolean(KEY_FILE_SIZE, false); 42 } 43 getViewMode(Context context, RootInfo root, @ViewMode int fallback)44 public static @ViewMode int getViewMode(Context context, RootInfo root, 45 @ViewMode int fallback) { 46 return getPrefs(context).getInt(createKey(root), fallback); 47 } 48 setDisplayFileSize(Context context, boolean display)49 public static void setDisplayFileSize(Context context, boolean display) { 50 getPrefs(context).edit().putBoolean(KEY_FILE_SIZE, display).apply(); 51 } 52 getShowDeviceRoot(Context context, @ActionType int action)53 public static boolean getShowDeviceRoot(Context context, @ActionType int action) { 54 return getPrefs(context).getBoolean(INCLUDE_DEVICE_ROOT + action, false); 55 } 56 setShowDeviceRoot( Context context, @ActionType int action, boolean display)57 public static void setShowDeviceRoot( 58 Context context, @ActionType int action, boolean display) { 59 getPrefs(context).edit().putBoolean(INCLUDE_DEVICE_ROOT + action, display).apply(); 60 } 61 setViewMode(Context context, RootInfo root, @ViewMode int viewMode)62 public static void setViewMode(Context context, RootInfo root, @ViewMode int viewMode) { 63 assert(viewMode != MODE_UNKNOWN); 64 getPrefs(context).edit().putInt(createKey(root), viewMode).apply(); 65 } 66 getPrefs(Context context)67 private static SharedPreferences getPrefs(Context context) { 68 return PreferenceManager.getDefaultSharedPreferences(context); 69 } 70 createKey(RootInfo root)71 private static String createKey(RootInfo root) { 72 return ROOT_VIEW_MODE_PREFIX + root.authority + root.rootId; 73 } 74 75 public static final int PERMISSION_ASK = 0; 76 public static final int PERMISSION_ASK_AGAIN = 1; 77 public static final int PERMISSION_NEVER_ASK = -1; 78 79 @IntDef(flag = true, value = { 80 PERMISSION_ASK, 81 PERMISSION_ASK_AGAIN, 82 PERMISSION_NEVER_ASK, 83 }) 84 @Retention(RetentionPolicy.SOURCE) 85 public @interface PermissionStatus {} 86 87 /** 88 * Methods below are used to keep track of denied user requests on scoped directory access so 89 * the dialog is not offered when user checked the 'Do not ask again' box 90 * 91 * <p>It uses a shared preferences, whose key is: 92 * <ol> 93 * <li>{@code USER_ID|PACKAGE_NAME|VOLUME_UUID|DIRECTORY} for storage volumes that have a UUID 94 * (typically physical volumes like SD cards). 95 * <li>{@code USER_ID|PACKAGE_NAME||DIRECTORY} for storage volumes that do not have a UUID 96 * (typically the emulated volume used for primary storage 97 * </ol> 98 */ getScopedAccessPermissionStatus(Context context, String packageName, @Nullable String uuid, String directory)99 static @PermissionStatus int getScopedAccessPermissionStatus(Context context, 100 String packageName, @Nullable String uuid, String directory) { 101 final String key = getScopedAccessDenialsKey(packageName, uuid, directory); 102 return getPrefs(context).getInt(key, PERMISSION_ASK); 103 } 104 setScopedAccessPermissionStatus(Context context, String packageName, @Nullable String uuid, String directory, @PermissionStatus int status)105 static void setScopedAccessPermissionStatus(Context context, String packageName, 106 @Nullable String uuid, String directory, @PermissionStatus int status) { 107 final String key = getScopedAccessDenialsKey(packageName, uuid, directory); 108 getPrefs(context).edit().putInt(key, status).apply(); 109 } 110 getScopedAccessDenialsKey(String packageName, String uuid, String directory)111 private static String getScopedAccessDenialsKey(String packageName, String uuid, 112 String directory) { 113 final int userId = UserHandle.myUserId(); 114 return uuid == null 115 ? userId + "|" + packageName + "||" + directory 116 : userId + "|" + packageName + "|" + uuid + "|" + directory; 117 } 118 } 119