1 /* 2 * Copyright (C) 2019 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.packageinstaller.role.model; 18 19 import android.content.Context; 20 import android.content.SharedPreferences; 21 import android.util.ArraySet; 22 23 import androidx.annotation.NonNull; 24 import androidx.annotation.Nullable; 25 26 import com.android.packageinstaller.Constants; 27 28 import java.util.Collections; 29 import java.util.Set; 30 31 /** 32 * Manages user denied status for requesting roles. 33 */ 34 public class UserDeniedManager { 35 36 @Nullable 37 private static UserDeniedManager sInstance; 38 39 private final SharedPreferences mPreferences; 40 41 /** 42 * Get a singleton instance of this class 43 * 44 * @param context the context for retrieving shared preferences. 45 * 46 * @return the singleton instance of this class 47 */ 48 @NonNull getInstance(@onNull Context context)49 public static UserDeniedManager getInstance(@NonNull Context context) { 50 if (sInstance == null) { 51 sInstance = new UserDeniedManager(context); 52 } 53 return sInstance; 54 } 55 UserDeniedManager(@onNull Context context)56 private UserDeniedManager(@NonNull Context context) { 57 context = context.getApplicationContext(); 58 mPreferences = context.getSharedPreferences(Constants.REQUEST_ROLE_USER_DENIED_FILE, 59 Context.MODE_PRIVATE); 60 } 61 62 /** 63 * Check whether an application has been denied for a role once. 64 * 65 * @param roleName the name of the role 66 * @param packageName the package name of the application 67 * 68 * @return whether the application has been denied for the role once 69 */ isDeniedOnce(@onNull String roleName, @NonNull String packageName)70 public boolean isDeniedOnce(@NonNull String roleName, @NonNull String packageName) { 71 return isDenied(roleName, packageName, false); 72 } 73 74 /** 75 * Remember that an application has been denied for a role once. 76 * 77 * @param roleName the name of the role 78 * @param packageName the package name of the application 79 */ setDeniedOnce(@onNull String roleName, @NonNull String packageName)80 public void setDeniedOnce(@NonNull String roleName, @NonNull String packageName) { 81 setDenied(roleName, packageName, false, true); 82 } 83 84 /** 85 * Check whether an application is always denied for a role. 86 * 87 * @param roleName the name of the role 88 * @param packageName the package name of the application 89 * 90 * @return whether the application is always denied for the role 91 */ isDeniedAlways(@onNull String roleName, @NonNull String packageName)92 public boolean isDeniedAlways(@NonNull String roleName, @NonNull String packageName) { 93 return isDenied(roleName, packageName, true); 94 } 95 96 /** 97 * Remember that an application is always denied for a role. 98 * 99 * @param roleName the name of the role 100 * @param packageName the package name of the application 101 */ setDeniedAlways(@onNull String roleName, @NonNull String packageName)102 public void setDeniedAlways(@NonNull String roleName, @NonNull String packageName) { 103 setDenied(roleName, packageName, true, true); 104 } 105 106 /** 107 * Forget about whether an application is denied for a role, once or always. 108 * 109 * @param roleName the name of the role 110 * @param packageName the package name of the application 111 */ clearDenied(@onNull String roleName, @NonNull String packageName)112 public void clearDenied(@NonNull String roleName, @NonNull String packageName) { 113 setDenied(roleName, packageName, false, false); 114 setDenied(roleName, packageName, true, false); 115 } 116 117 /** 118 * Forget about whether an application is denied for any of the roles, once or always. 119 * 120 * @param packageName the package name of the application 121 */ clearPackageDenied(@onNull String packageName)122 public void clearPackageDenied(@NonNull String packageName) { 123 mPreferences.edit() 124 .remove(getKey(packageName, false)) 125 .remove(getKey(packageName, true)) 126 .apply(); 127 } 128 129 @NonNull getKey(@onNull String packageName, boolean always)130 private static String getKey(@NonNull String packageName, boolean always) { 131 return (always ? Constants.REQUEST_ROLE_USER_DENIED_ALWAYS_KEY_PREFIX 132 : Constants.REQUEST_ROLE_USER_DENIED_ONCE_KEY_PREFIX) + packageName; 133 } 134 isDenied(@onNull String roleName, @NonNull String packageName, boolean always)135 private boolean isDenied(@NonNull String roleName, @NonNull String packageName, 136 boolean always) { 137 String key = getKey(packageName, always); 138 return mPreferences.getStringSet(key, Collections.emptySet()).contains(roleName); 139 } 140 setDenied(@onNull String roleName, @NonNull String packageName, boolean always, boolean denied)141 private void setDenied(@NonNull String roleName, @NonNull String packageName, boolean always, 142 boolean denied) { 143 String key = getKey(packageName, always); 144 Set<String> roleNames = mPreferences.getStringSet(key, Collections.emptySet()); 145 if (roleNames.contains(roleName) == denied) { 146 return; 147 } 148 roleNames = new ArraySet<>(roleNames); 149 if (denied) { 150 roleNames.add(roleName); 151 } else { 152 roleNames.remove(roleName); 153 } 154 if (roleName.isEmpty()) { 155 mPreferences.edit().remove(key).apply(); 156 } else { 157 mPreferences.edit().putStringSet(key, roleNames).apply(); 158 } 159 } 160 } 161