auto import from //depot/cupcake/@132589

This commit is contained in:
The Android Open Source Project
2009-03-03 14:04:24 -08:00
parent 3dec7d563a
commit 076357b856
310 changed files with 4072 additions and 18131 deletions

View File

@@ -18,7 +18,6 @@ package android.content;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.AssetFileDescriptor;
import android.content.res.Configuration;
import android.database.Cursor;
import android.database.CursorToBulkCursorAdaptor;
@@ -163,13 +162,6 @@ public abstract class ContentProvider implements ComponentCallbacks {
return ContentProvider.this.openFile(uri, mode);
}
public AssetFileDescriptor openAssetFile(Uri uri, String mode)
throws FileNotFoundException {
if (mode != null && mode.startsWith("rw")) checkWritePermission(uri);
else checkReadPermission(uri);
return ContentProvider.this.openAssetFile(uri, mode);
}
public ISyncAdapter getSyncAdapter() {
checkWritePermission(null);
return ContentProvider.this.getSyncAdapter().getISyncAdapter();
@@ -446,9 +438,8 @@ public abstract class ContentProvider implements ComponentCallbacks {
* of this method should create a new ParcelFileDescriptor for each call.
*
* @param uri The URI whose file is to be opened.
* @param mode Access mode for the file. May be "r" for read-only access,
* "rw" for read and write access, or "rwt" for read and write access
* that truncates any existing file.
* @param mode Access mode for the file. May be "r" for read-only access
* or "rw" for read and write access.
*
* @return Returns a new ParcelFileDescriptor which you can use to access
* the file.
@@ -457,66 +448,19 @@ public abstract class ContentProvider implements ComponentCallbacks {
* no file associated with the given URI or the mode is invalid.
* @throws SecurityException Throws SecurityException if the caller does
* not have permission to access the file.
*
* @see #openAssetFile(Uri, String)
* @see #openFileHelper(Uri, String)
*/
*/
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
throw new FileNotFoundException("No files supported by provider at "
+ uri);
}
/**
* This is like {@link #openFile}, but can be implemented by providers
* that need to be able to return sub-sections of files, often assets
* inside of their .apk. Note that when implementing this your clients
* must be able to deal with such files, either directly with
* {@link ContentResolver#openAssetFileDescriptor
* ContentResolver.openAssetFileDescriptor}, or by using the higher-level
* {@link ContentResolver#openInputStream ContentResolver.openInputStream}
* or {@link ContentResolver#openOutputStream ContentResolver.openOutputStream}
* methods.
*
* <p><em>Note: if you are implementing this to return a full file, you
* should create the AssetFileDescriptor with
* {@link AssetFileDescriptor#UNKNOWN_LENGTH} to be compatible with
* applications that can not handle sub-sections of files.</em></p>
*
* @param uri The URI whose file is to be opened.
* @param mode Access mode for the file. May be "r" for read-only access,
* "w" for write-only access (erasing whatever data is currently in
* the file), "wa" for write-only access to append to any existing data,
* "rw" for read and write access on any existing data, and "rwt" for read
* and write access that truncates any existing file.
*
* @return Returns a new AssetFileDescriptor which you can use to access
* the file.
*
* @throws FileNotFoundException Throws FileNotFoundException if there is
* no file associated with the given URI or the mode is invalid.
* @throws SecurityException Throws SecurityException if the caller does
* not have permission to access the file.
*
* @see #openFile(Uri, String)
* @see #openFileHelper(Uri, String)
*/
public AssetFileDescriptor openAssetFile(Uri uri, String mode)
throws FileNotFoundException {
ParcelFileDescriptor fd = openFile(uri, mode);
return fd != null ? new AssetFileDescriptor(fd, 0, -1) : null;
}
/**
* Convenience for subclasses that wish to implement {@link #openFile}
* by looking up a column named "_data" at the given URI.
*
* @param uri The URI to be opened.
* @param mode The file mode. May be "r" for read-only access,
* "w" for write-only access (erasing whatever data is currently in
* the file), "wa" for write-only access to append to any existing data,
* "rw" for read and write access on any existing data, and "rwt" for read
* and write access that truncates any existing file.
* @param mode The file mode.
*
* @return Returns a new ParcelFileDescriptor that can be used by the
* client to access the file.
@@ -545,7 +489,16 @@ public abstract class ContentProvider implements ComponentCallbacks {
throw new FileNotFoundException("Column _data not found.");
}
int modeBits = ContentResolver.modeToMode(uri, mode);
int modeBits;
if ("r".equals(mode)) {
modeBits = ParcelFileDescriptor.MODE_READ_ONLY;
} else if ("rw".equals(mode)) {
modeBits = ParcelFileDescriptor.MODE_READ_WRITE
| ParcelFileDescriptor.MODE_CREATE;
} else {
throw new FileNotFoundException("Bad mode for " + uri + ": "
+ mode);
}
return ParcelFileDescriptor.open(new File(path), modeBits);
}

View File

@@ -16,7 +16,6 @@
package android.content;
import android.content.res.AssetFileDescriptor;
import android.database.BulkCursorNative;
import android.database.BulkCursorToCursorAdaptor;
import android.database.Cursor;
@@ -188,25 +187,6 @@ abstract public class ContentProviderNative extends Binder implements IContentPr
return true;
}
case OPEN_ASSET_FILE_TRANSACTION:
{
data.enforceInterface(IContentProvider.descriptor);
Uri url = Uri.CREATOR.createFromParcel(data);
String mode = data.readString();
AssetFileDescriptor fd;
fd = openAssetFile(url, mode);
reply.writeNoException();
if (fd != null) {
reply.writeInt(1);
fd.writeToParcel(reply,
Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
reply.writeInt(0);
}
return true;
}
case GET_SYNC_ADAPTER_TRANSACTION:
{
data.enforceInterface(IContentProvider.descriptor);
@@ -433,29 +413,6 @@ final class ContentProviderProxy implements IContentProvider
return fd;
}
public AssetFileDescriptor openAssetFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IContentProvider.descriptor);
url.writeToParcel(data, 0);
data.writeString(mode);
mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0);
DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
int has = reply.readInt();
AssetFileDescriptor fd = has != 0
? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
data.recycle();
reply.recycle();
return fd;
}
public ISyncAdapter getSyncAdapter() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();

View File

@@ -17,7 +17,6 @@
package android.content;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.database.Cursor;
@@ -29,7 +28,6 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.text.TextUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -172,143 +170,6 @@ public abstract class ContentResolver {
* <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li>
* <li>file ({@link #SCHEME_FILE})</li>
* </ul>
*
* <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information
* on these schemes.
*
* @param uri The desired URI.
* @return InputStream
* @throws FileNotFoundException if the provided URI could not be opened.
* @see #openAssetFileDescriptor(Uri, String)
*/
public final InputStream openInputStream(Uri uri)
throws FileNotFoundException {
String scheme = uri.getScheme();
if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
// Note: left here to avoid breaking compatibility. May be removed
// with sufficient testing.
OpenResourceIdResult r = getResourceId(uri);
try {
InputStream stream = r.r.openRawResource(r.id);
return stream;
} catch (Resources.NotFoundException ex) {
throw new FileNotFoundException("Resource does not exist: " + uri);
}
} else if (SCHEME_FILE.equals(scheme)) {
// Note: left here to avoid breaking compatibility. May be removed
// with sufficient testing.
return new FileInputStream(uri.getPath());
} else {
AssetFileDescriptor fd = openAssetFileDescriptor(uri, "r");
try {
return fd != null ? fd.createInputStream() : null;
} catch (IOException e) {
throw new FileNotFoundException("Unable to create stream");
}
}
}
/**
* Synonym for {@link #openOutputStream(Uri, String)
* openOutputStream(uri, "w")}.
* @throws FileNotFoundException if the provided URI could not be opened.
*/
public final OutputStream openOutputStream(Uri uri)
throws FileNotFoundException {
return openOutputStream(uri, "w");
}
/**
* Open a stream on to the content associated with a content URI. If there
* is no data associated with the URI, FileNotFoundException is thrown.
*
* <h5>Accepts the following URI schemes:</h5>
* <ul>
* <li>content ({@link #SCHEME_CONTENT})</li>
* <li>file ({@link #SCHEME_FILE})</li>
* </ul>
*
* <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information
* on these schemes.
*
* @param uri The desired URI.
* @param mode May be "w", "wa", "rw", or "rwt".
* @return OutputStream
* @throws FileNotFoundException if the provided URI could not be opened.
* @see #openAssetFileDescriptor(Uri, String)
*/
public final OutputStream openOutputStream(Uri uri, String mode)
throws FileNotFoundException {
AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode);
try {
return fd != null ? fd.createOutputStream() : null;
} catch (IOException e) {
throw new FileNotFoundException("Unable to create stream");
}
}
/**
* Open a raw file descriptor to access data under a "content:" URI. This
* is like {@link #openAssetFileDescriptor(Uri, String)}, but uses the
* underlying {@link ContentProvider#openFile}
* ContentProvider.openFile()} method, so will <em>not</em> work with
* providers that return sub-sections of files. If at all possible,
* you should use {@link #openAssetFileDescriptor(Uri, String)}. You
* will receive a FileNotFoundException exception if the provider returns a
* sub-section of a file.
*
* <h5>Accepts the following URI schemes:</h5>
* <ul>
* <li>content ({@link #SCHEME_CONTENT})</li>
* <li>file ({@link #SCHEME_FILE})</li>
* </ul>
*
* <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information
* on these schemes.
*
* @param uri The desired URI to open.
* @param mode The file mode to use, as per {@link ContentProvider#openFile
* ContentProvider.openFile}.
* @return Returns a new ParcelFileDescriptor pointing to the file. You
* own this descriptor and are responsible for closing it when done.
* @throws FileNotFoundException Throws FileNotFoundException of no
* file exists under the URI or the mode is invalid.
* @see #openAssetFileDescriptor(Uri, String)
*/
public final ParcelFileDescriptor openFileDescriptor(Uri uri,
String mode) throws FileNotFoundException {
AssetFileDescriptor afd = openAssetFileDescriptor(uri, mode);
if (afd == null) {
return null;
}
if (afd.getDeclaredLength() < 0) {
// This is a full file!
return afd.getParcelFileDescriptor();
}
// Client can't handle a sub-section of a file, so close what
// we got and bail with an exception.
try {
afd.close();
} catch (IOException e) {
}
throw new FileNotFoundException("Not a whole file");
}
/**
* Open a raw file descriptor to access data under a "content:" URI. This
* interacts with the underlying {@link ContentProvider#openAssetFile}
* ContentProvider.openAssetFile()} method of the provider associated with the
* given URI, to retrieve any file stored there.
*
* <h5>Accepts the following URI schemes:</h5>
* <ul>
* <li>content ({@link #SCHEME_CONTENT})</li>
* <li>android.resource ({@link #SCHEME_ANDROID_RESOURCE})</li>
* <li>file ({@link #SCHEME_FILE})</li>
* </ul>
* <h5>The android.resource ({@link #SCHEME_ANDROID_RESOURCE}) Scheme</h5>
* <p>
* A Uri object can be used to reference a resource in an APK file. The
@@ -332,130 +193,129 @@ public abstract class ContentResolver {
* <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/raw/my_resource");</pre>
* </li>
* </ul>
* @param uri The desired "content:" URI.
* @return InputStream
* @throws FileNotFoundException if the provided URI could not be opened.
*/
public final InputStream openInputStream(Uri uri)
throws FileNotFoundException {
String scheme = uri.getScheme();
if (SCHEME_CONTENT.equals(scheme)) {
ParcelFileDescriptor fd = openFileDescriptor(uri, "r");
return fd != null ? new ParcelFileDescriptor.AutoCloseInputStream(fd) : null;
} else if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
String authority = uri.getAuthority();
Resources r;
if (TextUtils.isEmpty(authority)) {
throw new FileNotFoundException("No authority: " + uri);
} else {
try {
r = mContext.getPackageManager().getResourcesForApplication(authority);
} catch (NameNotFoundException ex) {
throw new FileNotFoundException("No package found for authority: " + uri);
}
}
List<String> path = uri.getPathSegments();
if (path == null) {
throw new FileNotFoundException("No path: " + uri);
}
int len = path.size();
int id;
if (len == 1) {
try {
id = Integer.parseInt(path.get(0));
} catch (NumberFormatException e) {
throw new FileNotFoundException("Single path segment is not a resource ID: " + uri);
}
} else if (len == 2) {
id = r.getIdentifier(path.get(1), path.get(0), authority);
} else {
throw new FileNotFoundException("More than two path segments: " + uri);
}
if (id == 0) {
throw new FileNotFoundException("No resource found for: " + uri);
}
try {
InputStream stream = r.openRawResource(id);
return stream;
} catch (Resources.NotFoundException ex) {
throw new FileNotFoundException("Resource ID does not exist: " + uri);
}
} else if (SCHEME_FILE.equals(scheme)) {
return new FileInputStream(uri.getPath());
} else {
throw new FileNotFoundException("Unknown scheme: " + uri);
}
}
/**
* Open a stream on to the content associated with a content URI. If there
* is no data associated with the URI, FileNotFoundException is thrown.
*
* <h5>Accepts the following URI schemes:</h5>
* <ul>
* <li>content ({@link #SCHEME_CONTENT})</li>
* </ul>
*
* @param uri The desired "content:" URI.
* @return OutputStream
*/
public final OutputStream openOutputStream(Uri uri)
throws FileNotFoundException {
String scheme = uri.getScheme();
if (SCHEME_CONTENT.equals(scheme)) {
ParcelFileDescriptor fd = openFileDescriptor(uri, "rw");
return fd != null
? new ParcelFileDescriptor.AutoCloseOutputStream(fd) : null;
} else {
throw new FileNotFoundException("Unknown scheme: " + uri);
}
}
/**
* Open a raw file descriptor to access data under a "content:" URI. This
* interacts with the underlying {@link ContentProvider#openFile}
* ContentProvider.openFile()} method of the provider associated with the
* given URI, to retrieve any file stored there.
*
* <h5>Accepts the following URI schemes:</h5>
* <ul>
* <li>content ({@link #SCHEME_CONTENT})</li>
* </ul>
*
* @param uri The desired URI to open.
* @param mode The file mode to use, as per {@link ContentProvider#openAssetFile
* ContentProvider.openAssetFile}.
* @param mode The file mode to use, as per {@link ContentProvider#openFile
* ContentProvider.openFile}.
* @return Returns a new ParcelFileDescriptor pointing to the file. You
* own this descriptor and are responsible for closing it when done.
* @throws FileNotFoundException Throws FileNotFoundException of no
* file exists under the URI or the mode is invalid.
*/
public final AssetFileDescriptor openAssetFileDescriptor(Uri uri,
public final ParcelFileDescriptor openFileDescriptor(Uri uri,
String mode) throws FileNotFoundException {
String scheme = uri.getScheme();
if (SCHEME_ANDROID_RESOURCE.equals(scheme)) {
if (!"r".equals(mode)) {
throw new FileNotFoundException("Can't write resources: " + uri);
}
OpenResourceIdResult r = getResourceId(uri);
try {
return r.r.openRawResourceFd(r.id);
} catch (Resources.NotFoundException ex) {
throw new FileNotFoundException("Resource does not exist: " + uri);
}
} else if (SCHEME_FILE.equals(scheme)) {
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
new File(uri.getPath()), modeToMode(uri, mode));
return new AssetFileDescriptor(pfd, 0, -1);
} else {
IContentProvider provider = acquireProvider(uri);
if (provider == null) {
throw new FileNotFoundException("No content provider: " + uri);
}
try {
AssetFileDescriptor fd = provider.openAssetFile(uri, mode);
if(fd == null) {
releaseProvider(provider);
return null;
}
ParcelFileDescriptor pfd = new ParcelFileDescriptorInner(
fd.getParcelFileDescriptor(), provider);
return new AssetFileDescriptor(pfd, fd.getStartOffset(),
fd.getDeclaredLength());
} catch (RemoteException e) {
IContentProvider provider = acquireProvider(uri);
if (provider == null) {
throw new FileNotFoundException("No content provider: " + uri);
}
try {
ParcelFileDescriptor fd = provider.openFile(uri, mode);
if(fd == null) {
releaseProvider(provider);
throw new FileNotFoundException("Dead content provider: " + uri);
} catch (FileNotFoundException e) {
releaseProvider(provider);
throw e;
} catch (RuntimeException e) {
releaseProvider(provider);
throw e;
return null;
}
return new ParcelFileDescriptorInner(fd, provider);
} catch (RemoteException e) {
releaseProvider(provider);
throw new FileNotFoundException("Dead content provider: " + uri);
} catch (FileNotFoundException e) {
releaseProvider(provider);
throw e;
} catch (RuntimeException e) {
releaseProvider(provider);
throw e;
}
}
class OpenResourceIdResult {
Resources r;
int id;
}
OpenResourceIdResult getResourceId(Uri uri) throws FileNotFoundException {
String authority = uri.getAuthority();
Resources r;
if (TextUtils.isEmpty(authority)) {
throw new FileNotFoundException("No authority: " + uri);
} else {
try {
r = mContext.getPackageManager().getResourcesForApplication(authority);
} catch (NameNotFoundException ex) {
throw new FileNotFoundException("No package found for authority: " + uri);
}
}
List<String> path = uri.getPathSegments();
if (path == null) {
throw new FileNotFoundException("No path: " + uri);
}
int len = path.size();
int id;
if (len == 1) {
try {
id = Integer.parseInt(path.get(0));
} catch (NumberFormatException e) {
throw new FileNotFoundException("Single path segment is not a resource ID: " + uri);
}
} else if (len == 2) {
id = r.getIdentifier(path.get(1), path.get(0), authority);
} else {
throw new FileNotFoundException("More than two path segments: " + uri);
}
if (id == 0) {
throw new FileNotFoundException("No resource found for: " + uri);
}
OpenResourceIdResult res = new OpenResourceIdResult();
res.r = r;
res.id = id;
return res;
}
/** @hide */
static public int modeToMode(Uri uri, String mode) throws FileNotFoundException {
int modeBits;
if ("r".equals(mode)) {
modeBits = ParcelFileDescriptor.MODE_READ_ONLY;
} else if ("w".equals(mode) || "wt".equals(mode)) {
modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
| ParcelFileDescriptor.MODE_CREATE
| ParcelFileDescriptor.MODE_TRUNCATE;
} else if ("wa".equals(mode)) {
modeBits = ParcelFileDescriptor.MODE_WRITE_ONLY
| ParcelFileDescriptor.MODE_CREATE
| ParcelFileDescriptor.MODE_APPEND;
} else if ("rw".equals(mode)) {
modeBits = ParcelFileDescriptor.MODE_READ_WRITE
| ParcelFileDescriptor.MODE_CREATE;
} else if ("rwt".equals(mode)) {
modeBits = ParcelFileDescriptor.MODE_READ_WRITE
| ParcelFileDescriptor.MODE_CREATE
| ParcelFileDescriptor.MODE_TRUNCATE;
} else {
throw new FileNotFoundException("Bad mode for " + uri + ": "
+ mode);
}
return modeBits;
}
/**
* Inserts a row into a table at the given URL.
*

View File

@@ -75,13 +75,6 @@ abstract class ContentServiceNative extends Binder implements IContentService
{
try {
switch (code) {
case 5038: {
data.readString(); // ignore the interface token that service generated
Uri uri = Uri.parse(data.readString());
notifyChange(uri, null, false, false);
return true;
}
case REGISTER_CONTENT_OBSERVER_TRANSACTION: {
Uri uri = Uri.CREATOR.createFromParcel(data);
boolean notifyForDescendents = data.readInt() != 0;

View File

@@ -16,7 +16,6 @@
package android.content;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.CursorWindow;
import android.database.IBulkCursor;
@@ -53,8 +52,6 @@ public interface IContentProvider extends IInterface {
String[] selectionArgs) throws RemoteException;
public ParcelFileDescriptor openFile(Uri url, String mode)
throws RemoteException, FileNotFoundException;
public AssetFileDescriptor openAssetFile(Uri url, String mode)
throws RemoteException, FileNotFoundException;
public ISyncAdapter getSyncAdapter() throws RemoteException;
/* IPC constants */
@@ -68,5 +65,4 @@ public interface IContentProvider extends IInterface {
static final int GET_SYNC_ADAPTER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 10;
static final int BULK_INSERT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 12;
static final int OPEN_FILE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 13;
static final int OPEN_ASSET_FILE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 14;
}

View File

@@ -522,7 +522,6 @@ import java.util.Set;
* <li> {@link #CATEGORY_ALTERNATIVE}
* <li> {@link #CATEGORY_SELECTED_ALTERNATIVE}
* <li> {@link #CATEGORY_LAUNCHER}
* <li> {@link #CATEGORY_INFO}
* <li> {@link #CATEGORY_HOME}
* <li> {@link #CATEGORY_PREFERENCE}
* <li> {@link #CATEGORY_GADGET}
@@ -1546,13 +1545,6 @@ public class Intent implements Parcelable {
*/
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER";
/**
* Provides information about the package it is in; typically used if
* a package does not contain a {@link #CATEGORY_LAUNCHER} to provide
* a front-door to the user without having to be shown in the all apps list.
*/
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_INFO = "android.intent.category.INFO";
/**
* This is the home activity, that is the first activity that is displayed
* when the device boots.

View File

@@ -479,26 +479,6 @@ public abstract class PackageManager {
public abstract PackageInfo getPackageInfo(String packageName, int flags)
throws NameNotFoundException;
/**
* Return a "good" intent to launch a front-door activity in a package,
* for use for example to implement an "open" button when browsing through
* packages. The current implementation will look first for a main
* activity in the category {@link Intent#CATEGORY_INFO}, next for a
* main activity in the category {@link Intent#CATEGORY_LAUNCHER}, or return
* null if neither are found.
*
* <p>Throws {@link NameNotFoundException} if a package with the given
* name can not be found on the system.
*
* @param packageName The name of the package to inspect.
*
* @return Returns either a fully-qualified Intent that can be used to
* launch the main activity in the package, or null if the package does
* not contain such an activity.
*/
public abstract Intent getLaunchIntentForPackage(String packageName)
throws NameNotFoundException;
/**
* Return an array of all of the secondary group-ids that have been
* assigned to a package.

View File

@@ -16,13 +16,9 @@
package android.content.res;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
@@ -30,32 +26,16 @@ import java.io.IOException;
* opened FileDescriptor that can be used to read the data, as well as the
* offset and length of that entry's data in the file.
*/
public class AssetFileDescriptor implements Parcelable {
/**
* Length used with {@link #AssetFileDescriptor(ParcelFileDescriptor, long, long)}
* and {@link #getDeclaredLength} when a length has not been declared. This means
* the data extends to the end of the file.
*/
public static final long UNKNOWN_LENGTH = -1;
public class AssetFileDescriptor {
private final ParcelFileDescriptor mFd;
private final long mStartOffset;
private final long mLength;
/**
* Create a new AssetFileDescriptor from the given values.
* @param fd The underlying file descriptor.
* @param startOffset The location within the file that the asset starts.
* This must be 0 if length is UNKNOWN_LENGTH.
* @param length The number of bytes of the asset, or
* {@link #UNKNOWN_LENGTH if it extends to the end of the file.
*/
public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset,
long length) {
if (length < 0 && startOffset != 0) {
throw new IllegalArgumentException(
"startOffset must be 0 when using UNKNOWN_LENGTH");
}
mFd = fd;
mStartOffset = startOffset;
mLength = length;
@@ -86,33 +66,9 @@ public class AssetFileDescriptor implements Parcelable {
}
/**
* Returns the total number of bytes of this asset entry's data. May be
* {@link #UNKNOWN_LENGTH} if the asset extends to the end of the file.
* If the AssetFileDescriptor was constructed with {@link #UNKNOWN_LENGTH},
* this will use {@link ParcelFileDescriptor#getStatSize()
* ParcelFileDescriptor.getStatSize()} to find the total size of the file,
* returning that number if found or {@link #UNKNOWN_LENGTH} if it could
* not be determined.
*
* @see #getDeclaredLength()
* Returns the total number of bytes of this asset entry's data.
*/
public long getLength() {
if (mLength >= 0) {
return mLength;
}
long len = mFd.getStatSize();
return len >= 0 ? len : UNKNOWN_LENGTH;
}
/**
* Return the actual number of bytes that were declared when the
* AssetFileDescriptor was constructed. Will be
* {@link #UNKNOWN_LENGTH} if the length was not declared, meaning data
* should be read to the end of the file.
*
* @see #getDeclaredLength()
*/
public long getDeclaredLength() {
return mLength;
}
@@ -122,227 +78,4 @@ public class AssetFileDescriptor implements Parcelable {
public void close() throws IOException {
mFd.close();
}
/**
* Create and return a new auto-close input stream for this asset. This
* will either return a full asset {@link AutoCloseInputStream}, or
* an underlying {@link ParcelFileDescriptor.AutoCloseInputStream
* ParcelFileDescriptor.AutoCloseInputStream} depending on whether the
* the object represents a complete file or sub-section of a file. You
* should only call this once for a particular asset.
*/
public FileInputStream createInputStream() throws IOException {
if (mLength < 0) {
return new ParcelFileDescriptor.AutoCloseInputStream(mFd);
}
return new AutoCloseInputStream(this);
}
/**
* Create and return a new auto-close output stream for this asset. This
* will either return a full asset {@link AutoCloseOutputStream}, or
* an underlying {@link ParcelFileDescriptor.AutoCloseOutputStream
* ParcelFileDescriptor.AutoCloseOutputStream} depending on whether the
* the object represents a complete file or sub-section of a file. You
* should only call this once for a particular asset.
*/
public FileOutputStream createOutputStream() throws IOException {
if (mLength < 0) {
return new ParcelFileDescriptor.AutoCloseOutputStream(mFd);
}
return new AutoCloseOutputStream(this);
}
@Override
public String toString() {
return "{AssetFileDescriptor: " + mFd
+ " start=" + mStartOffset + " len=" + mLength + "}";
}
/**
* An InputStream you can create on a ParcelFileDescriptor, which will
* take care of calling {@link ParcelFileDescriptor#close
* ParcelFileDescritor.close()} for you when the stream is closed.
*/
public static class AutoCloseInputStream
extends ParcelFileDescriptor.AutoCloseInputStream {
private long mRemaining;
public AutoCloseInputStream(AssetFileDescriptor fd) throws IOException {
super(fd.getParcelFileDescriptor());
super.skip(fd.getStartOffset());
mRemaining = (int)fd.getLength();
}
@Override
public int available() throws IOException {
return mRemaining >= 0
? (mRemaining < 0x7fffffff ? (int)mRemaining : 0x7fffffff)
: super.available();
}
@Override
public int read() throws IOException {
if (mRemaining >= 0) {
if (mRemaining == 0) return -1;
int res = super.read();
if (res >= 0) mRemaining--;
return res;
}
return super.read();
}
@Override
public int read(byte[] buffer, int offset, int count) throws IOException {
if (mRemaining >= 0) {
if (mRemaining == 0) return -1;
if (count > mRemaining) count = (int)mRemaining;
int res = super.read(buffer, offset, count);
if (res >= 0) mRemaining -= res;
return res;
}
return super.read(buffer, offset, count);
}
@Override
public int read(byte[] buffer) throws IOException {
if (mRemaining >= 0) {
if (mRemaining == 0) return -1;
int count = buffer.length;
if (count > mRemaining) count = (int)mRemaining;
int res = super.read(buffer, 0, count);
if (res >= 0) mRemaining -= res;
return res;
}
return super.read(buffer);
}
@Override
public long skip(long count) throws IOException {
if (mRemaining >= 0) {
if (mRemaining == 0) return -1;
if (count > mRemaining) count = mRemaining;
long res = super.skip(count);
if (res >= 0) mRemaining -= res;
return res;
}
// TODO Auto-generated method stub
return super.skip(count);
}
@Override
public void mark(int readlimit) {
if (mRemaining >= 0) {
// Not supported.
return;
}
super.mark(readlimit);
}
@Override
public boolean markSupported() {
if (mRemaining >= 0) {
return false;
}
return super.markSupported();
}
@Override
public synchronized void reset() throws IOException {
if (mRemaining >= 0) {
// Not supported.
return;
}
super.reset();
}
}
/**
* An OutputStream you can create on a ParcelFileDescriptor, which will
* take care of calling {@link ParcelFileDescriptor#close
* ParcelFileDescritor.close()} for you when the stream is closed.
*/
public static class AutoCloseOutputStream
extends ParcelFileDescriptor.AutoCloseOutputStream {
private long mRemaining;
public AutoCloseOutputStream(AssetFileDescriptor fd) throws IOException {
super(fd.getParcelFileDescriptor());
if (fd.getParcelFileDescriptor().seekTo(fd.getStartOffset()) < 0) {
throw new IOException("Unable to seek");
}
mRemaining = (int)fd.getLength();
}
@Override
public void write(byte[] buffer, int offset, int count) throws IOException {
if (mRemaining >= 0) {
if (mRemaining == 0) return;
if (count > mRemaining) count = (int)mRemaining;
super.write(buffer, offset, count);
mRemaining -= count;
return;
}
super.write(buffer, offset, count);
}
@Override
public void write(byte[] buffer) throws IOException {
if (mRemaining >= 0) {
if (mRemaining == 0) return;
int count = buffer.length;
if (count > mRemaining) count = (int)mRemaining;
super.write(buffer);
mRemaining -= count;
return;
}
super.write(buffer);
}
@Override
public void write(int oneByte) throws IOException {
if (mRemaining >= 0) {
if (mRemaining == 0) return;
super.write(oneByte);
mRemaining--;
return;
}
super.write(oneByte);
}
}
/* Parcelable interface */
public int describeContents() {
return mFd.describeContents();
}
public void writeToParcel(Parcel out, int flags) {
mFd.writeToParcel(out, flags);
out.writeLong(mStartOffset);
out.writeLong(mLength);
}
AssetFileDescriptor(Parcel src) {
mFd = ParcelFileDescriptor.CREATOR.createFromParcel(src);
mStartOffset = src.readLong();
mLength = src.readLong();
}
public static final Parcelable.Creator<AssetFileDescriptor> CREATOR
= new Parcelable.Creator<AssetFileDescriptor>() {
public AssetFileDescriptor createFromParcel(Parcel in) {
return new AssetFileDescriptor(in);
}
public AssetFileDescriptor[] newArray(int size) {
return new AssetFileDescriptor[size];
}
};
}

View File

@@ -16,6 +16,8 @@
package android.content.res;
import com.google.android.collect.Lists;
import com.android.internal.util.ArrayUtils;
import org.xmlpull.v1.XmlPullParser;
@@ -111,8 +113,7 @@ public class ColorStateList implements Parcelable {
* Create a ColorStateList from an XML document, given a set of {@link Resources}.
*/
public static ColorStateList createFromXml(Resources r, XmlPullParser parser)
throws XmlPullParserException, IOException {
throws XmlPullParserException, IOException {
AttributeSet attrs = Xml.asAttributeSet(parser);
int type;
@@ -124,16 +125,19 @@ public class ColorStateList implements Parcelable {
throw new XmlPullParserException("No start tag found");
}
return createFromXmlInner(r, parser, attrs);
final ColorStateList colorStateList = createFromXmlInner(r, parser, attrs);
return colorStateList;
}
/* Create from inside an XML document. Called on a parser positioned at
* a tag in an XML document, tries to create a ColorStateList from that tag.
* Returns null if the tag is not a valid ColorStateList.
*/
private static ColorStateList createFromXmlInner(Resources r, XmlPullParser parser,
AttributeSet attrs) throws XmlPullParserException, IOException {
private static ColorStateList createFromXmlInner(Resources r,
XmlPullParser parser,
AttributeSet attrs)
throws XmlPullParserException, IOException {
ColorStateList colorStateList;
final String name = parser.getName();
@@ -142,7 +146,8 @@ public class ColorStateList implements Parcelable {
colorStateList = new ColorStateList();
} else {
throw new XmlPullParserException(
parser.getPositionDescription() + ": invalid drawable tag " + name);
parser.getPositionDescription() + ": invalid drawable tag "
+ name);
}
colorStateList.inflate(r, parser, attrs);

View File

@@ -46,7 +46,6 @@ public class Resources {
static final String TAG = "Resources";
private static final boolean DEBUG_LOAD = false;
private static final boolean DEBUG_CONFIG = false;
private static final boolean TRACE_FOR_PRELOAD = false;
private static final int sSdkVersion = SystemProperties.getInt(
"ro.build.version.sdk", 0);
@@ -58,8 +57,6 @@ public class Resources {
// single-threaded, and after that these are immutable.
private static final SparseArray<Drawable.ConstantState> mPreloadedDrawables
= new SparseArray<Drawable.ConstantState>();
private static final SparseArray<ColorStateList> mPreloadedColorStateLists
= new SparseArray<ColorStateList>();
private static boolean mPreloaded;
/*package*/ final TypedValue mTmpValue = new TypedValue();
@@ -81,7 +78,7 @@ public class Resources {
private final Configuration mConfiguration = new Configuration();
/*package*/ final DisplayMetrics mMetrics = new DisplayMetrics();
PluralRules mPluralRule;
/**
* This exception is thrown by the resource APIs when a requested resource
* can not be found.
@@ -93,7 +90,7 @@ public class Resources {
public NotFoundException(String name) {
super(name);
}
}
};
/**
* Create a new Resources object on top of an existing set of assets in an
@@ -1232,9 +1229,7 @@ public class Resources {
width = mMetrics.widthPixels;
height = mMetrics.heightPixels;
} else {
//noinspection SuspiciousNameCombination
width = mMetrics.heightPixels;
//noinspection SuspiciousNameCombination
height = mMetrics.widthPixels;
}
int keyboardHidden = mConfiguration.keyboardHidden;
@@ -1347,7 +1342,6 @@ public class Resources {
try {
return Integer.parseInt(name);
} catch (Exception e) {
// Ignore
}
return mAssets.getResourceIdentifier(name, defType, defPackage);
}
@@ -1581,18 +1575,21 @@ public class Resources {
/*package*/ Drawable loadDrawable(TypedValue value, int id)
throws NotFoundException {
if (TRACE_FOR_PRELOAD) {
// Log only framework resources
if ((id >>> 24) == 0x1) {
final String name = getResourceName(id);
if (name != null) android.util.Log.d("PreloadDrawable", name);
}
if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT
&& value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
// Should we be caching these? If we use constant colors much
// at all, most likely...
//System.out.println("Creating drawable for color: #" +
// Integer.toHexString(value.data));
Drawable dr = new ColorDrawable(value.data);
dr.setChangingConfigurations(value.changingConfigurations);
return dr;
}
final int key = (value.assetCookie << 24) | value.data;
final int key = (value.assetCookie<<24)|value.data;
Drawable dr = getCachedDrawable(key);
//System.out.println("Cached drawable @ #" +
// Integer.toHexString(key.intValue()) + ": " + dr);
if (dr != null) {
return dr;
}
@@ -1600,52 +1597,46 @@ public class Resources {
Drawable.ConstantState cs = mPreloadedDrawables.get(key);
if (cs != null) {
dr = cs.newDrawable();
} else {
if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
dr = new ColorDrawable(value.data);
if (value.string == null) {
throw new NotFoundException(
"Resource is not a Drawable (color or path): " + value);
}
if (dr == null) {
if (value.string == null) {
throw new NotFoundException(
"Resource is not a Drawable (color or path): " + value);
String file = value.string.toString();
if (DEBUG_LOAD) Log.v(TAG, "Loading drawable for cookie "
+ value.assetCookie + ": " + file);
if (file.endsWith(".xml")) {
try {
XmlResourceParser rp = loadXmlResourceParser(
file, id, value.assetCookie, "drawable");
dr = Drawable.createFromXml(this, rp);
rp.close();
} catch (Exception e) {
NotFoundException rnf = new NotFoundException(
"File " + file + " from drawable resource ID #0x"
+ Integer.toHexString(id));
rnf.initCause(e);
throw rnf;
}
String file = value.string.toString();
if (DEBUG_LOAD) Log.v(TAG, "Loading drawable for cookie "
+ value.assetCookie + ": " + file);
if (file.endsWith(".xml")) {
try {
XmlResourceParser rp = loadXmlResourceParser(
file, id, value.assetCookie, "drawable");
dr = Drawable.createFromXml(this, rp);
rp.close();
} catch (Exception e) {
NotFoundException rnf = new NotFoundException(
"File " + file + " from drawable resource ID #0x"
+ Integer.toHexString(id));
rnf.initCause(e);
throw rnf;
}
} else {
try {
InputStream is = mAssets.openNonAsset(
value.assetCookie, file, AssetManager.ACCESS_BUFFER);
// System.out.println("Opened file " + file + ": " + is);
dr = Drawable.createFromResourceStream(this, value, is, file);
is.close();
// System.out.println("Created stream: " + dr);
} catch (Exception e) {
NotFoundException rnf = new NotFoundException(
"File " + file + " from drawable resource ID #0x"
+ Integer.toHexString(id));
rnf.initCause(e);
throw rnf;
}
} else {
try {
InputStream is = mAssets.openNonAsset(
value.assetCookie, file, AssetManager.ACCESS_BUFFER);
// System.out.println("Opened file " + file + ": " + is);
dr = Drawable.createFromResourceStream(this, value, is, file);
is.close();
// System.out.println("Created stream: " + dr);
} catch (Exception e) {
NotFoundException rnf = new NotFoundException(
"File " + file + " from drawable resource ID #0x"
+ Integer.toHexString(id));
rnf.initCause(e);
throw rnf;
}
}
}
@@ -1656,13 +1647,13 @@ public class Resources {
if (cs != null) {
if (mPreloading) {
mPreloadedDrawables.put(key, cs);
} else {
synchronized (mTmpValue) {
//Log.i(TAG, "Saving cached drawable @ #" +
// Integer.toHexString(key.intValue())
// + " in " + this + ": " + cs);
mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
}
}
synchronized (mTmpValue) {
//Log.i(TAG, "Saving cached drawable @ #" +
// Integer.toHexString(key.intValue())
// + " in " + this + ": " + cs);
mDrawableCache.put(
key, new WeakReference<Drawable.ConstantState>(cs));
}
}
}
@@ -1670,7 +1661,7 @@ public class Resources {
return dr;
}
private Drawable getCachedDrawable(int key) {
private final Drawable getCachedDrawable(int key) {
synchronized (mTmpValue) {
WeakReference<Drawable.ConstantState> wr = mDrawableCache.get(key);
if (wr != null) { // we have the key
@@ -1691,40 +1682,13 @@ public class Resources {
/*package*/ ColorStateList loadColorStateList(TypedValue value, int id)
throws NotFoundException {
if (TRACE_FOR_PRELOAD) {
// Log only framework resources
if ((id >>> 24) == 0x1) {
final String name = getResourceName(id);
if (name != null) android.util.Log.d("PreloadColorStateList", name);
}
if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT
&& value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
return ColorStateList.valueOf(value.data);
}
final int key = (value.assetCookie << 24) | value.data;
ColorStateList csl;
if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
csl = mPreloadedColorStateLists.get(key);
if (csl != null) {
return csl;
}
csl = ColorStateList.valueOf(value.data);
if (mPreloading) {
mPreloadedColorStateLists.put(key, csl);
}
return csl;
}
csl = getCachedColorStateList(key);
if (csl != null) {
return csl;
}
csl = mPreloadedColorStateLists.get(key);
final int key = (value.assetCookie<<24)|value.data;
ColorStateList csl = getCachedColorStateList(key);
if (csl != null) {
return csl;
}
@@ -1756,16 +1720,12 @@ public class Resources {
}
if (csl != null) {
if (mPreloading) {
mPreloadedColorStateLists.put(key, csl);
} else {
synchronized (mTmpValue) {
//Log.i(TAG, "Saving cached color state list @ #" +
// Integer.toHexString(key.intValue())
// + " in " + this + ": " + csl);
mColorStateListCache.put(
key, new WeakReference<ColorStateList>(csl));
}
synchronized (mTmpValue) {
//Log.i(TAG, "Saving cached color state list @ #" +
// Integer.toHexString(key.intValue())
// + " in " + this + ": " + csl);
mColorStateListCache.put(
key, new WeakReference<ColorStateList>(csl));
}
}

View File

@@ -141,8 +141,6 @@ final class StringBlock {
int type = style[i];
if (localLOGV) Log.v(TAG, "Applying style span id=" + type
+ ", start=" + style[i+1] + ", end=" + style[i+2]);
if (type == ids.boldId) {
buffer.setSpan(new StyleSpan(Typeface.BOLD),
style[i+1], style[i+2]+1,
@@ -180,8 +178,9 @@ final class StringBlock {
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
} else if (type == ids.listItemId) {
addParagraphSpan(buffer, new BulletSpan(10),
style[i+1], style[i+2]+1);
buffer.setSpan(new BulletSpan(10),
style[i+1], style[i+2]+1,
Spannable.SPAN_PARAGRAPH);
} else if (type == ids.marqueeId) {
buffer.setSpan(TextUtils.TruncateAt.MARQUEE,
style[i+1], style[i+2]+1,
@@ -195,8 +194,9 @@ final class StringBlock {
sub = subtag(tag, ";height=");
if (sub != null) {
int size = Integer.parseInt(sub);
addParagraphSpan(buffer, new Height(size),
style[i+1], style[i+2]+1);
buffer.setSpan(new Height(size),
style[i+1], style[i+2]+1,
Spannable.SPAN_PARAGRAPH);
}
sub = subtag(tag, ";size=");
@@ -231,28 +231,6 @@ final class StringBlock {
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
} else if (tag.startsWith("annotation;")) {
int len = tag.length();
int next;
for (int t = tag.indexOf(';'); t < len; t = next) {
int eq = tag.indexOf('=', t);
if (eq < 0) {
break;
}
next = tag.indexOf(';', eq);
if (next < 0) {
next = len;
}
String key = tag.substring(t + 1, eq);
String value = tag.substring(eq + 1, next);
buffer.setSpan(new Annotation(key, value),
style[i+1], style[i+2]+1,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
@@ -261,34 +239,6 @@ final class StringBlock {
return new SpannedString(buffer);
}
/**
* If a translator has messed up the edges of paragraph-level markup,
* fix it to actually cover the entire paragraph that it is attached to
* instead of just whatever range they put it on.
*/
private static void addParagraphSpan(Spannable buffer, Object what,
int start, int end) {
int len = buffer.length();
if (start != 0 && start != len && buffer.charAt(start - 1) != '\n') {
for (start--; start > 0; start--) {
if (buffer.charAt(start - 1) == '\n') {
break;
}
}
}
if (end != 0 && end != len && buffer.charAt(end - 1) != '\n') {
for (end++; end < len; end++) {
if (buffer.charAt(end - 1) == '\n') {
break;
}
}
}
buffer.setSpan(what, start, end, Spannable.SPAN_PARAGRAPH);
}
private static String subtag(String full, String attribute) {
int start = full.indexOf(attribute);
if (start < 0) {

View File

@@ -438,34 +438,6 @@ public class TypedArray {
throw new RuntimeException(getPositionDescription()
+ ": You must supply a " + name + " attribute.");
}
/**
* Special version of {@link #getDimensionPixelSize} for retrieving
* {@link android.view.ViewGroup}'s layout_width and layout_height
* attributes. This is only here for performance reasons; applications
* should use {@link #getDimensionPixelSize}.
*
* @param index Index of the attribute to retrieve.
* @param defValue The default value to return if this attribute is not
* default or contains the wrong type of data.
*
* @return Attribute dimension value multiplied by the appropriate
* metric and truncated to integer pixels.
*/
public int getLayoutDimension(int index, int defValue) {
index *= AssetManager.STYLE_NUM_ENTRIES;
final int[] data = mData;
final int type = data[index+AssetManager.STYLE_TYPE];
if (type >= TypedValue.TYPE_FIRST_INT
&& type <= TypedValue.TYPE_LAST_INT) {
return data[index+AssetManager.STYLE_DATA];
} else if (type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelSize(
data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
}
return defValue;
}
/**
* Retrieve a fractional unit attribute at <var>index</var>.