1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.prefs; 19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.IOException; 21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.io.OutputStream; 22e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughesimport java.nio.charset.Charsets; 235cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilsonimport java.util.Collection; 24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.EventListener; 25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.EventObject; 26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.HashMap; 27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.LinkedList; 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.Map; 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.TreeSet; 3132b2c95c350002f67c8b3e65777161feda766b72Jesse Wilsonimport libcore.io.Base64; 326186821cb13f4ac7ff50950c813394367e021eaeJesse Wilsonimport libcore.util.EmptyArray; 33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This abstract class is a partial implementation of the abstract class 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Preferences, which can be used to simplify {@code Preferences} provider's 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implementation. This class defines nine abstract SPI methods, which must be 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * implemented by a preference provider. 395cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 405cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * @since 1.4 415cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * @see Preferences 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic abstract class AbstractPreferences extends Preferences { 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class fields 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 495cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** the unhandled events collection */ 50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final List<EventObject> events = new LinkedList<EventObject>(); 515cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** the event dispatcher thread */ 5203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes private static final EventDispatcher dispatcher = new EventDispatcher("Preference Event Dispatcher"); 53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Class initializer 57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatcher.setDaemon(true); 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatcher.start(); 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Runtime.getRuntime().addShutdownHook(new Thread() { 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void run() { 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences uroot = Preferences.userRoot(); 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences sroot = Preferences.systemRoot(); 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project uroot.flush(); 695cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } catch (BackingStoreException e) { 705cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignore 71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sroot.flush(); 745cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } catch (BackingStoreException e) { 755cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignore 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project }); 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Instance fields (package-private) 84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 865cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** true if this node is in user preference hierarchy */ 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project boolean userNode; 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Instance fields (private) 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The object used to lock this node. 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final Object lock; 98f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This field is true if this node is created while it doesn't exist in the 101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * backing store. This field's default value is false, and it is checked 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * when the node creation is completed, and if it is true, the node change 103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * event will be fired for this node's parent. 104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected boolean newNode; 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1075cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson /** cached child nodes */ 108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private Map<String, AbstractPreferences> cachedNode; 109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //the collections of listeners 111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<EventListener> nodeChangeListeners; 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private List<EventListener> preferenceChangeListeners; 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //this node's name 115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String nodeName; 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //handler to this node's parent 118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences parentPref; 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //true if this node has been removed 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private boolean isRemoved; 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //handler to this node's root node 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences root; 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructors 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1325cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Constructs a new {@code AbstractPreferences} instance using the given 1335cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * parent node and node name. 1345cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param parent 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the parent node of the new node or {@code null} to indicate 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * that the new node is a root node. 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the new node or an empty string to indicate that 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this node is called "root". 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the name contains a slash character or is empty if {@code 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parent} is not {@code null}. 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AbstractPreferences(AbstractPreferences parent, String name) { 146b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if ((parent == null ^ name.length() == 0) || name.indexOf("/") >= 0) { 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 149b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes root = (parent == null) ? this : parent.root; 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners = new LinkedList<EventListener>(); 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners = new LinkedList<EventListener>(); 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isRemoved = false; 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cachedNode = new HashMap<String, AbstractPreferences>(); 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeName = name; 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref = parent; 1565e23b687ef8b3c696d54d1880b454942875665b7Elliott Hughes lock = new Object(); 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project userNode = root.userNode; 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of all cached child nodes. 167f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of cached child nodes. 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected final AbstractPreferences[] cachedChildren() { 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return cachedNode.values().toArray(new AbstractPreferences[cachedNode.size()]); 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the child node with the specified name or {@code null} if it 1765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * doesn't exist. Implementers can assume that the name supplied to this 1775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * method will be a valid node name string (conforming to the node naming 1785cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * format) and will not correspond to a node that has been cached or 1795cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * removed. 180f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the desired child node. 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the child node with the given name or {@code null} if it doesn't 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * exist. 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected AbstractPreferences getChild(String name) 190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws BackingStoreException { 191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences result = null; 194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] childrenNames = childrenNames(); 19532b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson for (String childrenName : childrenNames) { 19632b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson if (childrenName.equals(name)) { 197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = childSpi(name); 198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether this node has been removed by invoking the method {@code 208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removeNode()}. 2095cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true}, if this node has been removed, {@code false} 211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected boolean isRemoved() { 214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return isRemoved; 216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Flushes changes of this node to the backing store. This method should 221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * only flush this node and should not include the descendant nodes. Any 2225cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * implementation that wants to provide functionality to flush all nodes 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * at once should override the method {@link #flush() flush()}. 2245cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void flushSpi() throws BackingStoreException; 230f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2325cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Returns the names of all of the child nodes of this node or an empty 2335cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * array if this node has no children. The names of cached children are not 2345cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * required to be returned. 2355cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the names of this node's children. 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String[] childrenNamesSpi() throws BackingStoreException; 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the child preference node with the given name, creating it 245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if it does not exist. The caller of this method should ensure that the 2465cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * given name is valid and that this node has not been removed or cached. 247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * If the named node has just been removed, the implementation 248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of this method must create a new one instead of reactivating the removed 249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * one. 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The new creation is not required to be persisted immediately until the 252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * flush method will be invoked. 253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </p> 254f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the name of the child preference to be returned. 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the child preference node. 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract AbstractPreferences childSpi(String name); 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Puts the given key-value pair into this node. Caller of this method 264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * should ensure that both of the given values are valid and that this 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * node has not been removed. 2665cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given preference key. 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param value 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given preference value. 271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void putSpi(String name, String value); 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 2755cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * Gets the preference value mapped to the given key. The caller of this 2765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * method should ensure that the given key is valid and that this node has 2775cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * not been removed. This method should not throw any exceptions but if it 2785cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * does, the caller will ignore the exception, regarding it as a {@code 2795cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * null} return value. 2805cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the given key to be searched for. 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the preference value mapped to the given key. 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String getSpi(String key); 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of all preference keys of this node or an empty array if 2905cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * no preferences have been found. The caller of this method should ensure 2915cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * that this node has not been removed. 2925cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of all preference keys. 294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract String[] keysSpi() throws BackingStoreException; 299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes this node from the preference hierarchy tree. The caller of this 302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method should ensure that this node has no child nodes, which means the 303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * method {@link Preferences#removeNode() Preferences.removeNode()} should 304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * invoke this method multiple-times in bottom-up pattern. The removal is 305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not required to be persisted until after it is flushed. 3065cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * 307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void removeNodeSpi() throws BackingStoreException; 312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Removes the preference with the specified key. The caller of this method 315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * should ensure that the given key is valid and that this node has not been 316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * removed. 317f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param key 319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the key of the preference that is to be removed. 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void removeSpi(String key); 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Synchronizes this node with the backing store. This method should only 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * synchronize this node and should not include the descendant nodes. An 3265cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * implementation that wants to provide functionality to synchronize all 3275cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson * nodes at once should override the method {@link #sync() sync()}. 328f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws BackingStoreException 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the backing store is unavailable or causes an operation 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * failure. 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project protected abstract void syncSpi() throws BackingStoreException; 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Methods inherited from Preferences 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ----------------------------------------------------------- 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String absolutePath() { 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentPref == null) { 34303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return "/"; 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (parentPref == root) { 34503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return "/" + nodeName; 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 34703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes return parentPref.absolutePath() + "/" + nodeName; 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] childrenNames() throws BackingStoreException { 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project TreeSet<String> result = new TreeSet<String>(cachedNode.keySet()); 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] names = childrenNamesSpi(); 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < names.length; i++) { 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result.add(names[i]); 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 3595cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return result.toArray(new String[result.size()]); 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void clear() throws BackingStoreException { 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 36632b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson for (String key : keys()) { 36732b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson remove(key); 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 37303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes public void exportNode(OutputStream ostream) throws IOException, BackingStoreException { 37403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (ostream == null) { 37586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("ostream == null"); 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project XMLParser.exportPrefs(this, ostream, false); 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 38203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes public void exportSubtree(OutputStream ostream) throws IOException, BackingStoreException { 38303c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (ostream == null) { 38486acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("ostream == null"); 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project XMLParser.exportPrefs(this, ostream, true); 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void flush() throws BackingStoreException { 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project flushSpi(); 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences[] cc = cachedChildren(); 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int i; 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (i = 0; i < cc.length; i++) { 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project cc[i].flush(); 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String get(String key, String deflt) { 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key == null) { 40586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("key == null"); 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4075cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson String result = null; 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = getSpi(key); 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 4135cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // ignored 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (result == null ? deflt : result); 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean getBoolean(String key, boolean deflt) { 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 4245cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 42503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if ("true".equalsIgnoreCase(result)) { 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 42703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } else if ("false".equalsIgnoreCase(result)) { 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public byte[] getByteArray(String key, byte[] deflt) { 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String svalue = get(key, null); 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (svalue == null) { 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 440f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes if (svalue.length() == 0) { 441693eacca9fa67ad79d1b35dbaad61c5ac1ac457cElliott Hughes return EmptyArray.BYTE; 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 444e810d3b49631329b11440aa5b7a54db181d42ed1Elliott Hughes byte[] bavalue = svalue.getBytes(Charsets.US_ASCII); 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (bavalue.length % 4 != 0) { 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 4485cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Base64.decode(bavalue); 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (Exception e) { 4505cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public double getDouble(String key, double deflt) { 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4615cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Double.parseDouble(result); 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4635cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public float getFloat(String key, float deflt) { 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4745cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Float.parseFloat(result); 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4765cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int getInt(String key, int deflt) { 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 4875cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Integer.parseInt(result); 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 4895cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long getLong(String key, long deflt) { 495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String result = get(key, null); 496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result == null) { 497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return deflt; 498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 5005cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return Long.parseLong(result); 501adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (NumberFormatException e) { 5025cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return deflt; 503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isUserNode() { 508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return root == Preferences.userRoot(); 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String[] keys() throws BackingStoreException { 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return keysSpi(); 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String name() { 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return nodeName; 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Preferences node(String name) { 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences startNode = null; 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validateName(name); 53080a7fbab52b96c9fd47c72f8987d1babe2cd001dElliott Hughes if (name.isEmpty()) { 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return this; 53203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes } else if ("/".equals(name)) { 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return root; 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 53503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.startsWith("/")) { 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = root; 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.substring(1); 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = this; 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 5435cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return startNode.nodeImpl(name, true); 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (BackingStoreException e) { 5455cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson // should not happen 5465cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson return null; 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void validateName(String name) { 55103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.endsWith("/") && name.length() > 1) { 55203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name cannot end with '/'"); 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 55403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.indexOf("//") >= 0) { 55503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name cannot contain consecutive '/' characters"); 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences nodeImpl(String path, boolean createNew) 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws BackingStoreException { 561fd6bb3510c2f94d636f3572dcf5f7f4dcd1a2726Elliott Hughes String[] names = path.split("/"); 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences currentNode = this; 56332b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson AbstractPreferences temp; 56432b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson for (String name : names) { 56532b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson synchronized (currentNode.lock) { 56632b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson temp = currentNode.cachedNode.get(name); 56732b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson if (temp == null) { 56832b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson temp = getNodeFromBackend(createNew, currentNode, name); 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 57132b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson currentNode = temp; 57232b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson if (currentNode == null) { 57332b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson break; 57432b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson } 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return currentNode; 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 579adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private AbstractPreferences getNodeFromBackend(boolean createNew, 58003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes AbstractPreferences currentNode, String name) throws BackingStoreException { 581adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name.length() > MAX_NAME_LENGTH) { 58203c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalArgumentException("Name '" + name + "' too long"); 583adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 5845cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson AbstractPreferences temp; 585adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (createNew) { 586adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project temp = currentNode.childSpi(name); 587adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentNode.cachedNode.put(name, temp); 588adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (temp.newNode && currentNode.nodeChangeListeners.size() > 0) { 589adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project currentNode.notifyChildAdded(temp); 590adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 591adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 592adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project temp = currentNode.getChild(name); 593adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 594adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return temp; 595adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 596adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 597adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 598adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean nodeExists(String name) throws BackingStoreException { 599b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (name == null) { 60086acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("name == null"); 6015cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson } 602adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project AbstractPreferences startNode = null; 603adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 604adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isRemoved()) { 60503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.isEmpty()) { 606adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 607adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 60803c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalStateException("This node has been removed"); 609adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 610adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project validateName(name); 61103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.isEmpty() || "/".equals(name)) { 612adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 613adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 61403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes if (name.startsWith("/")) { 615adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = root; 616adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.substring(1); 617adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 618adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project startNode = this; 619adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 620adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 621adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 622adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project Preferences result = startNode.nodeImpl(name, false); 623b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes return (result != null); 624adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch(IllegalArgumentException e) { 625adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 626adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 627adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 628adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 629adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 630adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public Preferences parent() { 631adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 632adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return parentPref; 633adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 634adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 635adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkState() { 636adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (isRemoved()) { 63703c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new IllegalStateException("This node has been removed"); 638adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 639adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 640adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 641adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 642adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void put(String key, String value) { 64386acc043d3334651ee26c65467d78d6cefedd397Kenny Root if (key == null) { 64486acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("key == null"); 64586acc043d3334651ee26c65467d78d6cefedd397Kenny Root } else if (value == null) { 64686acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("value == null"); 647adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 648adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (key.length() > MAX_KEY_LENGTH || value.length() > MAX_VALUE_LENGTH) { 649adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 650adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 651adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 652adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 653adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project putSpi(key, value); 654adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 655adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project notifyPreferenceChange(key, value); 656adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 657adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 658adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 659adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putBoolean(String key, boolean value) { 66032b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson put(key, String.valueOf(value)); 661adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 662adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putByteArray(String key, byte[] value) { 66532b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson put(key, Base64.encode(value)); 666adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putDouble(String key, double value) { 67032b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson put(key, Double.toString(value)); 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putFloat(String key, float value) { 67532b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson put(key, Float.toString(value)); 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putInt(String key, int value) { 68032b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson put(key, Integer.toString(value)); 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void putLong(String key, long value) { 68532b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson put(key, Long.toString(value)); 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void remove(String key) { 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeSpi(key); 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project notifyPreferenceChange(key, null); 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeNode() throws BackingStoreException { 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (root == this) { 70003c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes throw new UnsupportedOperationException("Cannot remove root node"); 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (parentPref.lock) { 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeNodeImpl(); 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void removeNodeImpl() throws BackingStoreException { 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String[] childrenNames = childrenNamesSpi(); 71132b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson for (String childrenName : childrenNames) { 71232b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson if (cachedNode.get(childrenName) == null) { 71332b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson AbstractPreferences child = childSpi(childrenName); 71432b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson cachedNode.put(childrenName, child); 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 717f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 7185cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson final Collection<AbstractPreferences> values = cachedNode.values(); 7195cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson final AbstractPreferences[] children = values.toArray(new AbstractPreferences[values.size()]); 7205cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson for (AbstractPreferences child : children) { 7215cc8cb84ac4a3474cfb666c9b94fd721e4615ca0Jesse Wilson child.removeNodeImpl(); 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project removeNodeSpi(); 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project isRemoved = true; 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref.cachedNode.remove(nodeName); 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentPref.nodeChangeListeners.size() > 0) { 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project parentPref.notifyChildRemoved(this); 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addNodeChangeListener(NodeChangeListener ncl) { 734b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (ncl == null) { 73586acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("ncl == null"); 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners.add(ncl); 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void addPreferenceChangeListener(PreferenceChangeListener pcl) { 745b46dab348e2007bc08abaf7ecae34d89a2474e50Elliott Hughes if (pcl == null) { 74686acc043d3334651ee26c65467d78d6cefedd397Kenny Root throw new NullPointerException("pcl == null"); 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners.add(pcl); 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removeNodeChangeListener(NodeChangeListener ncl) { 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos; 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((pos = nodeChangeListeners.indexOf(ncl)) == -1) { 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project nodeChangeListeners.remove(pos); 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void removePreferenceChangeListener(PreferenceChangeListener pcl) { 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int pos; 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if ((pos = preferenceChangeListeners.indexOf(pcl)) == -1) { 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new IllegalArgumentException(); 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project preferenceChangeListeners.remove(pos); 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void sync() throws BackingStoreException { 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (lock) { 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkState(); 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project syncSpi(); 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 78403c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes for (AbstractPreferences child : cachedChildren()) { 78503c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes child.sync(); 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 791328f533a177f7579a9ea916f5569053ec9c149b8Elliott Hughes return (isUserNode() ? "User" : "System") + " Preference Node: " + absolutePath(); 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyChildAdded(Preferences child) { 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeEvent nce = new NodeAddEvent(this, child); 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(nce); 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyChildRemoved(Preferences child) { 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project NodeChangeEvent nce = new NodeRemoveEvent(this, child); 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(nce); 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void notifyPreferenceChange(String key, String newValue) { 81103c0a8e681c776fdba0389ab8593282139afc6d6Elliott Hughes PreferenceChangeEvent pce = new PreferenceChangeEvent(this, key, newValue); 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.add(pce); 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.notifyAll(); 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class EventDispatcher extends Thread { 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventDispatcher(String name){ 820adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(name); 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 822f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void run() { 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project while (true) { 82632b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson EventObject event; 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project event = getEventObject(); 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (InterruptedException e) { 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project e.printStackTrace(); 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 83332b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson AbstractPreferences pref = (AbstractPreferences) event.getSource(); 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (event instanceof NodeAddEvent) { 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchNodeAdd((NodeChangeEvent) event, 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.nodeChangeListeners); 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (event instanceof NodeRemoveEvent) { 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchNodeRemove((NodeChangeEvent) event, 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.nodeChangeListeners); 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else if (event instanceof PreferenceChangeEvent) { 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project dispatchPrefChange((PreferenceChangeEvent) event, 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project pref.preferenceChangeListeners); 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private EventObject getEventObject() throws InterruptedException { 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (events) { 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (events.isEmpty()) { 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.wait(); 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project EventObject event = events.get(0); 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project events.remove(0); 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return event; 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchPrefChange(PreferenceChangeEvent event, 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> preferenceChangeListeners) { 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (preferenceChangeListeners) { 86132b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson for (EventListener preferenceChangeListener : preferenceChangeListeners) { 86232b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson ((PreferenceChangeListener) preferenceChangeListener).preferenceChange(event); 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchNodeRemove(NodeChangeEvent event, 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> nodeChangeListeners) { 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 87032b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson for (EventListener nodeChangeListener : nodeChangeListeners) { 87132b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson ((NodeChangeListener) nodeChangeListener).childRemoved(event); 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void dispatchNodeAdd(NodeChangeEvent event, 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project List<EventListener> nodeChangeListeners) { 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project synchronized (nodeChangeListeners) { 87932b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson for (EventListener nodeChangeListener : nodeChangeListeners) { 88032b2c95c350002f67c8b3e65777161feda766b72Jesse Wilson NodeChangeListener ncl = (NodeChangeListener) nodeChangeListener; 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project ncl.childAdded(event); 882adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class NodeAddEvent extends NodeChangeEvent { 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //The base class is NOT serializable, so this class isn't either. 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 1L; 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeAddEvent(Preferences p, Preferences c) { 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(p, c); 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static class NodeRemoveEvent extends NodeChangeEvent { 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project //The base class is NOT serializable, so this class isn't either. 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 1L; 899f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes 900adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public NodeRemoveEvent(Preferences p, Preferences c) { 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project super(p, c); 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 903adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 904adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 905