1 /* 2 * Copyright (C) 2017 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 18 package android.provider; 19 20 import android.content.ComponentName; 21 import android.content.ContentResolver; 22 import android.text.TextUtils; 23 24 import com.android.internal.util.ArrayUtils; 25 26 import java.util.Collection; 27 import java.util.HashSet; 28 import java.util.Iterator; 29 import java.util.function.Function; 30 31 /** 32 * Utilities for dealing with {@link String} values in {@link Settings} 33 * 34 * @hide 35 */ 36 public class SettingsStringUtil { SettingsStringUtil()37 private SettingsStringUtil() {} 38 39 public static final String DELIMITER = ":"; 40 41 /** 42 * A {@link HashSet} of items, that uses a common convention of setting string 43 * serialization/deserialization of separating multiple items with {@link #DELIMITER} 44 */ 45 public static abstract class ColonDelimitedSet<T> extends HashSet<T> { 46 ColonDelimitedSet(String colonSeparatedItems)47 public ColonDelimitedSet(String colonSeparatedItems) { 48 for (String cn : 49 TextUtils.split(TextUtils.emptyIfNull(colonSeparatedItems), DELIMITER)) { 50 add(itemFromString(cn)); 51 } 52 } 53 itemFromString(String s)54 protected abstract T itemFromString(String s); itemToString(T item)55 protected String itemToString(T item) { 56 return String.valueOf(item); 57 } 58 59 @Override toString()60 public String toString() { 61 StringBuilder sb = new StringBuilder(); 62 Iterator<T> it = iterator(); 63 if (it.hasNext()) { 64 sb.append(itemToString(it.next())); 65 while (it.hasNext()) { 66 sb.append(DELIMITER); 67 sb.append(itemToString(it.next())); 68 } 69 } 70 return sb.toString(); 71 } 72 73 74 public static class OfStrings extends ColonDelimitedSet<String> { OfStrings(String colonSeparatedItems)75 public OfStrings(String colonSeparatedItems) { 76 super(colonSeparatedItems); 77 } 78 79 @Override itemFromString(String s)80 protected String itemFromString(String s) { 81 return s; 82 } 83 addAll(String delimitedElements, Collection<String> elements)84 public static String addAll(String delimitedElements, Collection<String> elements) { 85 final ColonDelimitedSet<String> set 86 = new ColonDelimitedSet.OfStrings(delimitedElements); 87 return set.addAll(elements) ? set.toString() : delimitedElements; 88 } 89 add(String delimitedElements, String element)90 public static String add(String delimitedElements, String element) { 91 final ColonDelimitedSet<String> set 92 = new ColonDelimitedSet.OfStrings(delimitedElements); 93 if (set.contains(element)) { 94 return delimitedElements; 95 } 96 set.add(element); 97 return set.toString(); 98 } 99 remove(String delimitedElements, String element)100 public static String remove(String delimitedElements, String element) { 101 final ColonDelimitedSet<String> set 102 = new ColonDelimitedSet.OfStrings(delimitedElements); 103 if (!set.contains(element)) { 104 return delimitedElements; 105 } 106 set.remove(element); 107 return set.toString(); 108 } 109 contains(String delimitedElements, String element)110 public static boolean contains(String delimitedElements, String element) { 111 final String[] elements = TextUtils.split(delimitedElements, DELIMITER); 112 return ArrayUtils.indexOf(elements, element) != -1; 113 } 114 } 115 } 116 117 public static class ComponentNameSet extends ColonDelimitedSet<ComponentName> { ComponentNameSet(String colonSeparatedPackageNames)118 public ComponentNameSet(String colonSeparatedPackageNames) { 119 super(colonSeparatedPackageNames); 120 } 121 122 @Override itemFromString(String s)123 protected ComponentName itemFromString(String s) { 124 return ComponentName.unflattenFromString(s); 125 } 126 127 @Override itemToString(ComponentName item)128 protected String itemToString(ComponentName item) { 129 return item.flattenToString(); 130 } 131 add(String delimitedElements, ComponentName element)132 public static String add(String delimitedElements, ComponentName element) { 133 final ComponentNameSet set = new ComponentNameSet(delimitedElements); 134 if (set.contains(element)) { 135 return delimitedElements; 136 } 137 set.add(element); 138 return set.toString(); 139 } 140 remove(String delimitedElements, ComponentName element)141 public static String remove(String delimitedElements, ComponentName element) { 142 final ComponentNameSet set = new ComponentNameSet(delimitedElements); 143 if (!set.contains(element)) { 144 return delimitedElements; 145 } 146 set.remove(element); 147 return set.toString(); 148 } 149 contains(String delimitedElements, ComponentName element)150 public static boolean contains(String delimitedElements, ComponentName element) { 151 return ColonDelimitedSet.OfStrings.contains( 152 delimitedElements, element.flattenToString()); 153 } 154 } 155 156 public static class SettingStringHelper { 157 private final ContentResolver mContentResolver; 158 private final String mSettingName; 159 private final int mUserId; 160 SettingStringHelper(ContentResolver contentResolver, String name, int userId)161 public SettingStringHelper(ContentResolver contentResolver, String name, int userId) { 162 mContentResolver = contentResolver; 163 mUserId = userId; 164 mSettingName = name; 165 } 166 read()167 public String read() { 168 return Settings.Secure.getStringForUser( 169 mContentResolver, mSettingName, mUserId); 170 } 171 write(String value)172 public boolean write(String value) { 173 return Settings.Secure.putStringForUser( 174 mContentResolver, mSettingName, value, mUserId); 175 } 176 modify(Function<String, String> change)177 public boolean modify(Function<String, String> change) { 178 return write(change.apply(read())); 179 } 180 } 181 } 182