1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Licensed to the Apache Software Foundation (ASF) under one or more
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  contributor license agreements.  See the NOTICE file distributed with
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  this work for additional information regarding copyright ownership.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  The ASF licenses this file to You under the Apache License, Version 2.0
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  (the "License"); you may not use this file except in compliance with
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  the License.  You may obtain a copy of the License at
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  distributed under the License is distributed on an "AS IS" BASIS,
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  See the License for the specific language governing permissions and
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *  limitations under the License.
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpackage java.io;
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.net.URI;
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.net.URISyntaxException;
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.net.URL;
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.security.AccessController;
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.ArrayList;
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// BEGIN android-added
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.Collections;
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// END android-added
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport java.util.List;
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// BEGIN android-removed
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// import org.apache.harmony.luni.util.DeleteOnExit;
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// END android-removed
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.Msg;
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.PriviAction;
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectimport org.apache.harmony.luni.util.Util;
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * An "abstract" representation of a file system entity identified by a
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * pathname. The pathname may be absolute (relative to the root directory
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * of the file system) or relative to the current directory in which the program
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is running.
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This class provides methods for querying/changing information about the file
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * as well as directory listing capabilities if the file represents a directory.
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * <p>
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * When manipulating file paths, the static fields of this class may be used to
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * determine the platform specific separators.
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.io.Serializable
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see java.lang.Comparable
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @since Android 1.0
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class File implements Serializable, Comparable<File> {
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static final long serialVersionUID = 301077366599181567L;
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String path;
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    transient byte[] properPath;
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The system dependent file separator character. Since Android is a Unix-
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * based system, this defaults to '/'.
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final char separatorChar;
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The system dependent file separator string. The initial value of this
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * field is the system property "file.separator". Since Android is a Unix-
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * based system, this defaults to "/".
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final String separator;
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The system dependent path separator character. Since Android is a Unix-
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * based system, this defaults to ':'.
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final char pathSeparatorChar;
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The system dependent path separator string. The initial value of this
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * field is the system property "path.separator". Since Android is a Unix-
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * based system, this defaults to ':'.
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static final String pathSeparator;
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* Temp file counter */
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static int counter;
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static boolean caseSensitive;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static native void oneTimeInitialization();
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static {
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        oneTimeInitialization();
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // The default protection domain grants access to these properties
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-changed
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // We're on linux so the filesystem is case sensitive and the separator is /.
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        separatorChar = System.getProperty("file.separator", "/").charAt(0); //$NON-NLS-1$ //$NON-NLS-2$
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pathSeparatorChar = System.getProperty("path.separator", ";").charAt(0); //$NON-NLS-1$//$NON-NLS-2$
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        separator = new String(new char[] { separatorChar }, 0, 1);
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        pathSeparator = new String(new char[] { pathSeparatorChar }, 0, 1);
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        caseSensitive = true;
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-changed
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs a new file using the specified directory and name.
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param dir
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the directory where the file is stored.
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the file's name.
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NullPointerException
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code name} is null.
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File(File dir, String name) {
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (name == null) {
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dir == null) {
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.path = fixSlashes(name);
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.path = calculatePath(dir.getPath(), name);
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs a new file using the specified path.
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param path
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the path to be used for the file.
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File(String path) {
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // path == null check & NullPointerException thrown by fixSlashes
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.path = fixSlashes(path);
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs a new File using the specified directory path and file name,
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * placing a path separator between the two.
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param dirPath
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the path to the directory where the file is stored.
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param name
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the file's name.
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws NullPointerException
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code name} is null.
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File(String dirPath, String name) {
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (name == null) {
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new NullPointerException();
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dirPath == null) {
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.path = fixSlashes(name);
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            this.path = calculatePath(dirPath, name);
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Constructs a new File using the path of the specified URI. {@code uri}
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * needs to be an absolute and hierarchical Unified Resource Identifier with
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file scheme and non-empty path component, but with undefined authority,
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * query or fragment components.
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param uri
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the Unified Resource Identifier that is used to construct this
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            file.
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code uri} does not comply with the conditions above.
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #toURI
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see java.net.URI
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File(URI uri) {
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // check pre-conditions
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkURI(uri);
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        this.path = fixSlashes(uri.getPath());
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String calculatePath(String dirPath, String name) {
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dirPath = fixSlashes(dirPath);
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!name.equals("")) { //$NON-NLS-1$
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Remove all the proceeding separator chars from name
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            name = fixSlashes(name);
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int separatorIndex = 0;
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            while ((separatorIndex < name.length())
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    && (name.charAt(separatorIndex) == separatorChar)) {
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                separatorIndex++;
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (separatorIndex > 0) {
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                name = name.substring(separatorIndex, name.length());
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Ensure there is a separator char between dirPath and name
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (dirPath.length() > 0
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    && (dirPath.charAt(dirPath.length() - 1) == separatorChar)) {
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return dirPath + name;
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return dirPath + separatorChar + name;
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return dirPath;
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void checkURI(URI uri) {
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!uri.isAbsolute()) {
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Msg.getString("K031a", uri)); //$NON-NLS-1$
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (!uri.getRawSchemeSpecificPart().startsWith("/")) { //$NON-NLS-1$
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Msg.getString("K031b", uri)); //$NON-NLS-1$
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String temp = uri.getScheme();
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (temp == null || !temp.equals("file")) { //$NON-NLS-1$
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Msg.getString("K031c", uri)); //$NON-NLS-1$
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        temp = uri.getRawPath();
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (temp == null || temp.length() == 0) {
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Msg.getString("K031d", uri)); //$NON-NLS-1$
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (uri.getRawAuthority() != null) {
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Msg.getString(
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "K031e", new String[] { "authority", uri.toString() })); //$NON-NLS-1$ //$NON-NLS-2$
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (uri.getRawQuery() != null) {
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Msg.getString(
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "K031e", new String[] { "query", uri.toString() })); //$NON-NLS-1$//$NON-NLS-2$
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (uri.getRawFragment() != null) {
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Msg.getString(
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "K031e", new String[] { "fragment", uri.toString() })); //$NON-NLS-1$ //$NON-NLS-2$
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static native byte[][] rootsImpl();
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static native boolean isCaseSensitiveImpl();
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Lists the file system roots. The Java platform may support zero or more
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file systems, each with its own platform-dependent root. Further, the
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * canonical pathname of any file on the system will always begin with one
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * of the returned file system roots.
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the array of file system roots.
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static File[] listRoots() {
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[][] rootsList = rootsImpl();
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (rootsList == null) {
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return new File[0];
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        File result[] = new File[rootsList.length];
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < rootsList.length; i++) {
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[i] = new File(Util.toString(rootsList[i]));
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The purpose of this method is to take a path and fix the slashes up. This
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * includes changing them all to the current platforms fileSeparator and
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * removing duplicates.
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String fixSlashes(String origPath) {
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int uncIndex = 1;
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int length = origPath.length(), newLength = 0;
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (separatorChar == '/') {
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            uncIndex = 0;
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (length > 2 && origPath.charAt(1) == ':') {
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            uncIndex = 2;
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean foundSlash = false;
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char newPath[] = origPath.toCharArray();
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < length; i++) {
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            char pathChar = newPath[i];
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (pathChar == '\\' || pathChar == '/') {
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /* UNC Name requires 2 leading slashes */
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if ((foundSlash && i == uncIndex) || !foundSlash) {
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    newPath[newLength++] = separatorChar;
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    foundSlash = true;
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // check for leading slashes before a drive
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (pathChar == ':'
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        && uncIndex > 0
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        && (newLength == 2 || (newLength == 3 && newPath[1] == separatorChar))
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        && newPath[0] == separatorChar) {
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    newPath[0] = newPath[newLength - 1];
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    newLength = 1;
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    // allow trailing slash after drive letter
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    uncIndex = 2;
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                newPath[newLength++] = pathChar;
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                foundSlash = false;
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // remove trailing slash
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (foundSlash
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && (newLength > (uncIndex + 1) || (newLength == 2 && newPath[0] != separatorChar))) {
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            newLength--;
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String tempPath = new String(newPath, 0, newLength);
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // If it's the same keep it identical for SecurityManager purposes
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!tempPath.equals(origPath)) {
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return tempPath;
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return origPath;
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Indicates whether the current context is allowed to read from this file.
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if this file can be read, {@code false} otherwise.
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies the
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             read request.
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean canRead() {
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-changed
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return exists() && isReadableImpl(properPath(true));
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-changed
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Indicates whether the current context is allowed to write to this file.
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if this file can be written, {@code false}
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         otherwise.
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies the
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             write request.
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean canWrite() {
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkWrite(path);
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Cannot use exists() since that does an unwanted read-check.
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean exists = false;
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (path.length() > 0) {
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            exists = existsImpl(properPath(true));
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-changed
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return exists && isWriteableImpl(properPath(true));
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-changed
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the relative sort ordering of the paths for this file and the
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file {@code another}. The ordering is platform dependent.
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param another
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            a file to compare this file to
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return an int determined by comparing the two paths. Possible values are
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         described in the Comparable interface.
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see Comparable
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int compareTo(File another) {
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (caseSensitive) {
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return this.getPath().compareTo(another.getPath());
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return this.getPath().compareToIgnoreCase(another.getPath());
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Deletes this file. Directories must be empty before they will be deleted.
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if this file was deleted, {@code false} otherwise.
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies the
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             request.
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see java.lang.SecurityManager#checkDelete
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean delete() {
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkDelete(path);
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[] propPath = properPath(true);
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((path.length() != 0) && isDirectoryImpl(propPath)) {
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return deleteDirImpl(propPath);
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return deleteFileImpl(propPath);
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean deleteDirImpl(byte[] filePath);
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean deleteFileImpl(byte[] filePath);
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Schedules this file to be automatically deleted once the virtual machine
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * terminates. This will only happen when the virtual machine terminates
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * normally as described by the Java Language Specification section 12.9.
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies the
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             request.
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void deleteOnExit() {
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkDelete(path);
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-changed
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DeleteOnExit.getInstance().addFile(getAbsoluteName());
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-changed
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Compares {@code obj} to this file and returns {@code true} if they
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * represent the <em>same</em> object using a path specific comparison.
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param obj
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the object to compare this file with.
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if {@code obj} is the same as this object,
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         {@code false} otherwise.
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean equals(Object obj) {
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!(obj instanceof File)) {
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!caseSensitive) {
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return path.equalsIgnoreCase(((File) obj).getPath());
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return path.equals(((File) obj).getPath());
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a boolean indicating whether this file can be found on the
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * underlying file system.
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if this file exists, {@code false} otherwise.
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #getPath
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean exists() {
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (path.length() == 0) {
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return existsImpl(properPath(true));
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean existsImpl(byte[] filePath);
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the absolute path of this file.
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the absolute file path.
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see java.lang.SecurityManager#checkPropertyAccess
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getAbsolutePath() {
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[] absolute = properPath(false);
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Util.toString(absolute);
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a new file constructed using the absolute path of this file.
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a new file from this file's absolute path.
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see java.lang.SecurityManager#checkPropertyAccess
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File getAbsoluteFile() {
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new File(this.getAbsolutePath());
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the absolute path of this file with all references resolved. An
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <em>absolute</em> path is one that begins at the root of the file
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * system. The canonical path is one in which all references have been
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * resolved. For the cases of '..' and '.', where the file system supports
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * parent and working directory respectively, these are removed and replaced
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * with a direct directory reference. If the file does not exist,
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * getCanonicalPath() may not resolve any references and simply returns an
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * absolute path name or throws an IOException.
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the canonical path of this file.
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an I/O error occurs.
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see java.lang.SecurityManager#checkPropertyAccess
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getCanonicalPath() throws IOException {
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[] result = properPath(false);
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        boolean exists = false;
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[] pathBytes = result;
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        do {
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            byte[] linkBytes = getLinkImpl(pathBytes);
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (linkBytes == pathBytes) {
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (linkBytes[0] == separatorChar) {
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pathBytes = linkBytes;
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                int index = pathBytes.length - 1;
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                while (pathBytes[index] != separatorChar) {
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    index--;
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                byte[] temp = new byte[index + 1 + linkBytes.length];
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.arraycopy(pathBytes, 0, temp, 0, index + 1);
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.arraycopy(linkBytes, 0, temp, index + 1,
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        linkBytes.length);
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pathBytes = temp;
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            exists = existsImpl(pathBytes);
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } while (exists);
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (exists) {
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = pathBytes;
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int numSeparators = 1;
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < result.length; i++) {
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (result[i] == separatorChar) {
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                numSeparators++;
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int sepLocations[] = new int[numSeparators];
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int rootLoc = 0;
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (separatorChar != '/') {
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (result[0] == '\\') {
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                rootLoc = (result.length > 1 && result[1] == '\\') ? 1 : 0;
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                rootLoc = 2; // skip drive i.e. c:
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte newResult[] = new byte[result.length + 1];
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int newLength = 0, lastSlash = 0, foundDots = 0;
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        sepLocations[lastSlash] = rootLoc;
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i <= result.length; i++) {
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (i < rootLoc) {
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                newResult[newLength++] = result[i];
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (i == result.length || result[i] == separatorChar) {
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (i == result.length && foundDots == 0) {
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        break;
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (foundDots == 1) {
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        /* Don't write anything, just reset and continue */
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        foundDots = 0;
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        continue;
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (foundDots > 1) {
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        /* Go back N levels */
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        lastSlash = lastSlash > (foundDots - 1) ? lastSlash
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                - (foundDots - 1) : 0;
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        newLength = sepLocations[lastSlash] + 1;
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        foundDots = 0;
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        continue;
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    sepLocations[++lastSlash] = newLength;
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    newResult[newLength++] = (byte) separatorChar;
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    continue;
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (result[i] == '.') {
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    foundDots++;
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    continue;
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /* Found some dots within text, write them out */
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (foundDots > 0) {
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    for (int j = 0; j < foundDots; j++) {
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        newResult[newLength++] = (byte) '.';
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                newResult[newLength++] = result[i];
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                foundDots = 0;
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // remove trailing slash
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (newLength > (rootLoc + 1)
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && newResult[newLength - 1] == separatorChar) {
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            newLength--;
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newResult[newLength] = 0;
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newResult = getCanonImpl(newResult);
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newLength = newResult.length;
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return Util.toString(newResult, 0, newLength);
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a new file created using the canonical path of this file.
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Equivalent to {@code new File(this.getCanonicalPath())}.
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the new file constructed from this file's canonical path.
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an I/O error occurs.
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see java.lang.SecurityManager#checkPropertyAccess
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File getCanonicalFile() throws IOException {
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new File(getCanonicalPath());
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native byte[] getCanonImpl(byte[] filePath);
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the name of the file or directory represented by this file.
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return this file's name or an empty string if there is no name part in
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         the file's path.
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getName() {
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int separatorIndex = path.lastIndexOf(separator);
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1,
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                path.length());
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the pathname of the parent of this file. This is the path up to
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * but not including the last name. {@code null} is returned if there is no
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * parent.
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return this file's parent pathname or {@code null}.
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getParent() {
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int length = path.length(), firstInPath = 0;
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (separatorChar == '\\' && length > 2 && path.charAt(1) == ':') {
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            firstInPath = 2;
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int index = path.lastIndexOf(separatorChar);
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (index == -1 && firstInPath > 0) {
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            index = 2;
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (index == -1 || path.charAt(length - 1) == separatorChar) {
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (path.indexOf(separatorChar) == index
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                && path.charAt(firstInPath) == separatorChar) {
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return path.substring(0, index + 1);
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return path.substring(0, index);
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a new file made from the pathname of the parent of this file.
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * This is the path up to but not including the last name. {@code null} is
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * returned when there is no parent.
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a new file representing this file's parent or {@code null}.
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File getParentFile() {
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String tempParent = getParent();
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (tempParent == null) {
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new File(tempParent);
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the path of this file.
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return this file's path.
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String getPath() {
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return path;
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns an integer hash code for the receiver. Any two objects for which
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code equals} returns {@code true} must return the same hash code.
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return this files's hash value.
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #equals
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public int hashCode() {
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (caseSensitive) {
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return path.hashCode() ^ 1234321;
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return path.toLowerCase().hashCode() ^ 1234321;
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Indicates if this file's pathname is absolute. Whether a pathname is
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * absolute is platform specific. On UNIX, absolute paths must start with
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * the character '/'; on Windows it is absolute if either it starts with
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * '\', '/', '\\' (to represent a file server), or a letter followed by a
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * colon.
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if this file's pathname is absolute, {@code false}
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         otherwise.
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #getPath
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isAbsolute() {
731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // BEGIN android-changed
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Removing platform independent code because we're always on linux.
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return path.length() > 0 && path.charAt(0) == separatorChar;
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // END android-changed
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // BEGIN android-removed
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // private native boolean isAbsoluteImpl(byte[] filePath);
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // END android-removed
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Indicates if this file represents a <em>directory</em> on the
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * underlying file system.
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if this file is a directory, {@code false}
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         otherwise.
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isDirectory() {
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (path.length() == 0) {
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return isDirectoryImpl(properPath(true));
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean isDirectoryImpl(byte[] filePath);
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Indicates if this file represents a <em>file</em> on the underlying
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file system.
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if this file is a file, {@code false} otherwise.
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isFile() {
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (path.length() == 0) {
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return isFileImpl(properPath(true));
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean isFileImpl(byte[] filePath);
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns whether or not this file is a hidden file as defined by the
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * operating system. The notion of "hidden" is system-dependent. For
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Unix systems (like Android) a file is considered hidden if its name
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * starts with a ".". For Windows systems there is an explicit flag in the
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file system for this purpose.
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the file is hidden, {@code false} otherwise.
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean isHidden() {
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (path.length() == 0) {
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return isHiddenImpl(properPath(true));
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean isHiddenImpl(byte[] filePath);
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // BEGIN android-changed
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean isReadableImpl(byte[] filePath);
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean isWriteableImpl(byte[] filePath);
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // END android-changed
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native byte[] getLinkImpl(byte[] filePath);
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the time when this file was last modified, measured in
824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * milliseconds since January 1st, 1970, midnight.
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the time when this file was last modified.
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public long lastModified() {
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        long result = lastModifiedImpl(properPath(true));
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* Temporary code to handle both return cases until natives fixed */
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (result == -1 || result == 0) {
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 0;
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native long lastModifiedImpl(byte[] filePath);
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Sets the time this file was last modified, measured in milliseconds since
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * January 1st, 1970, midnight.
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param time
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the last modification time for this file.
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the operation is successful, {@code false}
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         otherwise.
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if {@code time < 0}.
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies write
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean setLastModified(long time) {
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (time < 0) {
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Msg.getString("K006a")); //$NON-NLS-1$
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkWrite(path);
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (setLastModifiedImpl(properPath(true), time));
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean setLastModifiedImpl(byte[] path, long time);
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Marks this file or directory to be read-only as defined by the operating
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * system.
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the operation is successful, {@code false}
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         otherwise.
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies write
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean setReadOnly() {
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkWrite(path);
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (setReadOnlyImpl(properPath(true)));
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean setReadOnlyImpl(byte[] path);
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns the length of this file in bytes.
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the number of bytes in this file.
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public long length() {
906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return lengthImpl(properPath(true));
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native long lengthImpl(byte[] filePath);
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns an array of strings with the file names in the directory
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * represented by this file. The result is {@ null} if this file is not a
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * directory.
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The entries {@code .} and {@code ..} representing the current and parent
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * directory are not returned as part of the list.
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * </p>
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return an array of strings with file names or {@code null}.
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #isDirectory
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public java.lang.String[] list() {
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!isDirectory()) {
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[][] implList = listImpl(properPath(true));
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (implList == null) {
941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return new String[0];
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String result[] = new String[implList.length];
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int index = 0; index < implList.length; index++) {
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result[index] = Util.toString(implList[index]);
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns an array of files contained in the directory represented by this
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file. The result is {@code null} if this file is not a directory. The
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * paths of the files in the array are absolute if the path of this file is
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * absolute, they are relative otherwise.
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return an array of files or {@code null}.
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #list
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File[] listFiles() {
964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String[] tempNames = list();
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (tempNames == null) {
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int resultLength = tempNames.length;
969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        File results[] = new File[resultLength];
970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < resultLength; i++) {
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            results[i] = new File(this, tempNames[i]);
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return results;
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets a list of the files in the directory represented by this file. This
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * list is then filtered through a FilenameFilter and files with matching
979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * names are returned as an array of files. Returns {@code null} if this
980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file is not a directory. If {@code filter} is {@code null} then all
981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * filenames match.
982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The entries {@code .} and {@code ..} representing the current and parent
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * directories are not returned as part of the list.
985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * </p>
986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param filter
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the filter to match names against, may be {@code null}.
989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return an array of files or {@code null}.
990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #list(FilenameFilter filter)
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File[] listFiles(FilenameFilter filter) {
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String[] tempNames = list(filter);
998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (tempNames == null) {
999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int resultLength = tempNames.length;
1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        File results[] = new File[resultLength];
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = 0; i < resultLength; i++) {
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            results[i] = new File(this, tempNames[i]);
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return results;
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets a list of the files in the directory represented by this file. This
1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * list is then filtered through a FileFilter and matching files are
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * returned as an array of files. Returns {@code null} if this file is not a
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * directory. If {@code filter} is {@code null} then all files match.
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The entries {@code .} and {@code ..} representing the current and parent
1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * directories are not returned as part of the list.
1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * </p>
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param filter
1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the filter to match names against, may be {@code null}.
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return an array of files or {@code null}.
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public File[] listFiles(FileFilter filter) {
1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!isDirectory()) {
1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[][] implList = listImpl(properPath(true));
1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (implList == null) {
1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return new File[0];
1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        List<File> tempResult = new ArrayList<File>();
1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int index = 0; index < implList.length; index++) {
1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String aName = Util.toString(implList[index]);
1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            File aFile = new File(this, aName);
1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (filter == null || filter.accept(aFile)) {
1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                tempResult.add(aFile);
1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return tempResult.toArray(new File[tempResult.size()]);
1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Gets a list of the files in the directory represented by this file. This
1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * list is then filtered through a FilenameFilter and the names of files
1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * with matching names are returned as an array of strings. Returns
1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code null} if this file is not a directory. If {@code filter} is
1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * {@code null} then all filenames match.
1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * <p>
1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The entries {@code .} and {@code ..} representing the current and parent
1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * directories are not returned as part of the list.
1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * </p>
1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param filter
1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the filter to match names against, may be {@code null}.
1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return an array of files or {@code null}.
1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies read
1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access to this file.
1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public java.lang.String[] list(FilenameFilter filter) {
1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkRead(path);
1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!isDirectory()) {
1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        byte[][] implList = listImpl(properPath(true));
1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (implList == null) {
1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return new String[0];
1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        java.util.Vector<String> tempResult = new java.util.Vector<String>();
1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int index = 0; index < implList.length; index++) {
1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String aName = Util.toString(implList[index]);
1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (filter == null || filter.accept(this, aName)) {
1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                tempResult.addElement(aName);
1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String[] result = new String[tempResult.size()];
1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        tempResult.copyInto(result);
1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private synchronized static native byte[][] listImpl(byte[] path);
1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates the directory named by the trailing filename of this file. Does
1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * not create the complete path required to create this directory.
1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the directory has been created, {@code false}
1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         otherwise.
1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies write
1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access for this file.
1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #mkdirs
1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean mkdir() {
1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkWrite(path);
1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return mkdirImpl(properPath(true));
1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean mkdirImpl(byte[] filePath);
1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates the directory named by the trailing filename of this file,
1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * including the complete directory path required to create this directory.
1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the necessary directories have been created,
1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         {@code false} if the target directory already exists or one of
1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         the directories can not be created.
1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies write
1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access for this file.
1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @see #mkdir
1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean mkdirs() {
1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* If the terminal directory already exists, answer false */
1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (exists()) {
1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* If the receiver can be created, answer true */
1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (mkdir()) {
1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return true;
1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String parentDir = getParent();
1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* If there is no parent and we were not created, answer false */
1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (parentDir == null) {
1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* Otherwise, try to create a parent directory and then this directory */
1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return (new File(parentDir).mkdirs() && mkdir());
1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates a new, empty file on the file system according to the path
1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * information stored in this file.
1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the file has been created, {@code false} if it
1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *         already exists.
1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an I/O error occurs or the directory does not exist where
1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             the file should have been created.
1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies write
1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access for this file.
1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean createNewFile() throws IOException {
1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkWrite(path);
1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (0 == path.length()) {
1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IOException(Msg.getString("KA012")); //$NON-NLS-1$
1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int result = newFileImpl(properPath(true));
1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (result) {
1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0:
1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return true;
1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1:
1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return false;
1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // BEGIN android-changed
1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            default: {
1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Try to provide a reasonable explanation.
1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                String msg = null;
1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                try {
1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    File parent = getAbsoluteFile().getParentFile();
1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    if (parent == null) {
1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        /*
1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                         * This shouldn't happen, unless the caller
1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                         * tried to create "/". We just use the
1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                         * generic message for this case.
1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                         */
1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    } else if (! parent.exists()) {
1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        msg = "Parent directory of file does not exist";
1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    } else if (! parent.isDirectory()) {
1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        msg = "Parent of file is not a directory";
1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    } else if (! parent.canWrite()) {
1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        msg = "Parent directory of file is not writable";
1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                } catch (RuntimeException ex) {
1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    /*
1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * Ignore the exception, and just fall through to
1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     * use a generic message.
1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     */
1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if (msg == null) {
1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    msg = "Cannot create";
1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw new IOException(msg + ": " + path); //$NON-NLS-1$
1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // END android-changed
1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native int newFileImpl(byte[] filePath);
1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates an empty temporary file using the given prefix and suffix as part
1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * of the file name. If suffix is null, {@code .tmp} is used. This method
1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is a convenience method that calls {@link #createTempFile(String, String,
1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * File)} with the third argument being {@code null}.
1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param prefix
1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the prefix to the temp file name.
1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param suffix
1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the suffix to the temp file name.
1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the temporary file.
1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an error occurs when writing the file.
1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static File createTempFile(String prefix, String suffix)
1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throws IOException {
1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return createTempFile(prefix, suffix, null);
1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Creates an empty temporary file in the given directory using the given
1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * prefix and suffix as part of the file name.
1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param prefix
1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the prefix to the temp file name.
1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param suffix
1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the suffix to the temp file name.
1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param directory
1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the location to which the temp file is to be written, or
1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            {@code null} for the default location for temporary files,
1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            which is taken from the "java.io.tmpdir" system property. It
1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            may be necessary to set this property to an existing, writable
1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            directory for this method to work properly.
1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the temporary file.
1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IllegalArgumentException
1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the length of {@code prefix} is less than 3.
1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws IOException
1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if an error occurs when writing the file.
1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static File createTempFile(String prefix, String suffix,
1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            File directory) throws IOException {
1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Force a prefix null check first
1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (prefix.length() < 3) {
1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            throw new IllegalArgumentException(Msg.getString("K006b")); //$NON-NLS-1$
1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String newSuffix = suffix == null ? ".tmp" : suffix; //$NON-NLS-1$
1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String tmpDir = "."; //$NON-NLS-1$
1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        tmpDir = AccessController.doPrivileged(new PriviAction<String>(
1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                "java.io.tmpdir", ".")); //$NON-NLS-1$//$NON-NLS-2$
1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        File result, tmpDirFile = directory == null ? new File(tmpDir)
1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                : directory;
1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        do {
1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = genTempFile(prefix, newSuffix, tmpDirFile);
1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } while (!result.createNewFile());
1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;
1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static File genTempFile(String prefix, String suffix, File directory) {
1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (counter == 0) {
1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            int newInt = new java.util.Random().nextInt();
1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            counter = ((newInt / 65535) & 0xFFFF) + 0x2710;
1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        StringBuilder newName = new StringBuilder();
1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newName.append(prefix);
1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newName.append(counter++);
1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        newName.append(suffix);
1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new File(directory, newName.toString());
1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // BEGIN android-changed
1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // Removing platform independent code because we're always on linux.
1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a string representing the proper path for this file. If this file
1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * path is absolute, the user.dir property is not prepended, otherwise it
1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * is.
1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param internal
1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            is user.dir internal.
1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return the proper path.
1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    byte[] properPath(boolean internal) {
1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (properPath != null) {
1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return properPath;
1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if(path.length() > 0 && path.charAt(0) == separatorChar) {
1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return properPath = Util.getBytes(path);
1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Check security by getting user.dir when the path is not absolute
1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String userdir;
1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (internal) {
1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            userdir = AccessController.doPrivileged(new PriviAction<String>(
1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    "user.dir")); //$NON-NLS-1$
1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            userdir = System.getProperty("user.dir"); //$NON-NLS-1$
1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (path.length() == 0) {
1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return properPath = Util.getBytes(userdir);
1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int length = userdir.length();
1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (length > 0 && userdir.charAt(length - 1) == separatorChar) {
1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return properPath = Util.getBytes(userdir + path);
1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return properPath = Util.getBytes(userdir + separator + path);
1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // END android-changed
1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // BEGIN android-removed
1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // private static native byte[] properPathImpl(byte[] path);
1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // END android-removed
1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Renames this file to the name represented by the {@code dest} file. This
1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * works for both normal files and directories.
1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param dest
1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *            the file containing the new name.
1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return {@code true} if the File was renamed, {@code false} otherwise.
1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws SecurityException
1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies write
1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             access for this file or the {@code dest} file.
1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public boolean renameTo(java.io.File dest) {
1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        SecurityManager security = System.getSecurityManager();
1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (security != null) {
1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkWrite(path);
1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            security.checkWrite(dest.path);
1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return renameToImpl(properPath(true), dest.properPath(true));
1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private native boolean renameToImpl(byte[] pathExist, byte[] pathNew);
1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a string containing a concise, human-readable description of this
1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * file.
1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return a printable representation of this file.
1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public String toString() {
1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return path;
1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a Uniform Resource Identifier for this file. The URI is system
1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * dependent and may not be transferable between different operating / file
1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * systems.
1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return an URI for this file.
1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public URI toURI() {
1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String name = getAbsoluteName();
1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!name.startsWith("/")) { //$NON-NLS-1$
1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // start with sep.
1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return new URI("file", null, //$NON-NLS-1$
1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        new StringBuilder(name.length() + 1).append('/')
1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                .append(name).toString(), null, null);
1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else if (name.startsWith("//")) { //$NON-NLS-1$
1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                return new URI("file", name, null); // UNC path //$NON-NLS-1$
1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return new URI("file", null, name, null, null); //$NON-NLS-1$
1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (URISyntaxException e) {
1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // this should never happen
1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return null;
1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns a Uniform Resource Locator for this file. The URL is system
1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * dependent and may not be transferable between different operating / file
1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * systems.
1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @return an URL for this file.
1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @throws java.net.MalformedURLException
1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *             if the path cannot be transformed into an URL.
1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @since Android 1.0
1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public URL toURL() throws java.net.MalformedURLException {
1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String name = getAbsoluteName();
1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!name.startsWith("/")) { //$NON-NLS-1$
1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // start with sep.
1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return new URL("file", "", -1, new StringBuilder(name.length() + 1) //$NON-NLS-1$ //$NON-NLS-2$
1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    .append('/').append(name).toString(), null);
1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else if (name.startsWith("//")) { //$NON-NLS-1$
1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return new URL("file:" + name); // UNC path //$NON-NLS-1$
1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return new URL("file", "", -1, name, null); //$NON-NLS-1$ //$NON-NLS-2$
1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private String getAbsoluteName() {
1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        File f = getAbsoluteFile();
1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        String name = f.getPath();
1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (f.isDirectory() && name.charAt(name.length() - 1) != separatorChar) {
1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            // Directories must end with a slash
1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            name = new StringBuilder(name.length() + 1).append(name)
1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    .append('/').toString();
1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (separatorChar != '/') { // Must convert slashes.
1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            name = name.replace(separatorChar, '/');
1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return name;
1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void writeObject(ObjectOutputStream stream) throws IOException {
1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        stream.defaultWriteObject();
1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        stream.writeChar(separatorChar);
1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private void readObject(ObjectInputStream stream) throws IOException,
1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ClassNotFoundException {
1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        stream.defaultReadObject();
1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char inSeparator = stream.readChar();
1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        path = path.replace(inSeparator, separatorChar);
1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// BEGIN android-added
1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Implements the actual DeleteOnExit mechanism. Is registered as a shutdown
1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * hook in the Runtime, once it is actually being used.
1444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectclass DeleteOnExit extends Thread {
1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Our singleton instance.
1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private static DeleteOnExit instance;
1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Our list of files scheduled for deletion.
1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    private ArrayList<String> files = new ArrayList<String>();
1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Returns our singleton instance, creating it if necessary.
1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static synchronized DeleteOnExit getInstance() {
1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (instance == null) {
1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            instance = new DeleteOnExit();
1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Runtime.getRuntime().addShutdownHook(instance);
1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return instance;
1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Schedules a file for deletion.
1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * @param filename The file to delete.
1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void addFile(String filename) {
1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        synchronized(files) {
1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!files.contains(filename)) {
1477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                files.add(filename);
1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
1483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Does the actual work. Note we (a) first sort the files lexicographically
1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * and then (b) delete them in reverse order. This is to make sure files
1485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * get deleted before their parent directories.
1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    @Override
1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public void run() {
1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Collections.sort(files);
1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        for (int i = files.size() - 1; i >= 0; i--) {
1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            new File(files.get(i)).delete();
1492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// END android-added
1496