summaryrefslogtreecommitdiffstats
path: root/core/java/android/content
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/content')
-rw-r--r--core/java/android/content/AbstractSyncableContentProvider.java601
-rw-r--r--core/java/android/content/AbstractTableMerger.java582
-rw-r--r--core/java/android/content/ActivityNotFoundException.java35
-rw-r--r--core/java/android/content/AsyncQueryHandler.java360
-rw-r--r--core/java/android/content/BroadcastReceiver.java425
-rw-r--r--core/java/android/content/ComponentCallbacks.java54
-rw-r--r--core/java/android/content/ComponentName.aidl19
-rw-r--r--core/java/android/content/ComponentName.java276
-rw-r--r--core/java/android/content/ContentInsertHandler.java50
-rw-r--r--core/java/android/content/ContentProvider.java562
-rw-r--r--core/java/android/content/ContentProviderNative.java435
-rw-r--r--core/java/android/content/ContentQueryMap.java172
-rw-r--r--core/java/android/content/ContentResolver.java644
-rw-r--r--core/java/android/content/ContentService.java376
-rw-r--r--core/java/android/content/ContentServiceNative.java209
-rw-r--r--core/java/android/content/ContentUris.java67
-rw-r--r--core/java/android/content/ContentValues.java501
-rw-r--r--core/java/android/content/Context.java1654
-rw-r--r--core/java/android/content/ContextWrapper.java422
-rw-r--r--core/java/android/content/DefaultDataHandler.java262
-rw-r--r--core/java/android/content/DialogInterface.java144
-rw-r--r--core/java/android/content/IContentProvider.java68
-rw-r--r--core/java/android/content/IContentService.java53
-rw-r--r--core/java/android/content/ISyncAdapter.aidl43
-rw-r--r--core/java/android/content/ISyncContext.aidl38
-rw-r--r--core/java/android/content/Intent.aidl20
-rw-r--r--core/java/android/content/Intent.java4522
-rw-r--r--core/java/android/content/IntentFilter.aidl19
-rw-r--r--core/java/android/content/IntentFilter.java1408
-rw-r--r--core/java/android/content/MutableContextWrapper.java38
-rw-r--r--core/java/android/content/ReceiverCallNotAllowedException.java32
-rw-r--r--core/java/android/content/SearchRecentSuggestionsProvider.java385
-rw-r--r--core/java/android/content/ServiceConnection.java53
-rw-r--r--core/java/android/content/SharedPreferences.java282
-rw-r--r--core/java/android/content/SyncAdapter.java70
-rw-r--r--core/java/android/content/SyncContext.java73
-rw-r--r--core/java/android/content/SyncManager.java2175
-rw-r--r--core/java/android/content/SyncProvider.java53
-rw-r--r--core/java/android/content/SyncResult.aidl19
-rw-r--r--core/java/android/content/SyncResult.java178
-rw-r--r--core/java/android/content/SyncStateContentProviderHelper.java234
-rw-r--r--core/java/android/content/SyncStats.aidl19
-rw-r--r--core/java/android/content/SyncStats.java112
-rw-r--r--core/java/android/content/SyncStorageEngine.java758
-rw-r--r--core/java/android/content/SyncUIContext.java37
-rw-r--r--core/java/android/content/SyncableContentProvider.java228
-rw-r--r--core/java/android/content/TempProviderSyncAdapter.java550
-rw-r--r--core/java/android/content/TempProviderSyncResult.java36
-rw-r--r--core/java/android/content/UriMatcher.java262
-rw-r--r--core/java/android/content/package.html650
-rwxr-xr-xcore/java/android/content/pm/ActivityInfo.aidl20
-rw-r--r--core/java/android/content/pm/ActivityInfo.java353
-rwxr-xr-xcore/java/android/content/pm/ApplicationInfo.aidl20
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java310
-rw-r--r--core/java/android/content/pm/ComponentInfo.java138
-rwxr-xr-xcore/java/android/content/pm/ConfigurationInfo.java119
-rwxr-xr-xcore/java/android/content/pm/IPackageDataObserver.aidl28
-rw-r--r--core/java/android/content/pm/IPackageDeleteObserver.aidl28
-rw-r--r--core/java/android/content/pm/IPackageInstallObserver.aidl27
-rw-r--r--core/java/android/content/pm/IPackageManager.aidl269
-rwxr-xr-xcore/java/android/content/pm/IPackageStatsObserver.aidl30
-rwxr-xr-xcore/java/android/content/pm/InstrumentationInfo.aidl20
-rw-r--r--core/java/android/content/pm/InstrumentationInfo.java98
-rwxr-xr-xcore/java/android/content/pm/PackageInfo.aidl20
-rw-r--r--core/java/android/content/pm/PackageInfo.java199
-rw-r--r--core/java/android/content/pm/PackageItemInfo.java191
-rw-r--r--core/java/android/content/pm/PackageManager.java1626
-rw-r--r--core/java/android/content/pm/PackageParser.java2352
-rwxr-xr-xcore/java/android/content/pm/PackageStats.aidl20
-rwxr-xr-xcore/java/android/content/pm/PackageStats.java63
-rwxr-xr-xcore/java/android/content/pm/PermissionGroupInfo.aidl20
-rw-r--r--core/java/android/content/pm/PermissionGroupInfo.java108
-rwxr-xr-xcore/java/android/content/pm/PermissionInfo.aidl20
-rw-r--r--core/java/android/content/pm/PermissionInfo.java156
-rwxr-xr-xcore/java/android/content/pm/ProviderInfo.aidl20
-rw-r--r--core/java/android/content/pm/ProviderInfo.java129
-rwxr-xr-xcore/java/android/content/pm/ResolveInfo.aidl20
-rw-r--r--core/java/android/content/pm/ResolveInfo.java280
-rwxr-xr-xcore/java/android/content/pm/ServiceInfo.aidl20
-rw-r--r--core/java/android/content/pm/ServiceInfo.java56
-rwxr-xr-xcore/java/android/content/pm/Signature.aidl20
-rw-r--r--core/java/android/content/pm/Signature.java158
-rw-r--r--core/java/android/content/pm/package.html7
-rw-r--r--core/java/android/content/res/AssetFileDescriptor.java81
-rw-r--r--core/java/android/content/res/AssetManager.java697
-rw-r--r--core/java/android/content/res/ColorStateList.java332
-rwxr-xr-xcore/java/android/content/res/Configuration.aidl21
-rw-r--r--core/java/android/content/res/Configuration.java436
-rw-r--r--core/java/android/content/res/PluralRules.java111
-rw-r--r--core/java/android/content/res/Resources.java1850
-rw-r--r--core/java/android/content/res/StringBlock.java345
-rw-r--r--core/java/android/content/res/TypedArray.java660
-rw-r--r--core/java/android/content/res/XmlBlock.java515
-rw-r--r--core/java/android/content/res/XmlResourceParser.java36
-rw-r--r--core/java/android/content/res/package.html8
95 files changed, 0 insertions, 32302 deletions
diff --git a/core/java/android/content/AbstractSyncableContentProvider.java b/core/java/android/content/AbstractSyncableContentProvider.java
deleted file mode 100644
index ce6501c..0000000
--- a/core/java/android/content/AbstractSyncableContentProvider.java
+++ /dev/null
@@ -1,601 +0,0 @@
-package android.content;
-
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.Cursor;
-import android.net.Uri;
-import android.accounts.AccountMonitor;
-import android.accounts.AccountMonitorListener;
-import android.provider.SyncConstValue;
-import android.util.Config;
-import android.util.Log;
-import android.os.Bundle;
-import android.text.TextUtils;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Vector;
-import java.util.ArrayList;
-
-/**
- * A specialization of the ContentProvider that centralizes functionality
- * used by ContentProviders that are syncable. It also wraps calls to the ContentProvider
- * inside of database transactions.
- *
- * @hide
- */
-public abstract class AbstractSyncableContentProvider extends SyncableContentProvider {
- private static final String TAG = "SyncableContentProvider";
- protected SQLiteOpenHelper mOpenHelper;
- protected SQLiteDatabase mDb;
- private final String mDatabaseName;
- private final int mDatabaseVersion;
- private final Uri mContentUri;
- private AccountMonitor mAccountMonitor;
-
- /** the account set in the last call to onSyncStart() */
- private String mSyncingAccount;
-
- private SyncStateContentProviderHelper mSyncState = null;
-
- private static final String[] sAccountProjection = new String[] {SyncConstValue._SYNC_ACCOUNT};
-
- private boolean mIsTemporary;
-
- private AbstractTableMerger mCurrentMerger = null;
- private boolean mIsMergeCancelled = false;
-
- private static final String SYNC_ACCOUNT_WHERE_CLAUSE = SyncConstValue._SYNC_ACCOUNT + "=?";
-
- protected boolean isTemporary() {
- return mIsTemporary;
- }
-
- /**
- * Indicates whether or not this ContentProvider contains a full
- * set of data or just diffs. This knowledge comes in handy when
- * determining how to incorporate the contents of a temporary
- * provider into a real provider.
- */
- private boolean mContainsDiffs;
-
- /**
- * Initializes the AbstractSyncableContentProvider
- * @param dbName the filename of the database
- * @param dbVersion the current version of the database schema
- * @param contentUri The base Uri of the syncable content in this provider
- */
- public AbstractSyncableContentProvider(String dbName, int dbVersion, Uri contentUri) {
- super();
-
- mDatabaseName = dbName;
- mDatabaseVersion = dbVersion;
- mContentUri = contentUri;
- mIsTemporary = false;
- setContainsDiffs(false);
- if (Config.LOGV) {
- Log.v(TAG, "created SyncableContentProvider " + this);
- }
- }
-
- /**
- * Close resources that must be closed. You must call this to properly release
- * the resources used by the AbstractSyncableContentProvider.
- */
- public void close() {
- if (mOpenHelper != null) {
- mOpenHelper.close(); // OK to call .close() repeatedly.
- }
- }
-
- /**
- * Override to create your schema and do anything else you need to do with a new database.
- * This is run inside a transaction (so you don't need to use one).
- * This method may not use getDatabase(), or call content provider methods, it must only
- * use the database handle passed to it.
- */
- protected void bootstrapDatabase(SQLiteDatabase db) {}
-
- /**
- * Override to upgrade your database from an old version to the version you specified.
- * Don't set the DB version; this will automatically be done after the method returns.
- * This method may not use getDatabase(), or call content provider methods, it must only
- * use the database handle passed to it.
- *
- * @param oldVersion version of the existing database
- * @param newVersion current version to upgrade to
- * @return true if the upgrade was lossless, false if it was lossy
- */
- protected abstract boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion);
-
- /**
- * Override to do anything (like cleanups or checks) you need to do after opening a database.
- * Does nothing by default. This is run inside a transaction (so you don't need to use one).
- * This method may not use getDatabase(), or call content provider methods, it must only
- * use the database handle passed to it.
- */
- protected void onDatabaseOpened(SQLiteDatabase db) {}
-
- private class DatabaseHelper extends SQLiteOpenHelper {
- DatabaseHelper(Context context, String name) {
- // Note: context and name may be null for temp providers
- super(context, name, null, mDatabaseVersion);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- bootstrapDatabase(db);
- mSyncState.createDatabase(db);
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- if (!upgradeDatabase(db, oldVersion, newVersion)) {
- mSyncState.discardSyncData(db, null /* all accounts */);
- getContext().getContentResolver().startSync(mContentUri, new Bundle());
- }
- }
-
- @Override
- public void onOpen(SQLiteDatabase db) {
- onDatabaseOpened(db);
- mSyncState.onDatabaseOpened(db);
- }
- }
-
- @Override
- public boolean onCreate() {
- if (isTemporary()) throw new IllegalStateException("onCreate() called for temp provider");
- mOpenHelper = new AbstractSyncableContentProvider.DatabaseHelper(getContext(), mDatabaseName);
- mSyncState = new SyncStateContentProviderHelper(mOpenHelper);
-
- AccountMonitorListener listener = new AccountMonitorListener() {
- public void onAccountsUpdated(String[] accounts) {
- // Some providers override onAccountsChanged(); give them a database to work with.
- mDb = mOpenHelper.getWritableDatabase();
- onAccountsChanged(accounts);
- TempProviderSyncAdapter syncAdapter = (TempProviderSyncAdapter)getSyncAdapter();
- if (syncAdapter != null) {
- syncAdapter.onAccountsChanged(accounts);
- }
- }
- };
- mAccountMonitor = new AccountMonitor(getContext(), listener);
-
- return true;
- }
-
- /**
- * Get a non-persistent instance of this content provider.
- * You must call {@link #close} on the returned
- * SyncableContentProvider when you are done with it.
- *
- * @return a non-persistent content provider with the same layout as this
- * provider.
- */
- public AbstractSyncableContentProvider getTemporaryInstance() {
- AbstractSyncableContentProvider temp;
- try {
- temp = getClass().newInstance();
- } catch (InstantiationException e) {
- throw new RuntimeException("unable to instantiate class, "
- + "this should never happen", e);
- } catch (IllegalAccessException e) {
- throw new RuntimeException(
- "IllegalAccess while instantiating class, "
- + "this should never happen", e);
- }
-
- // Note: onCreate() isn't run for the temp provider, and it has no Context.
- temp.mIsTemporary = true;
- temp.setContainsDiffs(true);
- temp.mOpenHelper = temp.new DatabaseHelper(null, null);
- temp.mSyncState = new SyncStateContentProviderHelper(temp.mOpenHelper);
- if (!isTemporary()) {
- mSyncState.copySyncState(
- mOpenHelper.getReadableDatabase(),
- temp.mOpenHelper.getWritableDatabase(),
- getSyncingAccount());
- }
- return temp;
- }
-
- public SQLiteDatabase getDatabase() {
- if (mDb == null) mDb = mOpenHelper.getWritableDatabase();
- return mDb;
- }
-
- public boolean getContainsDiffs() {
- return mContainsDiffs;
- }
-
- public void setContainsDiffs(boolean containsDiffs) {
- if (containsDiffs && !isTemporary()) {
- throw new IllegalStateException(
- "only a temporary provider can contain diffs");
- }
- mContainsDiffs = containsDiffs;
- }
-
- /**
- * Each subclass of this class should define a subclass of {@link
- * android.content.AbstractTableMerger} for each table they wish to merge. It
- * should then override this method and return one instance of
- * each merger, in sequence. Their {@link
- * android.content.AbstractTableMerger#merge merge} methods will be called, one at a
- * time, in the order supplied.
- *
- * <p>The default implementation returns an empty list, so that no
- * merging will occur.
- * @return A sequence of subclasses of {@link
- * android.content.AbstractTableMerger}, one for each table that should be merged.
- */
- protected Iterable<? extends AbstractTableMerger> getMergers() {
- return Collections.emptyList();
- }
-
- @Override
- public final int update(final Uri url, final ContentValues values,
- final String selection, final String[] selectionArgs) {
- mDb = mOpenHelper.getWritableDatabase();
- mDb.beginTransaction();
- try {
- if (isTemporary() && mSyncState.matches(url)) {
- int numRows = mSyncState.asContentProvider().update(
- url, values, selection, selectionArgs);
- mDb.setTransactionSuccessful();
- return numRows;
- }
-
- int result = updateInternal(url, values, selection, selectionArgs);
- mDb.setTransactionSuccessful();
-
- if (!isTemporary() && result > 0) {
- getContext().getContentResolver().notifyChange(url, null /* observer */,
- changeRequiresLocalSync(url));
- }
-
- return result;
- } finally {
- mDb.endTransaction();
- }
- }
-
- @Override
- public final int delete(final Uri url, final String selection,
- final String[] selectionArgs) {
- mDb = mOpenHelper.getWritableDatabase();
- mDb.beginTransaction();
- try {
- if (isTemporary() && mSyncState.matches(url)) {
- int numRows = mSyncState.asContentProvider().delete(url, selection, selectionArgs);
- mDb.setTransactionSuccessful();
- return numRows;
- }
- int result = deleteInternal(url, selection, selectionArgs);
- mDb.setTransactionSuccessful();
- if (!isTemporary() && result > 0) {
- getContext().getContentResolver().notifyChange(url, null /* observer */,
- changeRequiresLocalSync(url));
- }
- return result;
- } finally {
- mDb.endTransaction();
- }
- }
-
- @Override
- public final Uri insert(final Uri url, final ContentValues values) {
- mDb = mOpenHelper.getWritableDatabase();
- mDb.beginTransaction();
- try {
- if (isTemporary() && mSyncState.matches(url)) {
- Uri result = mSyncState.asContentProvider().insert(url, values);
- mDb.setTransactionSuccessful();
- return result;
- }
- Uri result = insertInternal(url, values);
- mDb.setTransactionSuccessful();
- if (!isTemporary() && result != null) {
- getContext().getContentResolver().notifyChange(url, null /* observer */,
- changeRequiresLocalSync(url));
- }
- return result;
- } finally {
- mDb.endTransaction();
- }
- }
-
- @Override
- public final int bulkInsert(final Uri uri, final ContentValues[] values) {
- int size = values.length;
- int completed = 0;
- final boolean isSyncStateUri = mSyncState.matches(uri);
- mDb = mOpenHelper.getWritableDatabase();
- mDb.beginTransaction();
- try {
- for (int i = 0; i < size; i++) {
- Uri result;
- if (isTemporary() && isSyncStateUri) {
- result = mSyncState.asContentProvider().insert(uri, values[i]);
- } else {
- result = insertInternal(uri, values[i]);
- mDb.yieldIfContended();
- }
- if (result != null) {
- completed++;
- }
- }
- mDb.setTransactionSuccessful();
- } finally {
- mDb.endTransaction();
- }
- if (!isTemporary() && completed == size) {
- getContext().getContentResolver().notifyChange(uri, null /* observer */,
- changeRequiresLocalSync(uri));
- }
- return completed;
- }
-
- /**
- * Check if changes to this URI can be syncable changes.
- * @param uri the URI of the resource that was changed
- * @return true if changes to this URI can be syncable changes, false otherwise
- */
- public boolean changeRequiresLocalSync(Uri uri) {
- return true;
- }
-
- @Override
- public final Cursor query(final Uri url, final String[] projection,
- final String selection, final String[] selectionArgs,
- final String sortOrder) {
- mDb = mOpenHelper.getReadableDatabase();
- if (isTemporary() && mSyncState.matches(url)) {
- return mSyncState.asContentProvider().query(
- url, projection, selection, selectionArgs, sortOrder);
- }
- return queryInternal(url, projection, selection, selectionArgs, sortOrder);
- }
-
- /**
- * Called right before a sync is started.
- *
- * @param context the sync context for the operation
- * @param account
- */
- public void onSyncStart(SyncContext context, String account) {
- if (TextUtils.isEmpty(account)) {
- throw new IllegalArgumentException("you passed in an empty account");
- }
- mSyncingAccount = account;
- }
-
- /**
- * Called right after a sync is completed
- *
- * @param context the sync context for the operation
- * @param success true if the sync succeeded, false if an error occurred
- */
- public void onSyncStop(SyncContext context, boolean success) {
- }
-
- /**
- * The account of the most recent call to onSyncStart()
- * @return the account
- */
- public String getSyncingAccount() {
- return mSyncingAccount;
- }
-
- /**
- * Merge diffs from a sync source with this content provider.
- *
- * @param context the SyncContext within which this merge is taking place
- * @param diffs A temporary content provider containing diffs from a sync
- * source.
- * @param result a MergeResult that contains information about the merge, including
- * a temporary content provider with the same layout as this provider containing
- * @param syncResult
- */
- public void merge(SyncContext context, SyncableContentProvider diffs,
- TempProviderSyncResult result, SyncResult syncResult) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- synchronized(this) {
- mIsMergeCancelled = false;
- }
- Iterable<? extends AbstractTableMerger> mergers = getMergers();
- try {
- for (AbstractTableMerger merger : mergers) {
- synchronized(this) {
- if (mIsMergeCancelled) break;
- mCurrentMerger = merger;
- }
- merger.merge(context, getSyncingAccount(), diffs, result, syncResult, this);
- }
- if (mIsMergeCancelled) return;
- if (diffs != null) {
- mSyncState.copySyncState(
- ((AbstractSyncableContentProvider)diffs).mOpenHelper.getReadableDatabase(),
- mOpenHelper.getWritableDatabase(),
- getSyncingAccount());
- }
- } finally {
- synchronized (this) {
- mCurrentMerger = null;
- }
- }
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
- }
-
-
- /**
- * Invoked when the active sync has been canceled. Sets the sync state of this provider and
- * its merger to canceled.
- */
- public void onSyncCanceled() {
- synchronized (this) {
- mIsMergeCancelled = true;
- if (mCurrentMerger != null) {
- mCurrentMerger.onMergeCancelled();
- }
- }
- }
-
-
- public boolean isMergeCancelled() {
- return mIsMergeCancelled;
- }
-
- /**
- * Subclasses should override this instead of update(). See update()
- * for details.
- *
- * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
- * which means a database transaction will be active during the call;
- */
- protected abstract int updateInternal(Uri url, ContentValues values,
- String selection, String[] selectionArgs);
-
- /**
- * Subclasses should override this instead of delete(). See delete()
- * for details.
- *
- * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
- * which means a database transaction will be active during the call;
- */
- protected abstract int deleteInternal(Uri url, String selection, String[] selectionArgs);
-
- /**
- * Subclasses should override this instead of insert(). See insert()
- * for details.
- *
- * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
- * which means a database transaction will be active during the call;
- */
- protected abstract Uri insertInternal(Uri url, ContentValues values);
-
- /**
- * Subclasses should override this instead of query(). See query()
- * for details.
- *
- * <p> This method is *not* called within a acquireDbLock()/releaseDbLock()
- * block for performance reasons. If an implementation needs atomic access
- * to the database the lock can be acquired then.
- */
- protected abstract Cursor queryInternal(Uri url, String[] projection,
- String selection, String[] selectionArgs, String sortOrder);
-
- /**
- * Make sure that there are no entries for accounts that no longer exist
- * @param accountsArray the array of currently-existing accounts
- */
- protected void onAccountsChanged(String[] accountsArray) {
- Map<String, Boolean> accounts = new HashMap<String, Boolean>();
- for (String account : accountsArray) {
- accounts.put(account, false);
- }
- accounts.put(SyncConstValue.NON_SYNCABLE_ACCOUNT, false);
-
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- Map<String, String> tableMap = db.getSyncedTables();
- Vector<String> tables = new Vector<String>();
- tables.addAll(tableMap.keySet());
- tables.addAll(tableMap.values());
-
- db.beginTransaction();
- try {
- mSyncState.onAccountsChanged(accountsArray);
- for (String table : tables) {
- deleteRowsForRemovedAccounts(accounts, table,
- SyncConstValue._SYNC_ACCOUNT);
- }
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
- }
-
- /**
- * A helper method to delete all rows whose account is not in the accounts
- * map. The accountColumnName is the name of the column that is expected
- * to hold the account. If a row has an empty account it is never deleted.
- *
- * @param accounts a map of existing accounts
- * @param table the table to delete from
- * @param accountColumnName the name of the column that is expected
- * to hold the account.
- */
- protected void deleteRowsForRemovedAccounts(Map<String, Boolean> accounts,
- String table, String accountColumnName) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- Cursor c = db.query(table, sAccountProjection, null, null,
- accountColumnName, null, null);
- try {
- while (c.moveToNext()) {
- String account = c.getString(0);
- if (TextUtils.isEmpty(account)) {
- continue;
- }
- if (!accounts.containsKey(account)) {
- int numDeleted;
- numDeleted = db.delete(table, accountColumnName + "=?", new String[]{account});
- if (Config.LOGV) {
- Log.v(TAG, "deleted " + numDeleted
- + " records from table " + table
- + " for account " + account);
- }
- }
- }
- } finally {
- c.close();
- }
- }
-
- /**
- * Called when the sync system determines that this provider should no longer
- * contain records for the specified account.
- */
- public void wipeAccount(String account) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- Map<String, String> tableMap = db.getSyncedTables();
- ArrayList<String> tables = new ArrayList<String>();
- tables.addAll(tableMap.keySet());
- tables.addAll(tableMap.values());
-
- db.beginTransaction();
-
- try {
- // remove the SyncState data
- mSyncState.discardSyncData(db, account);
-
- // remove the data in the synced tables
- for (String table : tables) {
- db.delete(table, SYNC_ACCOUNT_WHERE_CLAUSE, new String[]{account});
- }
- db.setTransactionSuccessful();
- } finally {
- db.endTransaction();
- }
- }
-
- /**
- * Retrieves the SyncData bytes for the given account. The byte array returned may be null.
- */
- public byte[] readSyncDataBytes(String account) {
- return mSyncState.readSyncDataBytes(mOpenHelper.getReadableDatabase(), account);
- }
-
- /**
- * Sets the SyncData bytes for the given account. The byte array may be null.
- */
- public void writeSyncDataBytes(String account, byte[] data) {
- mSyncState.writeSyncDataBytes(mOpenHelper.getWritableDatabase(), account, data);
- }
-}
diff --git a/core/java/android/content/AbstractTableMerger.java b/core/java/android/content/AbstractTableMerger.java
deleted file mode 100644
index 700f1d8..0000000
--- a/core/java/android/content/AbstractTableMerger.java
+++ /dev/null
@@ -1,582 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.os.Debug;
-import android.provider.BaseColumns;
-import static android.provider.SyncConstValue.*;
-import android.text.TextUtils;
-import android.util.Log;
-
-/**
- * @hide
- */
-public abstract class AbstractTableMerger
-{
- private ContentValues mValues;
-
- protected SQLiteDatabase mDb;
- protected String mTable;
- protected Uri mTableURL;
- protected String mDeletedTable;
- protected Uri mDeletedTableURL;
- static protected ContentValues mSyncMarkValues;
- static private boolean TRACE;
-
- static {
- mSyncMarkValues = new ContentValues();
- mSyncMarkValues.put(_SYNC_MARK, 1);
- TRACE = false;
- }
-
- private static final String TAG = "AbstractTableMerger";
- private static final String[] syncDirtyProjection =
- new String[] {_SYNC_DIRTY, BaseColumns._ID, _SYNC_ID, _SYNC_VERSION};
- private static final String[] syncIdAndVersionProjection =
- new String[] {_SYNC_ID, _SYNC_VERSION};
-
- private volatile boolean mIsMergeCancelled;
-
- private static final String SELECT_MARKED = _SYNC_MARK + "> 0 and " + _SYNC_ACCOUNT + "=?";
-
- private static final String SELECT_BY_SYNC_ID_AND_ACCOUNT =
- _SYNC_ID +"=? and " + _SYNC_ACCOUNT + "=?";
- private static final String SELECT_BY_ID = BaseColumns._ID +"=?";
-
- private static final String SELECT_UNSYNCED = ""
- + _SYNC_DIRTY + " > 0 and (" + _SYNC_ACCOUNT + "=? or " + _SYNC_ACCOUNT + " is null)";
-
- public AbstractTableMerger(SQLiteDatabase database,
- String table, Uri tableURL, String deletedTable,
- Uri deletedTableURL)
- {
- mDb = database;
- mTable = table;
- mTableURL = tableURL;
- mDeletedTable = deletedTable;
- mDeletedTableURL = deletedTableURL;
- mValues = new ContentValues();
- }
-
- public abstract void insertRow(ContentProvider diffs,
- Cursor diffsCursor);
- public abstract void updateRow(long localPersonID,
- ContentProvider diffs, Cursor diffsCursor);
- public abstract void resolveRow(long localPersonID,
- String syncID, ContentProvider diffs, Cursor diffsCursor);
-
- /**
- * This is called when it is determined that a row should be deleted from the
- * ContentProvider. The localCursor is on a table from the local ContentProvider
- * and its current position is of the row that should be deleted. The localCursor
- * is only guaranteed to contain the BaseColumns.ID column so the implementation
- * of deleteRow() must query the database directly if other columns are needed.
- * <p>
- * It is the responsibility of the implementation of this method to ensure that the cursor
- * points to the next row when this method returns, either by calling Cursor.deleteRow() or
- * Cursor.next().
- *
- * @param localCursor The Cursor into the local table, which points to the row that
- * is to be deleted.
- */
- public void deleteRow(Cursor localCursor) {
- localCursor.deleteRow();
- }
-
- /**
- * After {@link #merge} has completed, this method is called to send
- * notifications to {@link android.database.ContentObserver}s of changes
- * to the containing {@link ContentProvider}. These notifications likely
- * do not want to request a sync back to the network.
- */
- protected abstract void notifyChanges();
-
- private static boolean findInCursor(Cursor cursor, int column, String id) {
- while (!cursor.isAfterLast() && !cursor.isNull(column)) {
- int comp = id.compareTo(cursor.getString(column));
- if (comp > 0) {
- cursor.moveToNext();
- continue;
- }
- return comp == 0;
- }
- return false;
- }
-
- public void onMergeCancelled() {
- mIsMergeCancelled = true;
- }
-
- /**
- * Carry out a merge of the given diffs, and add the results to
- * the given MergeResult. If we are the first merge to find
- * client-side diffs, we'll use the given ContentProvider to
- * construct a temporary instance to hold them.
- */
- public void merge(final SyncContext context,
- final String account,
- final SyncableContentProvider serverDiffs,
- TempProviderSyncResult result,
- SyncResult syncResult, SyncableContentProvider temporaryInstanceFactory) {
- mIsMergeCancelled = false;
- if (serverDiffs != null) {
- if (!mDb.isDbLockedByCurrentThread()) {
- throw new IllegalStateException("this must be called from within a DB transaction");
- }
- mergeServerDiffs(context, account, serverDiffs, syncResult);
- notifyChanges();
- }
-
- if (result != null) {
- findLocalChanges(result, temporaryInstanceFactory, account, syncResult);
- }
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "merge complete");
- }
-
- /**
- * @hide this is public for testing purposes only
- */
- public void mergeServerDiffs(SyncContext context,
- String account, SyncableContentProvider serverDiffs, SyncResult syncResult) {
- boolean diffsArePartial = serverDiffs.getContainsDiffs();
- // mark the current rows so that we can distinguish these from new
- // inserts that occur during the merge
- mDb.update(mTable, mSyncMarkValues, null, null);
- if (mDeletedTable != null) {
- mDb.update(mDeletedTable, mSyncMarkValues, null, null);
- }
-
- // load the local database entries, so we can merge them with the server
- final String[] accountSelectionArgs = new String[]{account};
- Cursor localCursor = mDb.query(mTable, syncDirtyProjection,
- SELECT_MARKED, accountSelectionArgs, null, null,
- mTable + "." + _SYNC_ID);
- Cursor deletedCursor;
- if (mDeletedTable != null) {
- deletedCursor = mDb.query(mDeletedTable, syncIdAndVersionProjection,
- SELECT_MARKED, accountSelectionArgs, null, null,
- mDeletedTable + "." + _SYNC_ID);
- } else {
- deletedCursor =
- mDb.rawQuery("select 'a' as _sync_id, 'b' as _sync_version limit 0", null);
- }
-
- // Apply updates and insertions from the server
- Cursor diffsCursor = serverDiffs.query(mTableURL,
- null, null, null, mTable + "." + _SYNC_ID);
- int deletedSyncIDColumn = deletedCursor.getColumnIndexOrThrow(_SYNC_ID);
- int deletedSyncVersionColumn = deletedCursor.getColumnIndexOrThrow(_SYNC_VERSION);
- int serverSyncIDColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_ID);
- int serverSyncVersionColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_VERSION);
- int serverSyncLocalIdColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_LOCAL_ID);
-
- String lastSyncId = null;
- int diffsCount = 0;
- int localCount = 0;
- localCursor.moveToFirst();
- deletedCursor.moveToFirst();
- while (diffsCursor.moveToNext()) {
- if (mIsMergeCancelled) {
- localCursor.close();
- deletedCursor.close();
- diffsCursor.close();
- return;
- }
- mDb.yieldIfContended();
- String serverSyncId = diffsCursor.getString(serverSyncIDColumn);
- String serverSyncVersion = diffsCursor.getString(serverSyncVersionColumn);
- long localRowId = 0;
- String localSyncVersion = null;
-
- diffsCount++;
- context.setStatusText("Processing " + diffsCount + "/"
- + diffsCursor.getCount());
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "processing server entry " +
- diffsCount + ", " + serverSyncId);
-
- if (TRACE) {
- if (diffsCount == 10) {
- Debug.startMethodTracing("atmtrace");
- }
- if (diffsCount == 20) {
- Debug.stopMethodTracing();
- }
- }
-
- boolean conflict = false;
- boolean update = false;
- boolean insert = false;
-
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "found event with serverSyncID " + serverSyncId);
- }
- if (TextUtils.isEmpty(serverSyncId)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.e(TAG, "server entry doesn't have a serverSyncID");
- }
- continue;
- }
-
- // It is possible that the sync adapter wrote the same record multiple times,
- // e.g. if the same record came via multiple feeds. If this happens just ignore
- // the duplicate records.
- if (serverSyncId.equals(lastSyncId)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "skipping record with duplicate remote server id " + lastSyncId);
- }
- continue;
- }
- lastSyncId = serverSyncId;
-
- String localSyncID = null;
- boolean localSyncDirty = false;
-
- while (!localCursor.isAfterLast()) {
- if (mIsMergeCancelled) {
- localCursor.deactivate();
- deletedCursor.deactivate();
- diffsCursor.deactivate();
- return;
- }
- localCount++;
- localSyncID = localCursor.getString(2);
-
- // If the local record doesn't have a _sync_id then
- // it is new. Ignore it for now, we will send an insert
- // the the server later.
- if (TextUtils.isEmpty(localSyncID)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "local record " +
- localCursor.getLong(1) +
- " has no _sync_id, ignoring");
- }
- localCursor.moveToNext();
- localSyncID = null;
- continue;
- }
-
- int comp = serverSyncId.compareTo(localSyncID);
-
- // the local DB has a record that the server doesn't have
- if (comp > 0) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "local record " +
- localCursor.getLong(1) +
- " has _sync_id " + localSyncID +
- " that is < server _sync_id " + serverSyncId);
- }
- if (diffsArePartial) {
- localCursor.moveToNext();
- } else {
- deleteRow(localCursor);
- if (mDeletedTable != null) {
- mDb.delete(mDeletedTable, _SYNC_ID +"=?", new String[] {localSyncID});
- }
- syncResult.stats.numDeletes++;
- mDb.yieldIfContended();
- }
- localSyncID = null;
- continue;
- }
-
- // the server has a record that the local DB doesn't have
- if (comp < 0) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "local record " +
- localCursor.getLong(1) +
- " has _sync_id " + localSyncID +
- " that is > server _sync_id " + serverSyncId);
- }
- localSyncID = null;
- }
-
- // the server and the local DB both have this record
- if (comp == 0) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "local record " +
- localCursor.getLong(1) +
- " has _sync_id " + localSyncID +
- " that matches the server _sync_id");
- }
- localSyncDirty = localCursor.getInt(0) != 0;
- localRowId = localCursor.getLong(1);
- localSyncVersion = localCursor.getString(3);
- localCursor.moveToNext();
- }
-
- break;
- }
-
- // If this record is in the deleted table then update the server version
- // in the deleted table, if necessary, and then ignore it here.
- // We will send a deletion indication to the server down a
- // little further.
- if (findInCursor(deletedCursor, deletedSyncIDColumn, serverSyncId)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "remote record " + serverSyncId + " is in the deleted table");
- }
- final String deletedSyncVersion = deletedCursor.getString(deletedSyncVersionColumn);
- if (!TextUtils.equals(deletedSyncVersion, serverSyncVersion)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "setting version of deleted record " + serverSyncId + " to "
- + serverSyncVersion);
- }
- ContentValues values = new ContentValues();
- values.put(_SYNC_VERSION, serverSyncVersion);
- mDb.update(mDeletedTable, values, "_sync_id=?", new String[]{serverSyncId});
- }
- continue;
- }
-
- // If the _sync_local_id is present in the diffsCursor
- // then this record corresponds to a local record that was just
- // inserted into the server and the _sync_local_id is the row id
- // of the local record. Set these fields so that the next check
- // treats this record as an update, which will allow the
- // merger to update the record with the server's sync id
- if (!diffsCursor.isNull(serverSyncLocalIdColumn)) {
- localRowId = diffsCursor.getLong(serverSyncLocalIdColumn);
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "the remote record with sync id " + serverSyncId
- + " has a local sync id, " + localRowId);
- }
- localSyncID = serverSyncId;
- localSyncDirty = false;
- localSyncVersion = null;
- }
-
- if (!TextUtils.isEmpty(localSyncID)) {
- // An existing server item has changed
- boolean recordChanged = (localSyncVersion == null) ||
- !serverSyncVersion.equals(localSyncVersion);
- if (recordChanged) {
- if (localSyncDirty) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "remote record " + serverSyncId
- + " conflicts with local _sync_id " + localSyncID
- + ", local _id " + localRowId);
- }
- conflict = true;
- } else {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG,
- "remote record " +
- serverSyncId +
- " updates local _sync_id " +
- localSyncID + ", local _id " +
- localRowId);
- }
- update = true;
- }
- }
- } else {
- // the local db doesn't know about this record so add it
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "remote record " + serverSyncId + " is new, inserting");
- }
- insert = true;
- }
-
- if (update) {
- updateRow(localRowId, serverDiffs, diffsCursor);
- syncResult.stats.numUpdates++;
- } else if (conflict) {
- resolveRow(localRowId, serverSyncId, serverDiffs, diffsCursor);
- syncResult.stats.numUpdates++;
- } else if (insert) {
- insertRow(serverDiffs, diffsCursor);
- syncResult.stats.numInserts++;
- }
- }
-
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "processed " + diffsCount + " server entries");
- }
-
- // If tombstones aren't in use delete any remaining local rows that
- // don't have corresponding server rows. Keep the rows that don't
- // have a sync id since those were created locally and haven't been
- // synced to the server yet.
- if (!diffsArePartial) {
- while (!localCursor.isAfterLast() && !TextUtils.isEmpty(localCursor.getString(2))) {
- if (mIsMergeCancelled) {
- localCursor.deactivate();
- deletedCursor.deactivate();
- diffsCursor.deactivate();
- return;
- }
- localCount++;
- final String localSyncId = localCursor.getString(2);
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG,
- "deleting local record " +
- localCursor.getLong(1) +
- " _sync_id " + localSyncId);
- }
- deleteRow(localCursor);
- if (mDeletedTable != null) {
- mDb.delete(mDeletedTable, _SYNC_ID + "=?", new String[] {localSyncId});
- }
- syncResult.stats.numDeletes++;
- mDb.yieldIfContended();
- }
- }
-
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "checked " + localCount +
- " local entries");
- diffsCursor.deactivate();
- localCursor.deactivate();
- deletedCursor.deactivate();
-
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "applying deletions from the server");
-
- // Apply deletions from the server
- if (mDeletedTableURL != null) {
- diffsCursor = serverDiffs.query(mDeletedTableURL, null, null, null, null);
-
- while (diffsCursor.moveToNext()) {
- if (mIsMergeCancelled) {
- diffsCursor.deactivate();
- return;
- }
- // delete all rows that match each element in the diffsCursor
- fullyDeleteMatchingRows(diffsCursor, account, syncResult);
- mDb.yieldIfContended();
- }
- diffsCursor.deactivate();
- }
- }
-
- private void fullyDeleteMatchingRows(Cursor diffsCursor, String account,
- SyncResult syncResult) {
- int serverSyncIdColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_ID);
- final boolean deleteBySyncId = !diffsCursor.isNull(serverSyncIdColumn);
-
- // delete the rows explicitly so that the delete operation can be overridden
- final Cursor c;
- final String[] selectionArgs;
- if (deleteBySyncId) {
- selectionArgs = new String[]{diffsCursor.getString(serverSyncIdColumn), account};
- c = mDb.query(mTable, new String[]{BaseColumns._ID}, SELECT_BY_SYNC_ID_AND_ACCOUNT,
- selectionArgs, null, null, null);
- } else {
- int serverSyncLocalIdColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_LOCAL_ID);
- selectionArgs = new String[]{diffsCursor.getString(serverSyncLocalIdColumn)};
- c = mDb.query(mTable, new String[]{BaseColumns._ID}, SELECT_BY_ID, selectionArgs,
- null, null, null);
- }
- try {
- c.moveToFirst();
- while (!c.isAfterLast()) {
- deleteRow(c); // advances the cursor
- syncResult.stats.numDeletes++;
- }
- } finally {
- c.deactivate();
- }
- if (deleteBySyncId && mDeletedTable != null) {
- mDb.delete(mDeletedTable, SELECT_BY_SYNC_ID_AND_ACCOUNT, selectionArgs);
- }
- }
-
- /**
- * Converts cursor into a Map, using the correct types for the values.
- */
- protected void cursorRowToContentValues(Cursor cursor, ContentValues map) {
- DatabaseUtils.cursorRowToContentValues(cursor, map);
- }
-
- /**
- * Finds local changes, placing the results in the given result object.
- * @param temporaryInstanceFactory As an optimization for the case
- * where there are no client-side diffs, mergeResult may initially
- * have no {@link android.content.TempProviderSyncResult#tempContentProvider}. If this is
- * the first in the sequence of AbstractTableMergers to find
- * client-side diffs, it will use the given ContentProvider to
- * create a temporary instance and store its {@link
- * ContentProvider} in the mergeResult.
- * @param account
- * @param syncResult
- */
- private void findLocalChanges(TempProviderSyncResult mergeResult,
- SyncableContentProvider temporaryInstanceFactory, String account,
- SyncResult syncResult) {
- SyncableContentProvider clientDiffs = mergeResult.tempContentProvider;
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "generating client updates");
-
- final String[] accountSelectionArgs = new String[]{account};
-
- // Generate the client updates and insertions
- // Create a cursor for dirty records
- Cursor localChangesCursor = mDb.query(mTable, null, SELECT_UNSYNCED, accountSelectionArgs,
- null, null, null);
- long numInsertsOrUpdates = localChangesCursor.getCount();
- while (localChangesCursor.moveToNext()) {
- if (mIsMergeCancelled) {
- localChangesCursor.close();
- return;
- }
- if (clientDiffs == null) {
- clientDiffs = temporaryInstanceFactory.getTemporaryInstance();
- }
- mValues.clear();
- cursorRowToContentValues(localChangesCursor, mValues);
- mValues.remove("_id");
- DatabaseUtils.cursorLongToContentValues(localChangesCursor, "_id", mValues,
- _SYNC_LOCAL_ID);
- clientDiffs.insert(mTableURL, mValues);
- }
- localChangesCursor.close();
-
- // Generate the client deletions
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "generating client deletions");
- long numEntries = DatabaseUtils.queryNumEntries(mDb, mTable);
- long numDeletedEntries = 0;
- if (mDeletedTable != null) {
- Cursor deletedCursor = mDb.query(mDeletedTable,
- syncIdAndVersionProjection,
- _SYNC_ACCOUNT + "=? AND " + _SYNC_ID + " IS NOT NULL", accountSelectionArgs,
- null, null, mDeletedTable + "." + _SYNC_ID);
-
- numDeletedEntries = deletedCursor.getCount();
- while (deletedCursor.moveToNext()) {
- if (mIsMergeCancelled) {
- deletedCursor.close();
- return;
- }
- if (clientDiffs == null) {
- clientDiffs = temporaryInstanceFactory.getTemporaryInstance();
- }
- mValues.clear();
- DatabaseUtils.cursorRowToContentValues(deletedCursor, mValues);
- clientDiffs.insert(mDeletedTableURL, mValues);
- }
- deletedCursor.close();
- }
-
- if (clientDiffs != null) {
- mergeResult.tempContentProvider = clientDiffs;
- }
- syncResult.stats.numDeletes += numDeletedEntries;
- syncResult.stats.numUpdates += numInsertsOrUpdates;
- syncResult.stats.numEntries += numEntries;
- }
-}
diff --git a/core/java/android/content/ActivityNotFoundException.java b/core/java/android/content/ActivityNotFoundException.java
deleted file mode 100644
index 16149bb..0000000
--- a/core/java/android/content/ActivityNotFoundException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-/**
- * This exception is thrown when a call to {@link Context#startActivity} or
- * one of its variants fails because an Activity can not be found to execute
- * the given Intent.
- */
-public class ActivityNotFoundException extends RuntimeException
-{
- public ActivityNotFoundException()
- {
- }
-
- public ActivityNotFoundException(String name)
- {
- super(name);
- }
-};
-
diff --git a/core/java/android/content/AsyncQueryHandler.java b/core/java/android/content/AsyncQueryHandler.java
deleted file mode 100644
index ac851cc..0000000
--- a/core/java/android/content/AsyncQueryHandler.java
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Log;
-
-import java.lang.ref.WeakReference;
-
-/**
- * A helper class to help make handling asynchronous {@link ContentResolver}
- * queries easier.
- */
-public abstract class AsyncQueryHandler extends Handler {
- private static final String TAG = "AsyncQuery";
- private static final boolean localLOGV = false;
-
- private static final int EVENT_ARG_QUERY = 1;
- private static final int EVENT_ARG_INSERT = 2;
- private static final int EVENT_ARG_UPDATE = 3;
- private static final int EVENT_ARG_DELETE = 4;
-
- /* package */ final WeakReference<ContentResolver> mResolver;
-
- private static Looper sLooper = null;
-
- private Handler mWorkerThreadHandler;
-
- protected static final class WorkerArgs {
- public Uri uri;
- public Handler handler;
- public String[] projection;
- public String selection;
- public String[] selectionArgs;
- public String orderBy;
- public Object result;
- public Object cookie;
- public ContentValues values;
- }
-
- protected class WorkerHandler extends Handler {
- public WorkerHandler(Looper looper) {
- super(looper);
- }
-
- @Override
- public void handleMessage(Message msg) {
- final ContentResolver resolver = mResolver.get();
- if (resolver == null) return;
-
- WorkerArgs args = (WorkerArgs) msg.obj;
-
- int token = msg.what;
- int event = msg.arg1;
-
- switch (event) {
- case EVENT_ARG_QUERY:
- Cursor cursor;
- try {
- cursor = resolver.query(args.uri, args.projection,
- args.selection, args.selectionArgs,
- args.orderBy);
- // Calling getCount() causes the cursor window to be filled,
- // which will make the first access on the main thread a lot faster.
- if (cursor != null) {
- cursor.getCount();
- }
- } catch (Exception e) {
- cursor = null;
- }
-
- args.result = cursor;
- break;
-
- case EVENT_ARG_INSERT:
- args.result = resolver.insert(args.uri, args.values);
- break;
-
- case EVENT_ARG_UPDATE:
- args.result = resolver.update(args.uri, args.values, args.selection,
- args.selectionArgs);
- break;
-
- case EVENT_ARG_DELETE:
- args.result = resolver.delete(args.uri, args.selection, args.selectionArgs);
- break;
-
- }
-
- // passing the original token value back to the caller
- // on top of the event values in arg1.
- Message reply = args.handler.obtainMessage(token);
- reply.obj = args;
- reply.arg1 = msg.arg1;
-
- if (localLOGV) {
- Log.d(TAG, "WorkerHandler.handleMsg: msg.arg1=" + msg.arg1
- + ", reply.what=" + reply.what);
- }
-
- reply.sendToTarget();
- }
- }
-
- public AsyncQueryHandler(ContentResolver cr) {
- super();
- mResolver = new WeakReference<ContentResolver>(cr);
- synchronized (AsyncQueryHandler.class) {
- if (sLooper == null) {
- HandlerThread thread = new HandlerThread("AsyncQueryWorker");
- thread.start();
-
- sLooper = thread.getLooper();
- }
- }
- mWorkerThreadHandler = createHandler(sLooper);
- }
-
- protected Handler createHandler(Looper looper) {
- return new WorkerHandler(looper);
- }
-
- /**
- * This method begins an asynchronous query. When the query is done
- * {@link #onQueryComplete} is called.
- *
- * @param token A token passed into {@link #onQueryComplete} to identify
- * the query.
- * @param cookie An object that gets passed into {@link #onQueryComplete}
- * @param uri The URI, using the content:// scheme, for the content to
- * retrieve.
- * @param projection A list of which columns to return. Passing null will
- * return all columns, which is discouraged to prevent reading data
- * from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return, formatted as an
- * SQL WHERE clause (excluding the WHERE itself). Passing null will
- * return all rows for the given URI.
- * @param selectionArgs You may include ?s in selection, which will be
- * replaced by the values from selectionArgs, in the order that they
- * appear in the selection. The values will be bound as Strings.
- * @param orderBy How to order the rows, formatted as an SQL ORDER BY
- * clause (excluding the ORDER BY itself). Passing null will use the
- * default sort order, which may be unordered.
- */
- public void startQuery(int token, Object cookie, Uri uri,
- String[] projection, String selection, String[] selectionArgs,
- String orderBy) {
- // Use the token as what so cancelOperations works properly
- Message msg = mWorkerThreadHandler.obtainMessage(token);
- msg.arg1 = EVENT_ARG_QUERY;
-
- WorkerArgs args = new WorkerArgs();
- args.handler = this;
- args.uri = uri;
- args.projection = projection;
- args.selection = selection;
- args.selectionArgs = selectionArgs;
- args.orderBy = orderBy;
- args.cookie = cookie;
- msg.obj = args;
-
- mWorkerThreadHandler.sendMessage(msg);
- }
-
- /**
- * Attempts to cancel operation that has not already started. Note that
- * there is no guarantee that the operation will be canceled. They still may
- * result in a call to on[Query/Insert/Update/Delete]Complete after this
- * call has completed.
- *
- * @param token The token representing the operation to be canceled.
- * If multiple operations have the same token they will all be canceled.
- */
- public final void cancelOperation(int token) {
- mWorkerThreadHandler.removeMessages(token);
- }
-
- /**
- * This method begins an asynchronous insert. When the insert operation is
- * done {@link #onInsertComplete} is called.
- *
- * @param token A token passed into {@link #onInsertComplete} to identify
- * the insert operation.
- * @param cookie An object that gets passed into {@link #onInsertComplete}
- * @param uri the Uri passed to the insert operation.
- * @param initialValues the ContentValues parameter passed to the insert operation.
- */
- public final void startInsert(int token, Object cookie, Uri uri,
- ContentValues initialValues) {
- // Use the token as what so cancelOperations works properly
- Message msg = mWorkerThreadHandler.obtainMessage(token);
- msg.arg1 = EVENT_ARG_INSERT;
-
- WorkerArgs args = new WorkerArgs();
- args.handler = this;
- args.uri = uri;
- args.cookie = cookie;
- args.values = initialValues;
- msg.obj = args;
-
- mWorkerThreadHandler.sendMessage(msg);
- }
-
- /**
- * This method begins an asynchronous update. When the update operation is
- * done {@link #onUpdateComplete} is called.
- *
- * @param token A token passed into {@link #onUpdateComplete} to identify
- * the update operation.
- * @param cookie An object that gets passed into {@link #onUpdateComplete}
- * @param uri the Uri passed to the update operation.
- * @param values the ContentValues parameter passed to the update operation.
- */
- public final void startUpdate(int token, Object cookie, Uri uri,
- ContentValues values, String selection, String[] selectionArgs) {
- // Use the token as what so cancelOperations works properly
- Message msg = mWorkerThreadHandler.obtainMessage(token);
- msg.arg1 = EVENT_ARG_UPDATE;
-
- WorkerArgs args = new WorkerArgs();
- args.handler = this;
- args.uri = uri;
- args.cookie = cookie;
- args.values = values;
- args.selection = selection;
- args.selectionArgs = selectionArgs;
- msg.obj = args;
-
- mWorkerThreadHandler.sendMessage(msg);
- }
-
- /**
- * This method begins an asynchronous delete. When the delete operation is
- * done {@link #onDeleteComplete} is called.
- *
- * @param token A token passed into {@link #onDeleteComplete} to identify
- * the delete operation.
- * @param cookie An object that gets passed into {@link #onDeleteComplete}
- * @param uri the Uri passed to the delete operation.
- * @param selection the where clause.
- */
- public final void startDelete(int token, Object cookie, Uri uri,
- String selection, String[] selectionArgs) {
- // Use the token as what so cancelOperations works properly
- Message msg = mWorkerThreadHandler.obtainMessage(token);
- msg.arg1 = EVENT_ARG_DELETE;
-
- WorkerArgs args = new WorkerArgs();
- args.handler = this;
- args.uri = uri;
- args.cookie = cookie;
- args.selection = selection;
- args.selectionArgs = selectionArgs;
- msg.obj = args;
-
- mWorkerThreadHandler.sendMessage(msg);
- }
-
- /**
- * Called when an asynchronous query is completed.
- *
- * @param token the token to identify the query, passed in from
- * {@link #startQuery}.
- * @param cookie the cookie object that's passed in from {@link #startQuery}.
- * @param cursor The cursor holding the results from the query.
- */
- protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
- // Empty
- }
-
- /**
- * Called when an asynchronous insert is completed.
- *
- * @param token the token to identify the query, passed in from
- * {@link #startInsert}.
- * @param cookie the cookie object that's passed in from
- * {@link #startInsert}.
- * @param uri the uri returned from the insert operation.
- */
- protected void onInsertComplete(int token, Object cookie, Uri uri) {
- // Empty
- }
-
- /**
- * Called when an asynchronous update is completed.
- *
- * @param token the token to identify the query, passed in from
- * {@link #startUpdate}.
- * @param cookie the cookie object that's passed in from
- * {@link #startUpdate}.
- * @param result the result returned from the update operation
- */
- protected void onUpdateComplete(int token, Object cookie, int result) {
- // Empty
- }
-
- /**
- * Called when an asynchronous delete is completed.
- *
- * @param token the token to identify the query, passed in from
- * {@link #startDelete}.
- * @param cookie the cookie object that's passed in from
- * {@link #startDelete}.
- * @param result the result returned from the delete operation
- */
- protected void onDeleteComplete(int token, Object cookie, int result) {
- // Empty
- }
-
- @Override
- public void handleMessage(Message msg) {
- WorkerArgs args = (WorkerArgs) msg.obj;
-
- if (localLOGV) {
- Log.d(TAG, "AsyncQueryHandler.handleMessage: msg.what=" + msg.what
- + ", msg.arg1=" + msg.arg1);
- }
-
- int token = msg.what;
- int event = msg.arg1;
-
- // pass token back to caller on each callback.
- switch (event) {
- case EVENT_ARG_QUERY:
- onQueryComplete(token, args.cookie, (Cursor) args.result);
- break;
-
- case EVENT_ARG_INSERT:
- onInsertComplete(token, args.cookie, (Uri) args.result);
- break;
-
- case EVENT_ARG_UPDATE:
- onUpdateComplete(token, args.cookie, (Integer) args.result);
- break;
-
- case EVENT_ARG_DELETE:
- onDeleteComplete(token, args.cookie, (Integer) args.result);
- break;
- }
- }
-}
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
deleted file mode 100644
index 08f6191..0000000
--- a/core/java/android/content/BroadcastReceiver.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.app.ActivityManagerNative;
-import android.app.IActivityManager;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Base class for code that will receive intents sent by sendBroadcast().
- * You can either dynamically register an instance of this class with
- * {@link Context#registerReceiver Context.registerReceiver()}
- * or statically publish an implementation through the
- * {@link android.R.styleable#AndroidManifestReceiver &lt;receiver&gt;}
- * tag in your <code>AndroidManifest.xml</code>. <em><strong>Note:</strong></em>
- * &nbsp;&nbsp;&nbsp;If registering a receiver in your
- * {@link android.app.Activity#onResume() Activity.onResume()}
- * implementation, you should unregister it in
- * {@link android.app.Activity#onPause() Activity.onPause()}.
- * (You won't receive intents when paused,
- * and this will cut down on unnecessary system overhead). Do not unregister in
- * {@link android.app.Activity#onSaveInstanceState(android.os.Bundle) Activity.onSaveInstanceState()},
- * because this won't be called if the user moves back in the history
- * stack.
- *
- * <p>There are two major classes of broadcasts that can be received:</p>
- * <ul>
- * <li> <b>Normal broadcasts</b> (sent with {@link Context#sendBroadcast(Intent)
- * Context.sendBroadcast}) are completely asynchronous. All receivers of the
- * broadcast are run, in an undefined order, often at the same time. This is
- * more efficient, but means that receivers can not use the result or abort
- * APIs included here.
- * <li> <b>Ordered broadcasts</b> (sent with {@link Context#sendOrderedBroadcast(Intent, String)
- * Context.sendOrderedBroadcast}) are delivered to one receiver at a time.
- * As each receiver executes in turn, it can propagate a result to the next
- * receiver, or it can completely abort the broadcast so that it won't be passed
- * to other receivers. The order receivers runs in can be controlled with the
- * {@link android.R.styleable#AndroidManifestIntentFilter_priority
- * android:priority} attribute of the matching intent-filter; receivers with
- * the same priority will be run in an arbitrary order.
- * </ul>
- *
- * <p>Even in the case of normal broadcasts, the system may in some
- * situations revert to delivering the broadcast one receiver at a time. In
- * particular, for receivers that may require the creation of a process, only
- * one will be run at a time to avoid overloading the system with new processes.
- * In this situation, however, the non-ordered semantics hold: these receivers
- * can not return results or abort their broadcast.</p>
- *
- * <p>Note that, although the Intent class is used for sending and receiving
- * these broadcasts, the Intent broadcast mechanism here is completely separate
- * from Intents that are used to start Activities with
- * {@link Context#startActivity Context.startActivity()}.
- * There is no way for an BroadcastReceiver
- * to see or capture Intents used with startActivity(); likewise, when
- * you broadcast an Intent, you will never find or start an Activity.
- * These two operations are semantically very different: starting an
- * Activity with an Intent is a foreground operation that modifies what the
- * user is currently interacting with; broadcasting an Intent is a background
- * operation that the user is not normally aware of.
- *
- * <p>The BroadcastReceiver class (when launched as a component through
- * a manifest's {@link android.R.styleable#AndroidManifestReceiver &lt;receiver&gt;}
- * tag) is an important part of an
- * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">application's overall lifecycle</a>.</p>
- *
- * <p>Topics covered here:
- * <ol>
- * <li><a href="#ReceiverLifecycle">Receiver Lifecycle</a>
- * <li><a href="#Permissions">Permissions</a>
- * <li><a href="#ProcessLifecycle">Process Lifecycle</a>
- * </ol>
- *
- * <a name="ReceiverLifecycle"></a>
- * <h3>Receiver Lifecycle</h3>
- *
- * <p>A BroadcastReceiver object is only valid for the duration of the call
- * to {@link #onReceive}. Once your code returns from this function,
- * the system considers the object to be finished and no longer active.
- *
- * <p>This has important repercussions to what you can do in an
- * {@link #onReceive} implementation: anything that requires asynchronous
- * operation is not available, because you will need to return from the
- * function to handle the asynchronous operation, but at that point the
- * BroadcastReceiver is no longer active and thus the system is free to kill
- * its process before the asynchronous operation completes.
- *
- * <p>In particular, you may <i>not</i> show a dialog or bind to a service from
- * within an BroadcastReceiver. For the former, you should instead use the
- * {@link android.app.NotificationManager} API. For the latter, you can
- * use {@link android.content.Context#startService Context.startService()} to
- * send a command to the service.
- *
- * <a name="Permissions"></a>
- * <h3>Permissions</h3>
- *
- * <p>Access permissions can be enforced by either the sender or receiver
- * of an Intent.
- *
- * <p>To enforce a permission when sending, you supply a non-null
- * <var>permission</var> argument to
- * {@link Context#sendBroadcast(Intent, String)} or
- * {@link Context#sendOrderedBroadcast(Intent, String, BroadcastReceiver, android.os.Handler, int, String, Bundle)}.
- * Only receivers who have been granted this permission
- * (by requesting it with the
- * {@link android.R.styleable#AndroidManifestUsesPermission &lt;uses-permission&gt;}
- * tag in their <code>AndroidManifest.xml</code>) will be able to receive
- * the broadcast.
- *
- * <p>To enforce a permission when receiving, you supply a non-null
- * <var>permission</var> when registering your receiver -- either when calling
- * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter, String, android.os.Handler)}
- * or in the static
- * {@link android.R.styleable#AndroidManifestReceiver &lt;receiver&gt;}
- * tag in your <code>AndroidManifest.xml</code>. Only broadcasters who have
- * been granted this permission (by requesting it with the
- * {@link android.R.styleable#AndroidManifestUsesPermission &lt;uses-permission&gt;}
- * tag in their <code>AndroidManifest.xml</code>) will be able to send an
- * Intent to the receiver.
- *
- * <p>See the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>
- * document for more information on permissions and security in general.
- *
- * <a name="ProcessLifecycle"></a>
- * <h3>Process Lifecycle</h3>
- *
- * <p>A process that is currently executing an BroadcastReceiver (that is,
- * currently running the code in its {@link #onReceive} method) is
- * considered to be a foreground process and will be kept running by the
- * system except under cases of extreme memory pressure.
- *
- * <p>Once you return from onReceive(), the BroadcastReceiver is no longer
- * active, and its hosting process is only as important as any other application
- * components that are running in it. This is especially important because if
- * that process was only hosting the BroadcastReceiver (a common case for
- * applications that the user has never or not recently interacted with), then
- * upon returning from onReceive() the system will consider its process
- * to be empty and aggressively kill it so that resources are available for other
- * more important processes.
- *
- * <p>This means that for longer-running operations you will often use
- * a {@link android.app.Service} in conjunction with an BroadcastReceiver to keep
- * the containing process active for the entire time of your operation.
- */
-public abstract class BroadcastReceiver {
- public BroadcastReceiver() {
- }
-
- /**
- * This method is called when the BroadcastReceiver is receiving an Intent
- * broadcast. During this time you can use the other methods on
- * BroadcastReceiver to view/modify the current result values. The function
- * is normally called from the main thread of its process, so you should
- * never perform long-running operations in it (there is a timeout of
- * 10 seconds that the system allows before considering the receiver to
- * be blocked and a candidate to be killed). You cannot launch a popup dialog
- * in your implementation of onReceive().
- *
- * <p><b>If this BroadcastReceiver was launched through a &lt;receiver&gt; tag,
- * then the object is no longer alive after returning from this
- * function.</b> This means you should not perform any operations that
- * return a result to you asynchronously -- in particular, for interacting
- * with services, you should use
- * {@link Context#startService(Intent)} instead of
- * {@link Context#bindService(Intent, ServiceConnection, int)}. If you wish
- * to interact with a service that is already running, you can use
- * {@link #peekService}.
- *
- * @param context The Context in which the receiver is running.
- * @param intent The Intent being received.
- */
- public abstract void onReceive(Context context, Intent intent);
-
- /**
- * Provide a binder to an already-running service. This method is synchronous
- * and will not start the target service if it is not present, so it is safe
- * to call from {@link #onReceive}.
- *
- * @param myContext The Context that had been passed to {@link #onReceive(Context, Intent)}
- * @param service The Intent indicating the service you wish to use. See {@link
- * Context#startService(Intent)} for more information.
- */
- public IBinder peekService(Context myContext, Intent service) {
- IActivityManager am = ActivityManagerNative.getDefault();
- IBinder binder = null;
- try {
- binder = am.peekService(service, service.resolveTypeIfNeeded(
- myContext.getContentResolver()));
- } catch (RemoteException e) {
- }
- return binder;
- }
-
- /**
- * Change the current result code of this broadcast; only works with
- * broadcasts sent through
- * {@link Context#sendOrderedBroadcast(Intent, String)
- * Context.sendOrderedBroadcast}. Often uses the
- * Activity {@link android.app.Activity#RESULT_CANCELED} and
- * {@link android.app.Activity#RESULT_OK} constants, though the
- * actual meaning of this value is ultimately up to the broadcaster.
- *
- * <p><strong>This method does not work with non-ordered broadcasts such
- * as those sent with {@link Context#sendBroadcast(Intent)
- * Context.sendBroadcast}</strong></p>
- *
- * @param code The new result code.
- *
- * @see #setResult(int, String, Bundle)
- */
- public final void setResultCode(int code) {
- checkSynchronousHint();
- mResultCode = code;
- }
-
- /**
- * Retrieve the current result code, as set by the previous receiver.
- *
- * @return int The current result code.
- */
- public final int getResultCode() {
- return mResultCode;
- }
-
- /**
- * Change the current result data of this broadcast; only works with
- * broadcasts sent through
- * {@link Context#sendOrderedBroadcast(Intent, String)
- * Context.sendOrderedBroadcast}. This is an arbitrary
- * string whose interpretation is up to the broadcaster.
- *
- * <p><strong>This method does not work with non-ordered broadcasts such
- * as those sent with {@link Context#sendBroadcast(Intent)
- * Context.sendBroadcast}</strong></p>
- *
- * @param data The new result data; may be null.
- *
- * @see #setResult(int, String, Bundle)
- */
- public final void setResultData(String data) {
- checkSynchronousHint();
- mResultData = data;
- }
-
- /**
- * Retrieve the current result data, as set by the previous receiver.
- * Often this is null.
- *
- * @return String The current result data; may be null.
- */
- public final String getResultData() {
- return mResultData;
- }
-
- /**
- * Change the current result extras of this broadcast; only works with
- * broadcasts sent through
- * {@link Context#sendOrderedBroadcast(Intent, String)
- * Context.sendOrderedBroadcast}. This is a Bundle
- * holding arbitrary data, whose interpretation is up to the
- * broadcaster. Can be set to null. Calling this method completely
- * replaces the current map (if any).
- *
- * <p><strong>This method does not work with non-ordered broadcasts such
- * as those sent with {@link Context#sendBroadcast(Intent)
- * Context.sendBroadcast}</strong></p>
- *
- * @param extras The new extra data map; may be null.
- *
- * @see #setResult(int, String, Bundle)
- */
- public final void setResultExtras(Bundle extras) {
- checkSynchronousHint();
- mResultExtras = extras;
- }
-
- /**
- * Retrieve the current result extra data, as set by the previous receiver.
- * Any changes you make to the returned Map will be propagated to the next
- * receiver.
- *
- * @param makeMap If true then a new empty Map will be made for you if the
- * current Map is null; if false you should be prepared to
- * receive a null Map.
- *
- * @return Map The current extras map.
- */
- public final Bundle getResultExtras(boolean makeMap) {
- Bundle e = mResultExtras;
- if (!makeMap) return e;
- if (e == null) mResultExtras = e = new Bundle();
- return e;
- }
-
- /**
- * Change all of the result data returned from this broadcasts; only works
- * with broadcasts sent through
- * {@link Context#sendOrderedBroadcast(Intent, String)
- * Context.sendOrderedBroadcast}. All current result data is replaced
- * by the value given to this method.
- *
- * <p><strong>This method does not work with non-ordered broadcasts such
- * as those sent with {@link Context#sendBroadcast(Intent)
- * Context.sendBroadcast}</strong></p>
- *
- * @param code The new result code. Often uses the
- * Activity {@link android.app.Activity#RESULT_CANCELED} and
- * {@link android.app.Activity#RESULT_OK} constants, though the
- * actual meaning of this value is ultimately up to the broadcaster.
- * @param data The new result data. This is an arbitrary
- * string whose interpretation is up to the broadcaster; may be null.
- * @param extras The new extra data map. This is a Bundle
- * holding arbitrary data, whose interpretation is up to the
- * broadcaster. Can be set to null. This completely
- * replaces the current map (if any).
- */
- public final void setResult(int code, String data, Bundle extras) {
- checkSynchronousHint();
- mResultCode = code;
- mResultData = data;
- mResultExtras = extras;
- }
-
- /**
- * Returns the flag indicating whether or not this receiver should
- * abort the current broadcast.
- *
- * @return True if the broadcast should be aborted.
- */
- public final boolean getAbortBroadcast() {
- return mAbortBroadcast;
- }
-
- /**
- * Sets the flag indicating that this receiver should abort the
- * current broadcast; only works with broadcasts sent through
- * {@link Context#sendOrderedBroadcast(Intent, String)
- * Context.sendOrderedBroadcast}. This will prevent
- * any other broadcast receivers from receiving the broadcast. It will still
- * call {@link #onReceive} of the BroadcastReceiver that the caller of
- * {@link Context#sendOrderedBroadcast(Intent, String)
- * Context.sendOrderedBroadcast} passed in.
- *
- * <p><strong>This method does not work with non-ordered broadcasts such
- * as those sent with {@link Context#sendBroadcast(Intent)
- * Context.sendBroadcast}</strong></p>
- */
- public final void abortBroadcast() {
- checkSynchronousHint();
- mAbortBroadcast = true;
- }
-
- /**
- * Clears the flag indicating that this receiver should abort the current
- * broadcast.
- */
- public final void clearAbortBroadcast() {
- mAbortBroadcast = false;
- }
-
- /**
- * For internal use, sets the hint about whether this BroadcastReceiver is
- * running in ordered mode.
- */
- public final void setOrderedHint(boolean isOrdered) {
- mOrderedHint = isOrdered;
- }
-
- /**
- * Control inclusion of debugging help for mismatched
- * calls to {@ Context#registerReceiver(BroadcastReceiver, IntentFilter)
- * Context.registerReceiver()}.
- * If called with true, before given to registerReceiver(), then the
- * callstack of the following {@link Context#unregisterReceiver(BroadcastReceiver)
- * Context.unregisterReceiver()} call is retained, to be printed if a later
- * incorrect unregister call is made. Note that doing this requires retaining
- * information about the BroadcastReceiver for the lifetime of the app,
- * resulting in a leak -- this should only be used for debugging.
- */
- public final void setDebugUnregister(boolean debug) {
- mDebugUnregister = debug;
- }
-
- /**
- * Return the last value given to {@link #setDebugUnregister}.
- */
- public final boolean getDebugUnregister() {
- return mDebugUnregister;
- }
-
- void checkSynchronousHint() {
- if (mOrderedHint) {
- return;
- }
- RuntimeException e = new RuntimeException(
- "BroadcastReceiver trying to return result during a non-ordered broadcast");
- e.fillInStackTrace();
- Log.e("BroadcastReceiver", e.getMessage(), e);
- }
-
- private int mResultCode;
- private String mResultData;
- private Bundle mResultExtras;
- private boolean mAbortBroadcast;
- private boolean mDebugUnregister;
- private boolean mOrderedHint;
-}
-
diff --git a/core/java/android/content/ComponentCallbacks.java b/core/java/android/content/ComponentCallbacks.java
deleted file mode 100644
index dad60b0..0000000
--- a/core/java/android/content/ComponentCallbacks.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.content.res.Configuration;
-
-/**
- * The set of callback APIs that are common to all application components
- * ({@link android.app.Activity}, {@link android.app.Service},
- * {@link ContentProvider}, and {@link android.app.Application}).
- */
-public interface ComponentCallbacks {
- /**
- * Called by the system when the device configuration changes while your
- * component is running. Note that, unlike activities, other components
- * are never restarted when a configuration changes: they must always deal
- * with the results of the change, such as by re-retrieving resources.
- *
- * <p>At the time that this function has been called, your Resources
- * object will have been updated to return resource values matching the
- * new configuration.
- *
- * @param newConfig The new device configuration.
- */
- void onConfigurationChanged(Configuration newConfig);
-
- /**
- * This is called when the overall system is running low on memory, and
- * would like actively running process to try to tighten their belt. While
- * the exact point at which this will be called is not defined, generally
- * it will happen around the time all background process have been killed,
- * that is before reaching the point of killing processes hosting
- * service and foreground UI that we would like to avoid killing.
- *
- * <p>Applications that want to be nice can implement this method to release
- * any caches or other unnecessary resources they may be holding on to.
- * The system will perform a gc for you after returning from this method.
- */
- void onLowMemory();
-}
diff --git a/core/java/android/content/ComponentName.aidl b/core/java/android/content/ComponentName.aidl
deleted file mode 100644
index 40dc8de..0000000
--- a/core/java/android/content/ComponentName.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * Copyright (c) 2007, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-parcelable ComponentName;
diff --git a/core/java/android/content/ComponentName.java b/core/java/android/content/ComponentName.java
deleted file mode 100644
index 32c6864..0000000
--- a/core/java/android/content/ComponentName.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Identifier for a specific application component
- * ({@link android.app.Activity}, {@link android.app.Service},
- * {@link android.content.BroadcastReceiver}, or
- * {@link android.content.ContentProvider}) that is available. Two
- * pieces of information, encapsulated here, are required to identify
- * a component: the package (a String) it exists in, and the class (a String)
- * name inside of that package.
- *
- */
-public final class ComponentName implements Parcelable {
- private final String mPackage;
- private final String mClass;
-
- /**
- * Create a new component identifier.
- *
- * @param pkg The name of the package that the component exists in. Can
- * not be null.
- * @param cls The name of the class inside of <var>pkg</var> that
- * implements the component. Can not be null.
- */
- public ComponentName(String pkg, String cls) {
- if (pkg == null) throw new NullPointerException("package name is null");
- if (cls == null) throw new NullPointerException("class name is null");
- mPackage = pkg;
- mClass = cls;
- }
-
- /**
- * Create a new component identifier from a Context and class name.
- *
- * @param pkg A Context for the package implementing the component,
- * from which the actual package name will be retrieved.
- * @param cls The name of the class inside of <var>pkg</var> that
- * implements the component.
- */
- public ComponentName(Context pkg, String cls) {
- if (cls == null) throw new NullPointerException("class name is null");
- mPackage = pkg.getPackageName();
- mClass = cls;
- }
-
- /**
- * Create a new component identifier from a Context and Class object.
- *
- * @param pkg A Context for the package implementing the component, from
- * which the actual package name will be retrieved.
- * @param cls The Class object of the desired component, from which the
- * actual class name will be retrieved.
- */
- public ComponentName(Context pkg, Class<?> cls) {
- mPackage = pkg.getPackageName();
- mClass = cls.getName();
- }
-
- /**
- * Return the package name of this component.
- */
- public String getPackageName() {
- return mPackage;
- }
-
- /**
- * Return the class name of this component.
- */
- public String getClassName() {
- return mClass;
- }
-
- /**
- * Return the class name, either fully qualified or in a shortened form
- * (with a leading '.') if it is a suffix of the package.
- */
- public String getShortClassName() {
- if (mClass.startsWith(mPackage)) {
- int PN = mPackage.length();
- int CN = mClass.length();
- if (CN > PN && mClass.charAt(PN) == '.') {
- return mClass.substring(PN, CN);
- }
- }
- return mClass;
- }
-
- /**
- * Return a String that unambiguously describes both the package and
- * class names contained in the ComponentName. You can later recover
- * the ComponentName from this string through
- * {@link #unflattenFromString(String)}.
- *
- * @return Returns a new String holding the package and class names. This
- * is represented as the package name, concatenated with a '/' and then the
- * class name.
- *
- * @see #unflattenFromString(String)
- */
- public String flattenToString() {
- return mPackage + "/" + mClass;
- }
-
- /**
- * The samee as {@link #flattenToString()}, but abbreviates the class
- * name if it is a suffix of the package. The result can still be used
- * with {@link #unflattenFromString(String)}.
- *
- * @return Returns a new String holding the package and class names. This
- * is represented as the package name, concatenated with a '/' and then the
- * class name.
- *
- * @see #unflattenFromString(String)
- */
- public String flattenToShortString() {
- return mPackage + "/" + getShortClassName();
- }
-
- /**
- * Recover a ComponentName from a String that was previously created with
- * {@link #flattenToString()}. It splits the string at the first '/',
- * taking the part before as the package name and the part after as the
- * class name. As a special convenience (to use, for example, when
- * parsing component names on the command line), if the '/' is immediately
- * followed by a '.' then the final class name will be the concatenation
- * of the package name with the string following the '/'. Thus
- * "com.foo/.Blah" becomes package="com.foo" class="com.foo.Blah".
- *
- * @param str The String that was returned by flattenToString().
- * @return Returns a new ComponentName containing the package and class
- * names that were encoded in <var>str</var>
- *
- * @see #flattenToString()
- */
- public static ComponentName unflattenFromString(String str) {
- int sep = str.indexOf('/');
- if (sep < 0 || (sep+1) >= str.length()) {
- return null;
- }
- String pkg = str.substring(0, sep);
- String cls = str.substring(sep+1);
- if (cls.length() > 0 && cls.charAt(0) == '.') {
- cls = pkg + cls;
- }
- return new ComponentName(pkg, cls);
- }
-
- /**
- * Return string representation of this class without the class's name
- * as a prefix.
- */
- public String toShortString() {
- return "{" + mPackage + "/" + mClass + "}";
- }
-
- @Override
- public String toString() {
- return "ComponentInfo{" + mPackage + "/" + mClass + "}";
- }
-
- @Override
- public boolean equals(Object obj) {
- try {
- if (obj != null) {
- ComponentName other = (ComponentName)obj;
- // Note: no null checks, because mPackage and mClass can
- // never be null.
- return mPackage.equals(other.mPackage)
- && mClass.equals(other.mClass);
- }
- } catch (ClassCastException e) {
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return mPackage.hashCode() + mClass.hashCode();
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(mPackage);
- out.writeString(mClass);
- }
-
- /**
- * Write a ComponentName to a Parcel, handling null pointers. Must be
- * read with {@link #readFromParcel(Parcel)}.
- *
- * @param c The ComponentName to be written.
- * @param out The Parcel in which the ComponentName will be placed.
- *
- * @see #readFromParcel(Parcel)
- */
- public static void writeToParcel(ComponentName c, Parcel out) {
- if (c != null) {
- c.writeToParcel(out, 0);
- } else {
- out.writeString(null);
- }
- }
-
- /**
- * Read a ComponentName from a Parcel that was previously written
- * with {@link #writeToParcel(ComponentName, Parcel)}, returning either
- * a null or new object as appropriate.
- *
- * @param in The Parcel from which to read the ComponentName
- * @return Returns a new ComponentName matching the previously written
- * object, or null if a null had been written.
- *
- * @see #writeToParcel(ComponentName, Parcel)
- */
- public static ComponentName readFromParcel(Parcel in) {
- String pkg = in.readString();
- return pkg != null ? new ComponentName(pkg, in) : null;
- }
-
- public static final Parcelable.Creator<ComponentName> CREATOR
- = new Parcelable.Creator<ComponentName>() {
- public ComponentName createFromParcel(Parcel in) {
- return new ComponentName(in);
- }
-
- public ComponentName[] newArray(int size) {
- return new ComponentName[size];
- }
- };
-
- /**
- * Instantiate a new ComponentName from the data in a Parcel that was
- * previously written with {@link #writeToParcel(Parcel, int)}. Note that you
- * must not use this with data written by
- * {@link #writeToParcel(ComponentName, Parcel)} since it is not possible
- * to handle a null ComponentObject here.
- *
- * @param in The Parcel containing the previously written ComponentName,
- * positioned at the location in the buffer where it was written.
- */
- public ComponentName(Parcel in) {
- mPackage = in.readString();
- if (mPackage == null) throw new NullPointerException(
- "package name is null");
- mClass = in.readString();
- if (mClass == null) throw new NullPointerException(
- "class name is null");
- }
-
- private ComponentName(String pkg, Parcel in) {
- mPackage = pkg;
- mClass = in.readString();
- }
-}
diff --git a/core/java/android/content/ContentInsertHandler.java b/core/java/android/content/ContentInsertHandler.java
deleted file mode 100644
index fbf726e..0000000
--- a/core/java/android/content/ContentInsertHandler.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-
-import org.xml.sax.ContentHandler;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Interface to insert data to ContentResolver
- * @hide
- */
-public interface ContentInsertHandler extends ContentHandler {
- /**
- * insert data from InputStream to ContentResolver
- * @param contentResolver
- * @param in InputStream
- * @throws IOException
- * @throws SAXException
- */
- public void insert(ContentResolver contentResolver, InputStream in)
- throws IOException, SAXException;
-
- /**
- * insert data from String to ContentResolver
- * @param contentResolver
- * @param in input string
- * @throws SAXException
- */
- public void insert(ContentResolver contentResolver, String in)
- throws SAXException;
-
-}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
deleted file mode 100644
index 3a64cee..0000000
--- a/core/java/android/content/ContentProvider.java
+++ /dev/null
@@ -1,562 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
-import android.content.res.Configuration;
-import android.database.Cursor;
-import android.database.CursorToBulkCursorAdaptor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
-import android.database.SQLException;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.ParcelFileDescriptor;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-
-/**
- * Content providers are one of the primary building blocks of Android applications, providing
- * content to applications. They encapsulate data and provide it to applications through the single
- * {@link ContentResolver} interface. A content provider is only required if you need to share
- * data between multiple applications. For example, the contacts data is used by multiple
- * applications and must be stored in a content provider. If you don't need to share data amongst
- * multiple applications you can use a database directly via
- * {@link android.database.sqlite.SQLiteDatabase}.
- *
- * <p>For more information, read <a href="{@docRoot}guide/topics/providers/content-providers.html">Content
- * Providers</a>.</p>
- *
- * <p>When a request is made via
- * a {@link ContentResolver} the system inspects the authority of the given URI and passes the
- * request to the content provider registered with the authority. The content provider can interpret
- * the rest of the URI however it wants. The {@link UriMatcher} class is helpful for parsing
- * URIs.</p>
- *
- * <p>The primary methods that need to be implemented are:
- * <ul>
- * <li>{@link #query} which returns data to the caller</li>
- * <li>{@link #insert} which inserts new data into the content provider</li>
- * <li>{@link #update} which updates existing data in the content provider</li>
- * <li>{@link #delete} which deletes data from the content provider</li>
- * <li>{@link #getType} which returns the MIME type of data in the content provider</li>
- * </ul></p>
- *
- * <p>This class takes care of cross process calls so subclasses don't have to worry about which
- * process a request is coming from.</p>
- */
-public abstract class ContentProvider implements ComponentCallbacks {
- private Context mContext = null;
- private String mReadPermission;
- private String mWritePermission;
-
- private Transport mTransport = new Transport();
-
- /**
- * Given an IContentProvider, try to coerce it back to the real
- * ContentProvider object if it is running in the local process. This can
- * be used if you know you are running in the same process as a provider,
- * and want to get direct access to its implementation details. Most
- * clients should not nor have a reason to use it.
- *
- * @param abstractInterface The ContentProvider interface that is to be
- * coerced.
- * @return If the IContentProvider is non-null and local, returns its actual
- * ContentProvider instance. Otherwise returns null.
- * @hide
- */
- public static ContentProvider coerceToLocalContentProvider(
- IContentProvider abstractInterface) {
- if (abstractInterface instanceof Transport) {
- return ((Transport)abstractInterface).getContentProvider();
- }
- return null;
- }
-
- /**
- * Binder object that deals with remoting.
- *
- * @hide
- */
- class Transport extends ContentProviderNative {
- ContentProvider getContentProvider() {
- return ContentProvider.this;
- }
-
- /**
- * Remote version of a query, which returns an IBulkCursor. The bulk
- * cursor should be wrapped with BulkCursorToCursorAdaptor before use.
- */
- public IBulkCursor bulkQuery(Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder,
- IContentObserver observer, CursorWindow window) {
- checkReadPermission(uri);
- Cursor cursor = ContentProvider.this.query(uri, projection,
- selection, selectionArgs, sortOrder);
- if (cursor == null) {
- return null;
- }
- String wperm = getWritePermission();
- return new CursorToBulkCursorAdaptor(cursor, observer,
- ContentProvider.this.getClass().getName(),
- wperm == null ||
- getContext().checkCallingOrSelfPermission(getWritePermission())
- == PackageManager.PERMISSION_GRANTED,
- window);
- }
-
- public Cursor query(Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
- checkReadPermission(uri);
- return ContentProvider.this.query(uri, projection, selection,
- selectionArgs, sortOrder);
- }
-
- public String getType(Uri uri) {
- return ContentProvider.this.getType(uri);
- }
-
-
- public Uri insert(Uri uri, ContentValues initialValues) {
- checkWritePermission(uri);
- return ContentProvider.this.insert(uri, initialValues);
- }
-
- public int bulkInsert(Uri uri, ContentValues[] initialValues) {
- checkWritePermission(uri);
- return ContentProvider.this.bulkInsert(uri, initialValues);
- }
-
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- checkWritePermission(uri);
- return ContentProvider.this.delete(uri, selection, selectionArgs);
- }
-
- public int update(Uri uri, ContentValues values, String selection,
- String[] selectionArgs) {
- checkWritePermission(uri);
- return ContentProvider.this.update(uri, values, selection, selectionArgs);
- }
-
- public ParcelFileDescriptor openFile(Uri uri, String mode)
- throws FileNotFoundException {
- if (mode != null && mode.startsWith("rw")) checkWritePermission(uri);
- else checkReadPermission(uri);
- return ContentProvider.this.openFile(uri, mode);
- }
-
- public ISyncAdapter getSyncAdapter() {
- checkWritePermission(null);
- return ContentProvider.this.getSyncAdapter().getISyncAdapter();
- }
-
- private void checkReadPermission(Uri uri) {
- final String rperm = getReadPermission();
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- if (getContext().checkUriPermission(uri, rperm, null, pid, uid,
- Intent.FLAG_GRANT_READ_URI_PERMISSION)
- == PackageManager.PERMISSION_GRANTED) {
- return;
- }
- String msg = "Permission Denial: reading "
- + ContentProvider.this.getClass().getName()
- + " uri " + uri + " from pid=" + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " requires " + rperm;
- throw new SecurityException(msg);
- }
-
- private void checkWritePermission(Uri uri) {
- final String wperm = getWritePermission();
- final int pid = Binder.getCallingPid();
- final int uid = Binder.getCallingUid();
- if (getContext().checkUriPermission(uri, null, wperm, pid, uid,
- Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
- == PackageManager.PERMISSION_GRANTED) {
- return;
- }
- String msg = "Permission Denial: writing "
- + ContentProvider.this.getClass().getName()
- + " uri " + uri + " from pid=" + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid()
- + " requires " + wperm;
- throw new SecurityException(msg);
- }
- }
-
-
- /**
- * Retrieve the Context this provider is running in. Only available once
- * onCreate(Map icicle) has been called -- this will be null in the
- * constructor.
- */
- public final Context getContext() {
- return mContext;
- }
-
- /**
- * Change the permission required to read data from the content
- * provider. This is normally set for you from its manifest information
- * when the provider is first created.
- *
- * @param permission Name of the permission required for read-only access.
- */
- protected final void setReadPermission(String permission) {
- mReadPermission = permission;
- }
-
- /**
- * Return the name of the permission required for read-only access to
- * this content provider. This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- */
- public final String getReadPermission() {
- return mReadPermission;
- }
-
- /**
- * Change the permission required to read and write data in the content
- * provider. This is normally set for you from its manifest information
- * when the provider is first created.
- *
- * @param permission Name of the permission required for read/write access.
- */
- protected final void setWritePermission(String permission) {
- mWritePermission = permission;
- }
-
- /**
- * Return the name of the permission required for read/write access to
- * this content provider. This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- */
- public final String getWritePermission() {
- return mWritePermission;
- }
-
- /**
- * Called when the provider is being started.
- *
- * @return true if the provider was successfully loaded, false otherwise
- */
- public abstract boolean onCreate();
-
- public void onConfigurationChanged(Configuration newConfig) {
- }
-
- public void onLowMemory() {
- }
-
- /**
- * Receives a query request from a client in a local process, and
- * returns a Cursor. This is called internally by the {@link ContentResolver}.
- * This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- * <p>
- * Example client call:<p>
- * <pre>// Request a specific record.
- * Cursor managedCursor = managedQuery(
- Contacts.People.CONTENT_URI.addId(2),
- projection, // Which columns to return.
- null, // WHERE clause.
- People.NAME + " ASC"); // Sort order.</pre>
- * Example implementation:<p>
- * <pre>// SQLiteQueryBuilder is a helper class that creates the
- // proper SQL syntax for us.
- SQLiteQueryBuilder qBuilder = new SQLiteQueryBuilder();
-
- // Set the table we're querying.
- qBuilder.setTables(DATABASE_TABLE_NAME);
-
- // If the query ends in a specific record number, we're
- // being asked for a specific record, so set the
- // WHERE clause in our query.
- if((URI_MATCHER.match(uri)) == SPECIFIC_MESSAGE){
- qBuilder.appendWhere("_id=" + uri.getPathLeafId());
- }
-
- // Make the query.
- Cursor c = qBuilder.query(mDb,
- projection,
- selection,
- selectionArgs,
- groupBy,
- having,
- sortOrder);
- c.setNotificationUri(getContext().getContentResolver(), uri);
- return c;</pre>
- *
- * @param uri The URI to query. This will be the full URI sent by the client;
- * if the client is requesting a specific record, the URI will end in a record number
- * that the implementation should parse and add to a WHERE or HAVING clause, specifying
- * that _id value.
- * @param projection The list of columns to put into the cursor. If
- * null all columns are included.
- * @param selection A selection criteria to apply when filtering rows.
- * If null then all rows are included.
- * @param sortOrder How the rows in the cursor should be sorted.
- * If null then the provider is free to define the sort order.
- * @return a Cursor or null.
- */
- public abstract Cursor query(Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder);
-
- /**
- * Return the MIME type of the data at the given URI. This should start with
- * <code>vnd.android.cursor.item</code> for a single record,
- * or <code>vnd.android.cursor.dir/</code> for multiple items.
- * This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- *
- * @param uri the URI to query.
- * @return a MIME type string, or null if there is no type.
- */
- public abstract String getType(Uri uri);
-
- /**
- * Implement this to insert a new row.
- * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
- * after inserting.
- * This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- * @param uri The content:// URI of the insertion request.
- * @param values A set of column_name/value pairs to add to the database.
- * @return The URI for the newly inserted item.
- */
- public abstract Uri insert(Uri uri, ContentValues values);
-
- /**
- * Implement this to insert a set of new rows, or the default implementation will
- * iterate over the values and call {@link #insert} on each of them.
- * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
- * after inserting.
- * This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- *
- * @param uri The content:// URI of the insertion request.
- * @param values An array of sets of column_name/value pairs to add to the database.
- * @return The number of values that were inserted.
- */
- public int bulkInsert(Uri uri, ContentValues[] values) {
- int numValues = values.length;
- for (int i = 0; i < numValues; i++) {
- insert(uri, values[i]);
- }
- return numValues;
- }
-
- /**
- * A request to delete one or more rows. The selection clause is applied when performing
- * the deletion, allowing the operation to affect multiple rows in a
- * directory.
- * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyDelete()}
- * after deleting.
- * This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- *
- * <p>The implementation is responsible for parsing out a row ID at the end
- * of the URI, if a specific row is being deleted. That is, the client would
- * pass in <code>content://contacts/people/22</code> and the implementation is
- * responsible for parsing the record number (22) when creating a SQL statement.
- *
- * @param uri The full URI to query, including a row ID (if a specific record is requested).
- * @param selection An optional restriction to apply to rows when deleting.
- * @return The number of rows affected.
- * @throws SQLException
- */
- public abstract int delete(Uri uri, String selection, String[] selectionArgs);
-
- /**
- * Update a content URI. All rows matching the optionally provided selection
- * will have their columns listed as the keys in the values map with the
- * values of those keys.
- * As a courtesy, call {@link ContentResolver#notifyChange(android.net.Uri ,android.database.ContentObserver) notifyChange()}
- * after updating.
- * This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- *
- * @param uri The URI to query. This can potentially have a record ID if this
- * is an update request for a specific record.
- * @param values A Bundle mapping from column names to new column values (NULL is a
- * valid value).
- * @param selection An optional filter to match rows to update.
- * @return the number of rows affected.
- */
- public abstract int update(Uri uri, ContentValues values, String selection,
- String[] selectionArgs);
-
- /**
- * Open a file blob associated with a content URI.
- * This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- *
- * <p>Returns a
- * ParcelFileDescriptor, from which you can obtain a
- * {@link java.io.FileDescriptor} for use with
- * {@link java.io.FileInputStream}, {@link java.io.FileOutputStream}, etc.
- * This can be used to store large data (such as an image) associated with
- * a particular piece of content.
- *
- * <p>The returned ParcelFileDescriptor is owned by the caller, so it is
- * their responsibility to close it when done. That is, the implementation
- * 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
- * or "rw" for read and write access.
- *
- * @return Returns a new ParcelFileDescriptor 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.
- */
- public ParcelFileDescriptor openFile(Uri uri, String mode)
- throws FileNotFoundException {
- throw new FileNotFoundException("No files supported by provider at "
- + uri);
- }
-
- /**
- * 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.
- *
- * @return Returns a new ParcelFileDescriptor that can be used by the
- * client to access the file.
- */
- protected final ParcelFileDescriptor openFileHelper(Uri uri,
- String mode) throws FileNotFoundException {
- Cursor c = query(uri, new String[]{"_data"}, null, null, null);
- int count = (c != null) ? c.getCount() : 0;
- if (count != 1) {
- // If there is not exactly one result, throw an appropriate
- // exception.
- if (c != null) {
- c.close();
- }
- if (count == 0) {
- throw new FileNotFoundException("No entry for " + uri);
- }
- throw new FileNotFoundException("Multiple items at " + uri);
- }
-
- c.moveToFirst();
- int i = c.getColumnIndex("_data");
- String path = (i >= 0 ? c.getString(i) : null);
- c.close();
- if (path == null) {
- throw new FileNotFoundException("Column _data not found.");
- }
-
- 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);
- }
-
- /**
- * Get the sync adapter that is to be used by this content provider.
- * This is intended for use by the sync system. If null then this
- * content provider is considered not syncable.
- * This method can be called from multiple
- * threads, as described in
- * <a href="{@docRoot}guide/topics/fundamentals.html#procthread">Application Fundamentals:
- * Processes and Threads</a>.
- *
- * @return the SyncAdapter that is to be used by this ContentProvider, or null
- * if this ContentProvider is not syncable
- * @hide
- */
- public SyncAdapter getSyncAdapter() {
- return null;
- }
-
- /**
- * Returns true if this instance is a temporary content provider.
- * @return true if this instance is a temporary content provider
- */
- protected boolean isTemporary() {
- return false;
- }
-
- /**
- * Returns the Binder object for this provider.
- *
- * @return the Binder object for this provider
- * @hide
- */
- public IContentProvider getIContentProvider() {
- return mTransport;
- }
-
- /**
- * After being instantiated, this is called to tell the content provider
- * about itself.
- *
- * @param context The context this provider is running in
- * @param info Registered information about this content provider
- */
- public void attachInfo(Context context, ProviderInfo info) {
-
- /*
- * Only allow it to be set once, so after the content service gives
- * this to us clients can't change it.
- */
- if (mContext == null) {
- mContext = context;
- if (info != null) {
- setReadPermission(info.readPermission);
- setWritePermission(info.writePermission);
- }
- ContentProvider.this.onCreate();
- }
- }
-}
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
deleted file mode 100644
index ede2c9b..0000000
--- a/core/java/android/content/ContentProviderNative.java
+++ /dev/null
@@ -1,435 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.BulkCursorNative;
-import android.database.BulkCursorToCursorAdaptor;
-import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.DatabaseUtils;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.ParcelFileDescriptor;
-import android.os.Parcelable;
-
-import java.io.FileNotFoundException;
-
-/**
- * {@hide}
- */
-abstract public class ContentProviderNative extends Binder implements IContentProvider {
- private static final String TAG = "ContentProvider";
-
- public ContentProviderNative()
- {
- attachInterface(this, descriptor);
- }
-
- /**
- * Cast a Binder object into a content resolver interface, generating
- * a proxy if needed.
- */
- static public IContentProvider asInterface(IBinder obj)
- {
- if (obj == null) {
- return null;
- }
- IContentProvider in =
- (IContentProvider)obj.queryLocalInterface(descriptor);
- if (in != null) {
- return in;
- }
-
- return new ContentProviderProxy(obj);
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- throws RemoteException {
- try {
- switch (code) {
- case QUERY_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- int num = data.readInt();
- String[] projection = null;
- if (num > 0) {
- projection = new String[num];
- for (int i = 0; i < num; i++) {
- projection[i] = data.readString();
- }
- }
- String selection = data.readString();
- num = data.readInt();
- String[] selectionArgs = null;
- if (num > 0) {
- selectionArgs = new String[num];
- for (int i = 0; i < num; i++) {
- selectionArgs[i] = data.readString();
- }
- }
- String sortOrder = data.readString();
- IContentObserver observer = IContentObserver.Stub.
- asInterface(data.readStrongBinder());
- CursorWindow window = CursorWindow.CREATOR.createFromParcel(data);
-
- IBulkCursor bulkCursor = bulkQuery(url, projection, selection,
- selectionArgs, sortOrder, observer, window);
- reply.writeNoException();
- if (bulkCursor != null) {
- reply.writeStrongBinder(bulkCursor.asBinder());
- } else {
- reply.writeStrongBinder(null);
- }
- return true;
- }
-
- case GET_TYPE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- String type = getType(url);
- reply.writeNoException();
- reply.writeString(type);
-
- return true;
- }
-
- case INSERT_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- ContentValues values = ContentValues.CREATOR.createFromParcel(data);
-
- Uri out = insert(url, values);
- reply.writeNoException();
- Uri.writeToParcel(reply, out);
- return true;
- }
-
- case BULK_INSERT_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- ContentValues[] values = data.createTypedArray(ContentValues.CREATOR);
-
- int count = bulkInsert(url, values);
- reply.writeNoException();
- reply.writeInt(count);
- return true;
- }
-
- case DELETE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- String selection = data.readString();
- String[] selectionArgs = data.readStringArray();
-
- int count = delete(url, selection, selectionArgs);
-
- reply.writeNoException();
- reply.writeInt(count);
- return true;
- }
-
- case UPDATE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- ContentValues values = ContentValues.CREATOR.createFromParcel(data);
- String selection = data.readString();
- String[] selectionArgs = data.readStringArray();
-
- int count = update(url, values, selection, selectionArgs);
-
- reply.writeNoException();
- reply.writeInt(count);
- return true;
- }
-
- case OPEN_FILE_TRANSACTION:
- {
- data.enforceInterface(IContentProvider.descriptor);
- Uri url = Uri.CREATOR.createFromParcel(data);
- String mode = data.readString();
-
- ParcelFileDescriptor fd;
- fd = openFile(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);
- ISyncAdapter sa = getSyncAdapter();
- reply.writeNoException();
- reply.writeStrongBinder(sa != null ? sa.asBinder() : null);
- return true;
- }
- }
- } catch (Exception e) {
- DatabaseUtils.writeExceptionToParcel(reply, e);
- return true;
- }
-
- return super.onTransact(code, data, reply, flags);
- }
-
- public IBinder asBinder()
- {
- return this;
- }
-}
-
-
-final class ContentProviderProxy implements IContentProvider
-{
- public ContentProviderProxy(IBinder remote)
- {
- mRemote = remote;
- }
-
- public IBinder asBinder()
- {
- return mRemote;
- }
-
- public IBulkCursor bulkQuery(Uri url, String[] projection,
- String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
- CursorWindow window) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IContentProvider.descriptor);
-
- url.writeToParcel(data, 0);
- int length = 0;
- if (projection != null) {
- length = projection.length;
- }
- data.writeInt(length);
- for (int i = 0; i < length; i++) {
- data.writeString(projection[i]);
- }
- data.writeString(selection);
- if (selectionArgs != null) {
- length = selectionArgs.length;
- } else {
- length = 0;
- }
- data.writeInt(length);
- for (int i = 0; i < length; i++) {
- data.writeString(selectionArgs[i]);
- }
- data.writeString(sortOrder);
- data.writeStrongBinder(observer.asBinder());
- window.writeToParcel(data, 0);
-
- mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- IBulkCursor bulkCursor = null;
- IBinder bulkCursorBinder = reply.readStrongBinder();
- if (bulkCursorBinder != null) {
- bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder);
- }
-
- data.recycle();
- reply.recycle();
-
- return bulkCursor;
- }
-
- public Cursor query(Uri url, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) throws RemoteException {
- //TODO make a pool of windows so we can reuse memory dealers
- CursorWindow window = new CursorWindow(false /* window will be used remotely */);
- BulkCursorToCursorAdaptor adaptor = new BulkCursorToCursorAdaptor();
- IBulkCursor bulkCursor = bulkQuery(url, projection, selection, selectionArgs, sortOrder,
- adaptor.getObserver(), window);
-
- if (bulkCursor == null) {
- return null;
- }
- adaptor.set(bulkCursor);
- return adaptor;
- }
-
- public String getType(Uri url) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IContentProvider.descriptor);
-
- url.writeToParcel(data, 0);
-
- mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- String out = reply.readString();
-
- data.recycle();
- reply.recycle();
-
- return out;
- }
-
- public Uri insert(Uri url, ContentValues values) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IContentProvider.descriptor);
-
- url.writeToParcel(data, 0);
- values.writeToParcel(data, 0);
-
- mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- Uri out = Uri.CREATOR.createFromParcel(reply);
-
- data.recycle();
- reply.recycle();
-
- return out;
- }
-
- public int bulkInsert(Uri url, ContentValues[] values) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IContentProvider.descriptor);
-
- url.writeToParcel(data, 0);
- data.writeTypedArray(values, 0);
-
- mRemote.transact(IContentProvider.BULK_INSERT_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
-
- data.recycle();
- reply.recycle();
-
- return count;
- }
-
- public int delete(Uri url, String selection, String[] selectionArgs)
- throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IContentProvider.descriptor);
-
- url.writeToParcel(data, 0);
- data.writeString(selection);
- data.writeStringArray(selectionArgs);
-
- mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
-
- data.recycle();
- reply.recycle();
-
- return count;
- }
-
- public int update(Uri url, ContentValues values, String selection,
- String[] selectionArgs) throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IContentProvider.descriptor);
-
- url.writeToParcel(data, 0);
- values.writeToParcel(data, 0);
- data.writeString(selection);
- data.writeStringArray(selectionArgs);
-
- mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
-
- data.recycle();
- reply.recycle();
-
- return count;
- }
-
- public ParcelFileDescriptor openFile(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_FILE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null;
-
- data.recycle();
- reply.recycle();
-
- return fd;
- }
-
- public ISyncAdapter getSyncAdapter() throws RemoteException {
- Parcel data = Parcel.obtain();
- Parcel reply = Parcel.obtain();
-
- data.writeInterfaceToken(IContentProvider.descriptor);
-
- mRemote.transact(IContentProvider.GET_SYNC_ADAPTER_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- ISyncAdapter syncAdapter = ISyncAdapter.Stub.asInterface(reply.readStrongBinder());
-
- data.recycle();
- reply.recycle();
-
- return syncAdapter;
- }
-
- private IBinder mRemote;
-}
-
diff --git a/core/java/android/content/ContentQueryMap.java b/core/java/android/content/ContentQueryMap.java
deleted file mode 100644
index dbcb4a7..0000000
--- a/core/java/android/content/ContentQueryMap.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.os.Handler;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Observable;
-
-/**
- * Caches the contents of a cursor into a Map of String->ContentValues and optionally
- * keeps the cache fresh by registering for updates on the content backing the cursor. The column of
- * the database that is to be used as the key of the map is user-configurable, and the
- * ContentValues contains all columns other than the one that is designated the key.
- * <p>
- * The cursor data is accessed by row key and column name via getValue().
- */
-public class ContentQueryMap extends Observable {
- private Cursor mCursor;
- private String[] mColumnNames;
- private int mKeyColumn;
-
- private Handler mHandlerForUpdateNotifications = null;
- private boolean mKeepUpdated = false;
-
- private Map<String, ContentValues> mValues = null;
-
- private ContentObserver mContentObserver;
-
- /** Set when a cursor change notification is received and is cleared on a call to requery(). */
- private boolean mDirty = false;
-
- /**
- * Creates a ContentQueryMap that caches the content backing the cursor
- *
- * @param cursor the cursor whose contents should be cached
- * @param columnNameOfKey the column that is to be used as the key of the values map
- * @param keepUpdated true if the cursor's ContentProvider should be monitored for changes and
- * the map updated when changes do occur
- * @param handlerForUpdateNotifications the Handler that should be used to receive
- * notifications of changes (if requested). Normally you pass null here, but if
- * you know that the thread that is creating this isn't a thread that can receive
- * messages then you can create your own handler and use that here.
- */
- public ContentQueryMap(Cursor cursor, String columnNameOfKey, boolean keepUpdated,
- Handler handlerForUpdateNotifications) {
- mCursor = cursor;
- mColumnNames = mCursor.getColumnNames();
- mKeyColumn = mCursor.getColumnIndexOrThrow(columnNameOfKey);
- mHandlerForUpdateNotifications = handlerForUpdateNotifications;
- setKeepUpdated(keepUpdated);
-
- // If we aren't keeping the cache updated with the current state of the cursor's
- // ContentProvider then read it once into the cache. Otherwise the cache will be filled
- // automatically.
- if (!keepUpdated) {
- readCursorIntoCache();
- }
- }
-
- /**
- * Change whether or not the ContentQueryMap will register with the cursor's ContentProvider
- * for change notifications. If you use a ContentQueryMap in an activity you should call this
- * with false in onPause(), which means you need to call it with true in onResume()
- * if want it to be kept updated.
- * @param keepUpdated if true the ContentQueryMap should be registered with the cursor's
- * ContentProvider, false otherwise
- */
- public void setKeepUpdated(boolean keepUpdated) {
- if (keepUpdated == mKeepUpdated) return;
- mKeepUpdated = keepUpdated;
-
- if (!mKeepUpdated) {
- mCursor.unregisterContentObserver(mContentObserver);
- mContentObserver = null;
- } else {
- if (mHandlerForUpdateNotifications == null) {
- mHandlerForUpdateNotifications = new Handler();
- }
- if (mContentObserver == null) {
- mContentObserver = new ContentObserver(mHandlerForUpdateNotifications) {
- @Override
- public void onChange(boolean selfChange) {
- // If anyone is listening, we need to do this now to broadcast
- // to the observers. Otherwise, we'll just set mDirty and
- // let it query lazily when they ask for the values.
- if (countObservers() != 0) {
- requery();
- } else {
- mDirty = true;
- }
- }
- };
- }
- mCursor.registerContentObserver(mContentObserver);
- // mark dirty, since it is possible the cursor's backing data had changed before we
- // registered for changes
- mDirty = true;
- }
- }
-
- /**
- * Access the ContentValues for the row specified by rowName
- * @param rowName which row to read
- * @return the ContentValues for the row, or null if the row wasn't present in the cursor
- */
- public synchronized ContentValues getValues(String rowName) {
- if (mDirty) requery();
- return mValues.get(rowName);
- }
-
- /** Requeries the cursor and reads the contents into the cache */
- public void requery() {
- mDirty = false;
- mCursor.requery();
- readCursorIntoCache();
- setChanged();
- notifyObservers();
- }
-
- private synchronized void readCursorIntoCache() {
- // Make a new map so old values returned by getRows() are undisturbed.
- int capacity = mValues != null ? mValues.size() : 0;
- mValues = new HashMap<String, ContentValues>(capacity);
- while (mCursor.moveToNext()) {
- ContentValues values = new ContentValues();
- for (int i = 0; i < mColumnNames.length; i++) {
- if (i != mKeyColumn) {
- values.put(mColumnNames[i], mCursor.getString(i));
- }
- }
- mValues.put(mCursor.getString(mKeyColumn), values);
- }
- }
-
- public synchronized Map<String, ContentValues> getRows() {
- if (mDirty) requery();
- return mValues;
- }
-
- public synchronized void close() {
- if (mContentObserver != null) {
- mCursor.unregisterContentObserver(mContentObserver);
- mContentObserver = null;
- }
- mCursor.close();
- mCursor = null;
- }
-
- @Override
- protected void finalize() throws Throwable {
- if (mCursor != null) close();
- super.finalize();
- }
-}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
deleted file mode 100644
index 52f55b6..0000000
--- a/core/java/android/content/ContentResolver.java
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.database.CursorWrapper;
-import android.database.IContentObserver;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
-import android.text.TextUtils;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.List;
-
-
-/**
- * This class provides applications access to the content model.
- */
-public abstract class ContentResolver {
- public final static String SYNC_EXTRAS_ACCOUNT = "account";
- public static final String SYNC_EXTRAS_EXPEDITED = "expedited";
- public static final String SYNC_EXTRAS_FORCE = "force";
- public static final String SYNC_EXTRAS_UPLOAD = "upload";
- public static final String SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS = "deletions_override";
- public static final String SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS = "discard_deletions";
-
- public static final String SCHEME_CONTENT = "content";
- public static final String SCHEME_ANDROID_RESOURCE = "android.resource";
- public static final String SCHEME_FILE = "file";
-
- /**
- * This is the Android platform's base MIME type for a content: URI
- * containing a Cursor of a single item. Applications should use this
- * as the base type along with their own sub-type of their content: URIs
- * that represent a particular item. For example, hypothetical IMAP email
- * client may have a URI
- * <code>content://com.company.provider.imap/inbox/1</code> for a particular
- * message in the inbox, whose MIME type would be reported as
- * <code>CURSOR_ITEM_BASE_TYPE + "/vnd.company.imap-msg"</code>
- *
- * <p>Compare with {@link #CURSOR_DIR_BASE_TYPE}.
- */
- public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item";
-
- /**
- * This is the Android platform's base MIME type for a content: URI
- * containing a Cursor of zero or more items. Applications should use this
- * as the base type along with their own sub-type of their content: URIs
- * that represent a directory of items. For example, hypothetical IMAP email
- * client may have a URI
- * <code>content://com.company.provider.imap/inbox</code> for all of the
- * messages in its inbox, whose MIME type would be reported as
- * <code>CURSOR_DIR_BASE_TYPE + "/vnd.company.imap-msg"</code>
- *
- * <p>Note how the base MIME type varies between this and
- * {@link #CURSOR_ITEM_BASE_TYPE} depending on whether there is
- * one single item or multiple items in the data set, while the sub-type
- * remains the same because in either case the data structure contained
- * in the cursor is the same.
- */
- public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir";
-
- public ContentResolver(Context context)
- {
- mContext = context;
- }
-
- /** @hide */
- protected abstract IContentProvider acquireProvider(Context c, String name);
- /** @hide */
- public abstract boolean releaseProvider(IContentProvider icp);
-
- /**
- * Return the MIME type of the given content URL.
- *
- * @param url A Uri identifying content (either a list or specific type),
- * using the content:// scheme.
- * @return A MIME type for the content, or null if the URL is invalid or the type is unknown
- */
- public final String getType(Uri url)
- {
- IContentProvider provider = acquireProvider(url);
- if (provider == null) {
- return null;
- }
- try {
- return provider.getType(url);
- } catch (RemoteException e) {
- return null;
- } catch (java.lang.Exception e) {
- return null;
- } finally {
- releaseProvider(provider);
- }
- }
-
- /**
- * Query the given URI, returning a {@link Cursor} over the result set.
- *
- * @param uri The URI, using the content:// scheme, for the content to
- * retrieve.
- * @param projection A list of which columns to return. Passing null will
- * return all columns, which is discouraged to prevent reading data
- * from storage that isn't going to be used.
- * @param selection A filter declaring which rows to return, formatted as an
- * SQL WHERE clause (excluding the WHERE itself). Passing null will
- * return all rows for the given URI.
- * @param selectionArgs You may include ?s in selection, which will be
- * replaced by the values from selectionArgs, in the order that they
- * appear in the selection. The values will be bound as Strings.
- * @param sortOrder How to order the rows, formatted as an SQL ORDER BY
- * clause (excluding the ORDER BY itself). Passing null will use the
- * default sort order, which may be unordered.
- * @return A Cursor object, which is positioned before the first entry, or null
- * @see Cursor
- */
- public final Cursor query(Uri uri, String[] projection,
- String selection, String[] selectionArgs, String sortOrder) {
- IContentProvider provider = acquireProvider(uri);
- if (provider == null) {
- return null;
- }
- try {
- Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
- if(qCursor == null) {
- releaseProvider(provider);
- return null;
- }
- //Wrap the cursor object into CursorWrapperInner object
- return new CursorWrapperInner(qCursor, provider);
- } catch (RemoteException e) {
- releaseProvider(provider);
- return null;
- } catch(RuntimeException e) {
- releaseProvider(provider);
- throw e;
- }
- }
-
- /**
- * 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>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
- * Uri should be one of the following formats:
- * <ul>
- * <li><code>android.resource://package_name/id_number</code><br/>
- * <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
- * For example <code>com.example.myapp</code><br/>
- * <code>id_number</code> is the int form of the ID.<br/>
- * The easiest way to construct this form is
- * <pre>Uri uri = Uri.parse("android.resource://com.example.myapp/" + R.raw.my_resource");</pre>
- * </li>
- * <li><code>android.resource://package_name/type/name</code><br/>
- * <code>package_name</code> is your package name as listed in your AndroidManifest.xml.
- * For example <code>com.example.myapp</code><br/>
- * <code>type</code> is the string form of the resource type. For example, <code>raw</code>
- * or <code>drawable</code>.
- * <code>name</code> is the string form of the resource name. That is, whatever the file
- * name was in your res directory, without the type extension.
- * The easiest way to construct this form is
- * <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#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 ParcelFileDescriptor openFileDescriptor(Uri uri,
- String mode) throws FileNotFoundException {
- 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);
- 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;
- }
- }
-
- /**
- * Inserts a row into a table at the given URL.
- *
- * If the content provider supports transactions the insertion will be atomic.
- *
- * @param url The URL of the table to insert into.
- * @param values The initial values for the newly inserted row. The key is the column name for
- * the field. Passing an empty ContentValues will create an empty row.
- * @return the URL of the newly created row.
- */
- public final Uri insert(Uri url, ContentValues values)
- {
- IContentProvider provider = acquireProvider(url);
- if (provider == null) {
- throw new IllegalArgumentException("Unknown URL " + url);
- }
- try {
- return provider.insert(url, values);
- } catch (RemoteException e) {
- return null;
- } finally {
- releaseProvider(provider);
- }
- }
-
- /**
- * Inserts multiple rows into a table at the given URL.
- *
- * This function make no guarantees about the atomicity of the insertions.
- *
- * @param url The URL of the table to insert into.
- * @param values The initial values for the newly inserted rows. The key is the column name for
- * the field. Passing null will create an empty row.
- * @return the number of newly created rows.
- */
- public final int bulkInsert(Uri url, ContentValues[] values)
- {
- IContentProvider provider = acquireProvider(url);
- if (provider == null) {
- throw new IllegalArgumentException("Unknown URL " + url);
- }
- try {
- return provider.bulkInsert(url, values);
- } catch (RemoteException e) {
- return 0;
- } finally {
- releaseProvider(provider);
- }
- }
-
- /**
- * Deletes row(s) specified by a content URI.
- *
- * If the content provider supports transactions, the deletion will be atomic.
- *
- * @param url The URL of the row to delete.
- * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause
- (excluding the WHERE itself).
- * @return The number of rows deleted.
- */
- public final int delete(Uri url, String where, String[] selectionArgs)
- {
- IContentProvider provider = acquireProvider(url);
- if (provider == null) {
- throw new IllegalArgumentException("Unknown URL " + url);
- }
- try {
- return provider.delete(url, where, selectionArgs);
- } catch (RemoteException e) {
- return -1;
- } finally {
- releaseProvider(provider);
- }
- }
-
- /**
- * Update row(s) in a content URI.
- *
- * If the content provider supports transactions the update will be atomic.
- *
- * @param uri The URI to modify.
- * @param values The new field values. The key is the column name for the field.
- A null value will remove an existing field value.
- * @param where A filter to apply to rows before deleting, formatted as an SQL WHERE clause
- (excluding the WHERE itself).
- * @return the URL of the newly created row
- * @throws NullPointerException if uri or values are null
- */
- public final int update(Uri uri, ContentValues values, String where,
- String[] selectionArgs) {
- IContentProvider provider = acquireProvider(uri);
- if (provider == null) {
- throw new IllegalArgumentException("Unknown URI " + uri);
- }
- try {
- return provider.update(uri, values, where, selectionArgs);
- } catch (RemoteException e) {
- return -1;
- } finally {
- releaseProvider(provider);
- }
- }
-
- /**
- * Returns the content provider for the given content URI..
- *
- * @param uri The URI to a content provider
- * @return The ContentProvider for the given URI, or null if no content provider is found.
- * @hide
- */
- public final IContentProvider acquireProvider(Uri uri)
- {
- if (!SCHEME_CONTENT.equals(uri.getScheme())) {
- return null;
- }
- String auth = uri.getAuthority();
- if (auth != null) {
- return acquireProvider(mContext, uri.getAuthority());
- }
- return null;
- }
-
- /**
- * @hide
- */
- public final IContentProvider acquireProvider(String name) {
- if(name == null) {
- return null;
- }
- return acquireProvider(mContext, name);
- }
-
- /**
- * Register an observer class that gets callbacks when data identified by a
- * given content URI changes.
- *
- * @param uri The URI to watch for changes. This can be a specific row URI, or a base URI
- * for a whole class of content.
- * @param notifyForDescendents If <code>true</code> changes to URIs beginning with <code>uri</code>
- * will also cause notifications to be sent. If <code>false</code> only changes to the exact URI
- * specified by <em>uri</em> will cause notifications to be sent. If true, than any URI values
- * at or below the specified URI will also trigger a match.
- * @param observer The object that receives callbacks when changes occur.
- * @see #unregisterContentObserver
- */
- public final void registerContentObserver(Uri uri, boolean notifyForDescendents,
- ContentObserver observer)
- {
- try {
- ContentServiceNative.getDefault().registerContentObserver(uri, notifyForDescendents,
- observer.getContentObserver());
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Unregisters a change observer.
- *
- * @param observer The previously registered observer that is no longer needed.
- * @see #registerContentObserver
- */
- public final void unregisterContentObserver(ContentObserver observer) {
- try {
- IContentObserver contentObserver = observer.releaseContentObserver();
- if (contentObserver != null) {
- ContentServiceNative.getDefault().unregisterContentObserver(
- contentObserver);
- }
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Notify registered observers that a row was updated.
- * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}.
- * By default, CursorAdapter objects will get this notification.
- *
- * @param uri
- * @param observer The observer that originated the change, may be <code>null</null>
- */
- public void notifyChange(Uri uri, ContentObserver observer) {
- notifyChange(uri, observer, true /* sync to network */);
- }
-
- /**
- * Notify registered observers that a row was updated.
- * To register, call {@link #registerContentObserver(android.net.Uri , boolean, android.database.ContentObserver) registerContentObserver()}.
- * By default, CursorAdapter objects will get this notification.
- *
- * @param uri
- * @param observer The observer that originated the change, may be <code>null</null>
- * @param syncToNetwork If true, attempt to sync the change to the network.
- */
- public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
- try {
- ContentServiceNative.getDefault().notifyChange(
- uri, observer == null ? null : observer.getContentObserver(),
- observer != null && observer.deliverSelfNotifications(), syncToNetwork);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Start an asynchronous sync operation. If you want to monitor the progress
- * of the sync you may register a SyncObserver. Only values of the following
- * types may be used in the extras bundle:
- * <ul>
- * <li>Integer</li>
- * <li>Long</li>
- * <li>Boolean</li>
- * <li>Float</li>
- * <li>Double</li>
- * <li>String</li>
- * </ul>
- *
- * @param uri the uri of the provider to sync or null to sync all providers.
- * @param extras any extras to pass to the SyncAdapter.
- */
- public void startSync(Uri uri, Bundle extras) {
- validateSyncExtrasBundle(extras);
- try {
- ContentServiceNative.getDefault().startSync(uri, extras);
- } catch (RemoteException e) {
- }
- }
-
- /**
- * Check that only values of the following types are in the Bundle:
- * <ul>
- * <li>Integer</li>
- * <li>Long</li>
- * <li>Boolean</li>
- * <li>Float</li>
- * <li>Double</li>
- * <li>String</li>
- * <li>null</li>
- * </ul>
- * @param extras the Bundle to check
- */
- public static void validateSyncExtrasBundle(Bundle extras) {
- try {
- for (String key : extras.keySet()) {
- Object value = extras.get(key);
- if (value == null) continue;
- if (value instanceof Long) continue;
- if (value instanceof Integer) continue;
- if (value instanceof Boolean) continue;
- if (value instanceof Float) continue;
- if (value instanceof Double) continue;
- if (value instanceof String) continue;
- throw new IllegalArgumentException("unexpected value type: "
- + value.getClass().getName());
- }
- } catch (IllegalArgumentException e) {
- throw e;
- } catch (RuntimeException exc) {
- throw new IllegalArgumentException("error unparceling Bundle", exc);
- }
- }
-
- public void cancelSync(Uri uri) {
- try {
- ContentServiceNative.getDefault().cancelSync(uri);
- } catch (RemoteException e) {
- }
- }
-
- private final class CursorWrapperInner extends CursorWrapper {
- private IContentProvider mContentProvider;
- public static final String TAG="CursorWrapperInner";
- private boolean mCloseFlag = false;
-
- CursorWrapperInner(Cursor cursor, IContentProvider icp) {
- super(cursor);
- mContentProvider = icp;
- }
-
- @Override
- public void close() {
- super.close();
- ContentResolver.this.releaseProvider(mContentProvider);
- mCloseFlag = true;
- }
-
- @Override
- protected void finalize() throws Throwable {
- try {
- if(!mCloseFlag) {
- ContentResolver.this.releaseProvider(mContentProvider);
- }
- } finally {
- super.finalize();
- }
- }
- }
-
- private final class ParcelFileDescriptorInner extends ParcelFileDescriptor {
- private IContentProvider mContentProvider;
- public static final String TAG="ParcelFileDescriptorInner";
- private boolean mReleaseProviderFlag = false;
-
- ParcelFileDescriptorInner(ParcelFileDescriptor pfd, IContentProvider icp) {
- super(pfd);
- mContentProvider = icp;
- }
-
- @Override
- public void close() throws IOException {
- if(!mReleaseProviderFlag) {
- super.close();
- ContentResolver.this.releaseProvider(mContentProvider);
- mReleaseProviderFlag = true;
- }
- }
-
- @Override
- protected void finalize() throws Throwable {
- if (!mReleaseProviderFlag) {
- close();
- }
- }
- }
-
- private final Context mContext;
- private static final String TAG = "ContentResolver";
-}
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java
deleted file mode 100644
index b028868..0000000
--- a/core/java/android/content/ContentService.java
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.IContentObserver;
-import android.database.sqlite.SQLiteException;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Config;
-import android.util.Log;
-import android.Manifest;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-
-/**
- * {@hide}
- */
-public final class ContentService extends ContentServiceNative {
- private static final String TAG = "ContentService";
- private Context mContext;
- private boolean mFactoryTest;
- private final ObserverNode mRootNode = new ObserverNode("");
- private SyncManager mSyncManager = null;
- private final Object mSyncManagerLock = new Object();
-
- private SyncManager getSyncManager() {
- synchronized(mSyncManagerLock) {
- try {
- // Try to create the SyncManager, return null if it fails (e.g. the disk is full).
- if (mSyncManager == null) mSyncManager = new SyncManager(mContext, mFactoryTest);
- } catch (SQLiteException e) {
- Log.e(TAG, "Can't create SyncManager", e);
- }
- return mSyncManager;
- }
- }
-
- @Override
- protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.DUMP,
- "caller doesn't have the DUMP permission");
-
- // This makes it so that future permission checks will be in the context of this
- // process rather than the caller's process. We will restore this before returning.
- long identityToken = clearCallingIdentity();
- try {
- if (mSyncManager == null) {
- pw.println("No SyncManager created! (Disk full?)");
- } else {
- mSyncManager.dump(fd, pw);
- }
- } finally {
- restoreCallingIdentity(identityToken);
- }
- }
-
- /*package*/ ContentService(Context context, boolean factoryTest) {
- mContext = context;
- mFactoryTest = factoryTest;
- getSyncManager();
- }
-
- public void registerContentObserver(Uri uri, boolean notifyForDescendents,
- IContentObserver observer) {
- if (observer == null || uri == null) {
- throw new IllegalArgumentException("You must pass a valid uri and observer");
- }
- synchronized (mRootNode) {
- mRootNode.addObserver(uri, observer, notifyForDescendents);
- if (Config.LOGV) Log.v(TAG, "Registered observer " + observer + " at " + uri +
- " with notifyForDescendents " + notifyForDescendents);
- }
- }
-
- public void unregisterContentObserver(IContentObserver observer) {
- if (observer == null) {
- throw new IllegalArgumentException("You must pass a valid observer");
- }
- synchronized (mRootNode) {
- mRootNode.removeObserver(observer);
- if (Config.LOGV) Log.v(TAG, "Unregistered observer " + observer);
- }
- }
-
- public void notifyChange(Uri uri, IContentObserver observer,
- boolean observerWantsSelfNotifications, boolean syncToNetwork) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Notifying update of " + uri + " from observer " + observer
- + ", syncToNetwork " + syncToNetwork);
- }
- // This makes it so that future permission checks will be in the context of this
- // process rather than the caller's process. We will restore this before returning.
- long identityToken = clearCallingIdentity();
- try {
- ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>();
- synchronized (mRootNode) {
- mRootNode.collectObservers(uri, 0, observer, observerWantsSelfNotifications,
- calls);
- }
- final int numCalls = calls.size();
- for (int i=0; i<numCalls; i++) {
- ObserverCall oc = calls.get(i);
- try {
- oc.mObserver.onChange(oc.mSelfNotify);
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Notified " + oc.mObserver + " of " + "update at " + uri);
- }
- } catch (RemoteException ex) {
- synchronized (mRootNode) {
- Log.w(TAG, "Found dead observer, removing");
- IBinder binder = oc.mObserver.asBinder();
- final ArrayList<ObserverNode.ObserverEntry> list
- = oc.mNode.mObservers;
- int numList = list.size();
- for (int j=0; j<numList; j++) {
- ObserverNode.ObserverEntry oe = list.get(j);
- if (oe.observer.asBinder() == binder) {
- list.remove(j);
- j--;
- numList--;
- }
- }
- }
- }
- }
- if (syncToNetwork) {
- SyncManager syncManager = getSyncManager();
- if (syncManager != null) syncManager.scheduleLocalSync(uri);
- }
- } finally {
- restoreCallingIdentity(identityToken);
- }
- }
-
- /**
- * Hide this class since it is not part of api,
- * but current unittest framework requires it to be public
- * @hide
- *
- */
- public static final class ObserverCall {
- final ObserverNode mNode;
- final IContentObserver mObserver;
- final boolean mSelfNotify;
-
- ObserverCall(ObserverNode node, IContentObserver observer,
- boolean selfNotify) {
- mNode = node;
- mObserver = observer;
- mSelfNotify = selfNotify;
- }
- }
-
- public void startSync(Uri url, Bundle extras) {
- ContentResolver.validateSyncExtrasBundle(extras);
- // This makes it so that future permission checks will be in the context of this
- // process rather than the caller's process. We will restore this before returning.
- long identityToken = clearCallingIdentity();
- try {
- SyncManager syncManager = getSyncManager();
- if (syncManager != null) syncManager.startSync(url, extras);
- } finally {
- restoreCallingIdentity(identityToken);
- }
- }
-
- /**
- * Clear all scheduled sync operations that match the uri and cancel the active sync
- * if it matches the uri. If the uri is null, clear all scheduled syncs and cancel
- * the active one, if there is one.
- * @param uri Filter on the sync operations to cancel, or all if null.
- */
- public void cancelSync(Uri uri) {
- // This makes it so that future permission checks will be in the context of this
- // process rather than the caller's process. We will restore this before returning.
- long identityToken = clearCallingIdentity();
- try {
- SyncManager syncManager = getSyncManager();
- if (syncManager != null) {
- syncManager.clearScheduledSyncOperations(uri);
- syncManager.cancelActiveSync(uri);
- }
- } finally {
- restoreCallingIdentity(identityToken);
- }
- }
-
- public static IContentService main(Context context, boolean factoryTest) {
- ContentService service = new ContentService(context, factoryTest);
- ServiceManager.addService("content", service);
- return service;
- }
-
- /**
- * Hide this class since it is not part of api,
- * but current unittest framework requires it to be public
- * @hide
- */
- public static final class ObserverNode {
- private class ObserverEntry implements IBinder.DeathRecipient {
- public IContentObserver observer;
- public boolean notifyForDescendents;
-
- public ObserverEntry(IContentObserver o, boolean n) {
- observer = o;
- notifyForDescendents = n;
- try {
- observer.asBinder().linkToDeath(this, 0);
- } catch (RemoteException e) {
- binderDied();
- }
- }
-
- public void binderDied() {
- removeObserver(observer);
- }
- }
-
- public static final int INSERT_TYPE = 0;
- public static final int UPDATE_TYPE = 1;
- public static final int DELETE_TYPE = 2;
-
- private String mName;
- private ArrayList<ObserverNode> mChildren = new ArrayList<ObserverNode>();
- private ArrayList<ObserverEntry> mObservers = new ArrayList<ObserverEntry>();
-
- public ObserverNode(String name) {
- mName = name;
- }
-
- private String getUriSegment(Uri uri, int index) {
- if (uri != null) {
- if (index == 0) {
- return uri.getAuthority();
- } else {
- return uri.getPathSegments().get(index - 1);
- }
- } else {
- return null;
- }
- }
-
- private int countUriSegments(Uri uri) {
- if (uri == null) {
- return 0;
- }
- return uri.getPathSegments().size() + 1;
- }
-
- public void addObserver(Uri uri, IContentObserver observer, boolean notifyForDescendents) {
- addObserver(uri, 0, observer, notifyForDescendents);
- }
-
- private void addObserver(Uri uri, int index, IContentObserver observer,
- boolean notifyForDescendents) {
-
- // If this is the leaf node add the observer
- if (index == countUriSegments(uri)) {
- mObservers.add(new ObserverEntry(observer, notifyForDescendents));
- return;
- }
-
- // Look to see if the proper child already exists
- String segment = getUriSegment(uri, index);
- int N = mChildren.size();
- for (int i = 0; i < N; i++) {
- ObserverNode node = mChildren.get(i);
- if (node.mName.equals(segment)) {
- node.addObserver(uri, index + 1, observer, notifyForDescendents);
- return;
- }
- }
-
- // No child found, create one
- ObserverNode node = new ObserverNode(segment);
- mChildren.add(node);
- node.addObserver(uri, index + 1, observer, notifyForDescendents);
- }
-
- public boolean removeObserver(IContentObserver observer) {
- int size = mChildren.size();
- for (int i = 0; i < size; i++) {
- boolean empty = mChildren.get(i).removeObserver(observer);
- if (empty) {
- mChildren.remove(i);
- i--;
- size--;
- }
- }
-
- IBinder observerBinder = observer.asBinder();
- size = mObservers.size();
- for (int i = 0; i < size; i++) {
- ObserverEntry entry = mObservers.get(i);
- if (entry.observer.asBinder() == observerBinder) {
- mObservers.remove(i);
- // We no longer need to listen for death notifications. Remove it.
- observerBinder.unlinkToDeath(entry, 0);
- break;
- }
- }
-
- if (mChildren.size() == 0 && mObservers.size() == 0) {
- return true;
- }
- return false;
- }
-
- private void collectMyObservers(Uri uri,
- boolean leaf, IContentObserver observer, boolean selfNotify,
- ArrayList<ObserverCall> calls)
- {
- int N = mObservers.size();
- IBinder observerBinder = observer == null ? null : observer.asBinder();
- for (int i = 0; i < N; i++) {
- ObserverEntry entry = mObservers.get(i);
-
- // Don't notify the observer if it sent the notification and isn't interesed
- // in self notifications
- if (entry.observer.asBinder() == observerBinder && !selfNotify) {
- continue;
- }
-
- // Make sure the observer is interested in the notification
- if (leaf || (!leaf && entry.notifyForDescendents)) {
- calls.add(new ObserverCall(this, entry.observer, selfNotify));
- }
- }
- }
-
- public void collectObservers(Uri uri, int index, IContentObserver observer,
- boolean selfNotify, ArrayList<ObserverCall> calls) {
- String segment = null;
- int segmentCount = countUriSegments(uri);
- if (index >= segmentCount) {
- // This is the leaf node, notify all observers
- collectMyObservers(uri, true, observer, selfNotify, calls);
- } else if (index < segmentCount){
- segment = getUriSegment(uri, index);
- // Notify any observers at this level who are interested in descendents
- collectMyObservers(uri, false, observer, selfNotify, calls);
- }
-
- int N = mChildren.size();
- for (int i = 0; i < N; i++) {
- ObserverNode node = mChildren.get(i);
- if (segment == null || node.mName.equals(segment)) {
- // We found the child,
- node.collectObservers(uri, index + 1, observer, selfNotify, calls);
- if (segment != null) {
- break;
- }
- }
- }
- }
- }
-}
diff --git a/core/java/android/content/ContentServiceNative.java b/core/java/android/content/ContentServiceNative.java
deleted file mode 100644
index f050501..0000000
--- a/core/java/android/content/ContentServiceNative.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.IContentObserver;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.ServiceManager;
-import android.os.Bundle;
-import android.util.Config;
-import android.util.Log;
-
-/**
- * {@hide}
- */
-abstract class ContentServiceNative extends Binder implements IContentService
-{
- public ContentServiceNative()
- {
- attachInterface(this, descriptor);
- }
-
- /**
- * Cast a Binder object into a content resolver interface, generating
- * a proxy if needed.
- */
- static public IContentService asInterface(IBinder obj)
- {
- if (obj == null) {
- return null;
- }
- IContentService in =
- (IContentService)obj.queryLocalInterface(descriptor);
- if (in != null) {
- return in;
- }
-
- return new ContentServiceProxy(obj);
- }
-
- /**
- * Retrieve the system's default/global content service.
- */
- static public IContentService getDefault()
- {
- if (gDefault != null) {
- return gDefault;
- }
- IBinder b = ServiceManager.getService("content");
- if (Config.LOGV) Log.v("ContentService", "default service binder = " + b);
- gDefault = asInterface(b);
- if (Config.LOGV) Log.v("ContentService", "default service = " + gDefault);
- return gDefault;
- }
-
- @Override
- public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
- {
- try {
- switch (code) {
- case REGISTER_CONTENT_OBSERVER_TRANSACTION: {
- Uri uri = Uri.CREATOR.createFromParcel(data);
- boolean notifyForDescendents = data.readInt() != 0;
- IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder());
- registerContentObserver(uri, notifyForDescendents, observer);
- return true;
- }
-
- case UNREGISTER_CHANGE_OBSERVER_TRANSACTION: {
- IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder());
- unregisterContentObserver(observer);
- return true;
- }
-
- case NOTIFY_CHANGE_TRANSACTION: {
- Uri uri = Uri.CREATOR.createFromParcel(data);
- IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder());
- boolean observerWantsSelfNotifications = data.readInt() != 0;
- boolean syncToNetwork = data.readInt() != 0;
- notifyChange(uri, observer, observerWantsSelfNotifications, syncToNetwork);
- return true;
- }
-
- case START_SYNC_TRANSACTION: {
- Uri url = null;
- int hasUrl = data.readInt();
- if (hasUrl != 0) {
- url = Uri.CREATOR.createFromParcel(data);
- }
- startSync(url, data.readBundle());
- return true;
- }
-
- case CANCEL_SYNC_TRANSACTION: {
- Uri url = null;
- int hasUrl = data.readInt();
- if (hasUrl != 0) {
- url = Uri.CREATOR.createFromParcel(data);
- }
- cancelSync(url);
- return true;
- }
-
- default:
- return super.onTransact(code, data, reply, flags);
- }
- } catch (Exception e) {
- Log.e("ContentServiceNative", "Caught exception in transact", e);
- }
-
- return false;
- }
-
- public IBinder asBinder()
- {
- return this;
- }
-
- private static IContentService gDefault;
-}
-
-
-final class ContentServiceProxy implements IContentService
-{
- public ContentServiceProxy(IBinder remote)
- {
- mRemote = remote;
- }
-
- public IBinder asBinder()
- {
- return mRemote;
- }
-
- public void registerContentObserver(Uri uri, boolean notifyForDescendents,
- IContentObserver observer) throws RemoteException
- {
- Parcel data = Parcel.obtain();
- uri.writeToParcel(data, 0);
- data.writeInt(notifyForDescendents ? 1 : 0);
- data.writeStrongInterface(observer);
- mRemote.transact(REGISTER_CONTENT_OBSERVER_TRANSACTION, data, null, 0);
- data.recycle();
- }
-
- public void unregisterContentObserver(IContentObserver observer) throws RemoteException {
- Parcel data = Parcel.obtain();
- data.writeStrongInterface(observer);
- mRemote.transact(UNREGISTER_CHANGE_OBSERVER_TRANSACTION, data, null, 0);
- data.recycle();
- }
-
- public void notifyChange(Uri uri, IContentObserver observer,
- boolean observerWantsSelfNotifications, boolean syncToNetwork)
- throws RemoteException {
- Parcel data = Parcel.obtain();
- uri.writeToParcel(data, 0);
- data.writeStrongInterface(observer);
- data.writeInt(observerWantsSelfNotifications ? 1 : 0);
- data.writeInt(syncToNetwork ? 1 : 0);
- mRemote.transact(NOTIFY_CHANGE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
- data.recycle();
- }
-
- public void startSync(Uri url, Bundle extras) throws RemoteException {
- Parcel data = Parcel.obtain();
- if (url == null) {
- data.writeInt(0);
- } else {
- data.writeInt(1);
- url.writeToParcel(data, 0);
- }
- extras.writeToParcel(data, 0);
- mRemote.transact(START_SYNC_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
- data.recycle();
- }
-
- public void cancelSync(Uri url) throws RemoteException {
- Parcel data = Parcel.obtain();
- if (url == null) {
- data.writeInt(0);
- } else {
- data.writeInt(1);
- url.writeToParcel(data, 0);
- }
- mRemote.transact(CANCEL_SYNC_TRANSACTION, data, null /* reply */, IBinder.FLAG_ONEWAY);
- data.recycle();
- }
-
- private IBinder mRemote;
-}
-
diff --git a/core/java/android/content/ContentUris.java b/core/java/android/content/ContentUris.java
deleted file mode 100644
index aa76034..0000000
--- a/core/java/android/content/ContentUris.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.net.Uri;
-
-/**
- * Utility methods useful for working with content {@link android.net.Uri}s,
- * those with a "content" scheme.
- */
-public class ContentUris {
-
- /**
- * Converts the last path segment to a long.
- *
- * <p>This supports a common convention for content URIs where an ID is
- * stored in the last segment.
- *
- * @throws UnsupportedOperationException if this isn't a hierarchical URI
- * @throws NumberFormatException if the last segment isn't a number
- *
- * @return the long conversion of the last segment or -1 if the path is
- * empty
- */
- public static long parseId(Uri contentUri) {
- String last = contentUri.getLastPathSegment();
- return last == null ? -1 : Long.parseLong(last);
- }
-
- /**
- * Appends the given ID to the end of the path.
- *
- * @param builder to append the ID to
- * @param id to append
- *
- * @return the given builder
- */
- public static Uri.Builder appendId(Uri.Builder builder, long id) {
- return builder.appendEncodedPath(String.valueOf(id));
- }
-
- /**
- * Appends the given ID to the end of the path.
- *
- * @param contentUri to start with
- * @param id to append
- *
- * @return a new URI with the given ID appended to the end of the path
- */
- public static Uri withAppendedId(Uri contentUri, long id) {
- return appendId(contentUri.buildUpon(), id).build();
- }
-}
diff --git a/core/java/android/content/ContentValues.java b/core/java/android/content/ContentValues.java
deleted file mode 100644
index 532cc03..0000000
--- a/core/java/android/content/ContentValues.java
+++ /dev/null
@@ -1,501 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * This class is used to store a set of values that the {@link ContentResolver}
- * can process.
- */
-public final class ContentValues implements Parcelable {
- public static final String TAG = "ContentValues";
-
- /** Holds the actual values */
- private HashMap<String, Object> mValues;
-
- /**
- * Creates an empty set of values using the default initial size
- */
- public ContentValues() {
- // Choosing a default size of 8 based on analysis of typical
- // consumption by applications.
- mValues = new HashMap<String, Object>(8);
- }
-
- /**
- * Creates an empty set of values using the given initial size
- *
- * @param size the initial size of the set of values
- */
- public ContentValues(int size) {
- mValues = new HashMap<String, Object>(size, 1.0f);
- }
-
- /**
- * Creates a set of values copied from the given set
- *
- * @param from the values to copy
- */
- public ContentValues(ContentValues from) {
- mValues = new HashMap<String, Object>(from.mValues);
- }
-
- /**
- * Creates a set of values copied from the given HashMap. This is used
- * by the Parcel unmarshalling code.
- *
- * @param from the values to start with
- * {@hide}
- */
- private ContentValues(HashMap<String, Object> values) {
- mValues = values;
- }
-
- @Override
- public boolean equals(Object object) {
- if (!(object instanceof ContentValues)) {
- return false;
- }
- return mValues.equals(((ContentValues) object).mValues);
- }
-
- @Override
- public int hashCode() {
- return mValues.hashCode();
- }
-
- /**
- * Adds a value to the set.
- *
- * @param key the name of the value to put
- * @param value the data for the value to put
- */
- public void put(String key, String value) {
- mValues.put(key, value);
- }
-
- /**
- * Adds all values from the passed in ContentValues.
- *
- * @param other the ContentValues from which to copy
- */
- public void putAll(ContentValues other) {
- mValues.putAll(other.mValues);
- }
-
- /**
- * Adds a value to the set.
- *
- * @param key the name of the value to put
- * @param value the data for the value to put
- */
- public void put(String key, Byte value) {
- mValues.put(key, value);
- }
-
- /**
- * Adds a value to the set.
- *
- * @param key the name of the value to put
- * @param value the data for the value to put
- */
- public void put(String key, Short value) {
- mValues.put(key, value);
- }
-
- /**
- * Adds a value to the set.
- *
- * @param key the name of the value to put
- * @param value the data for the value to put
- */
- public void put(String key, Integer value) {
- mValues.put(key, value);
- }
-
- /**
- * Adds a value to the set.
- *
- * @param key the name of the value to put
- * @param value the data for the value to put
- */
- public void put(String key, Long value) {
- mValues.put(key, value);
- }
-
- /**
- * Adds a value to the set.
- *
- * @param key the name of the value to put
- * @param value the data for the value to put
- */
- public void put(String key, Float value) {
- mValues.put(key, value);
- }
-
- /**
- * Adds a value to the set.
- *
- * @param key the name of the value to put
- * @param value the data for the value to put
- */
- public void put(String key, Double value) {
- mValues.put(key, value);
- }
-
- /**
- * Adds a value to the set.
- *
- * @param key the name of the value to put
- * @param value the data for the value to put
- */
- public void put(String key, Boolean value) {
- mValues.put(key, value);
- }
-
- /**
- * Adds a value to the set.
- *
- * @param key the name of the value to put
- * @param value the data for the value to put
- */
- public void put(String key, byte[] value) {
- mValues.put(key, value);
- }
-
- /**
- * Adds a null value to the set.
- *
- * @param key the name of the value to make null
- */
- public void putNull(String key) {
- mValues.put(key, null);
- }
-
- /**
- * Returns the number of values.
- *
- * @return the number of values
- */
- public int size() {
- return mValues.size();
- }
-
- /**
- * Remove a single value.
- *
- * @param key the name of the value to remove
- */
- public void remove(String key) {
- mValues.remove(key);
- }
-
- /**
- * Removes all values.
- */
- public void clear() {
- mValues.clear();
- }
-
- /**
- * Returns true if this object has the named value.
- *
- * @param key the value to check for
- * @return {@code true} if the value is present, {@code false} otherwise
- */
- public boolean containsKey(String key) {
- return mValues.containsKey(key);
- }
-
- /**
- * Gets a value. Valid value types are {@link String}, {@link Boolean}, and
- * {@link Number} implementations.
- *
- * @param key the value to get
- * @return the data for the value
- */
- public Object get(String key) {
- return mValues.get(key);
- }
-
- /**
- * Gets a value and converts it to a String.
- *
- * @param key the value to get
- * @return the String for the value
- */
- public String getAsString(String key) {
- Object value = mValues.get(key);
- return value != null ? mValues.get(key).toString() : null;
- }
-
- /**
- * Gets a value and converts it to a Long.
- *
- * @param key the value to get
- * @return the Long value, or null if the value is missing or cannot be converted
- */
- public Long getAsLong(String key) {
- Object value = mValues.get(key);
- try {
- return value != null ? ((Number) value).longValue() : null;
- } catch (ClassCastException e) {
- if (value instanceof CharSequence) {
- try {
- return Long.valueOf(value.toString());
- } catch (NumberFormatException e2) {
- Log.e(TAG, "Cannot parse Long value for " + value + " at key " + key);
- return null;
- }
- } else {
- Log.e(TAG, "Cannot cast value for " + key + " to a Long");
- return null;
- }
- }
- }
-
- /**
- * Gets a value and converts it to an Integer.
- *
- * @param key the value to get
- * @return the Integer value, or null if the value is missing or cannot be converted
- */
- public Integer getAsInteger(String key) {
- Object value = mValues.get(key);
- try {
- return value != null ? ((Number) value).intValue() : null;
- } catch (ClassCastException e) {
- if (value instanceof CharSequence) {
- try {
- return Integer.valueOf(value.toString());
- } catch (NumberFormatException e2) {
- Log.e(TAG, "Cannot parse Integer value for " + value + " at key " + key);
- return null;
- }
- } else {
- Log.e(TAG, "Cannot cast value for " + key + " to a Integer");
- return null;
- }
- }
- }
-
- /**
- * Gets a value and converts it to a Short.
- *
- * @param key the value to get
- * @return the Short value, or null if the value is missing or cannot be converted
- */
- public Short getAsShort(String key) {
- Object value = mValues.get(key);
- try {
- return value != null ? ((Number) value).shortValue() : null;
- } catch (ClassCastException e) {
- if (value instanceof CharSequence) {
- try {
- return Short.valueOf(value.toString());
- } catch (NumberFormatException e2) {
- Log.e(TAG, "Cannot parse Short value for " + value + " at key " + key);
- return null;
- }
- } else {
- Log.e(TAG, "Cannot cast value for " + key + " to a Short");
- return null;
- }
- }
- }
-
- /**
- * Gets a value and converts it to a Byte.
- *
- * @param key the value to get
- * @return the Byte value, or null if the value is missing or cannot be converted
- */
- public Byte getAsByte(String key) {
- Object value = mValues.get(key);
- try {
- return value != null ? ((Number) value).byteValue() : null;
- } catch (ClassCastException e) {
- if (value instanceof CharSequence) {
- try {
- return Byte.valueOf(value.toString());
- } catch (NumberFormatException e2) {
- Log.e(TAG, "Cannot parse Byte value for " + value + " at key " + key);
- return null;
- }
- } else {
- Log.e(TAG, "Cannot cast value for " + key + " to a Byte");
- return null;
- }
- }
- }
-
- /**
- * Gets a value and converts it to a Double.
- *
- * @param key the value to get
- * @return the Double value, or null if the value is missing or cannot be converted
- */
- public Double getAsDouble(String key) {
- Object value = mValues.get(key);
- try {
- return value != null ? ((Number) value).doubleValue() : null;
- } catch (ClassCastException e) {
- if (value instanceof CharSequence) {
- try {
- return Double.valueOf(value.toString());
- } catch (NumberFormatException e2) {
- Log.e(TAG, "Cannot parse Double value for " + value + " at key " + key);
- return null;
- }
- } else {
- Log.e(TAG, "Cannot cast value for " + key + " to a Double");
- return null;
- }
- }
- }
-
- /**
- * Gets a value and converts it to a Float.
- *
- * @param key the value to get
- * @return the Float value, or null if the value is missing or cannot be converted
- */
- public Float getAsFloat(String key) {
- Object value = mValues.get(key);
- try {
- return value != null ? ((Number) value).floatValue() : null;
- } catch (ClassCastException e) {
- if (value instanceof CharSequence) {
- try {
- return Float.valueOf(value.toString());
- } catch (NumberFormatException e2) {
- Log.e(TAG, "Cannot parse Float value for " + value + " at key " + key);
- return null;
- }
- } else {
- Log.e(TAG, "Cannot cast value for " + key + " to a Float");
- return null;
- }
- }
- }
-
- /**
- * Gets a value and converts it to a Boolean.
- *
- * @param key the value to get
- * @return the Boolean value, or null if the value is missing or cannot be converted
- */
- public Boolean getAsBoolean(String key) {
- Object value = mValues.get(key);
- try {
- return (Boolean) value;
- } catch (ClassCastException e) {
- if (value instanceof CharSequence) {
- return Boolean.valueOf(value.toString());
- } else {
- Log.e(TAG, "Cannot cast value for " + key + " to a Boolean");
- return null;
- }
- }
- }
-
- /**
- * Gets a value that is a byte array. Note that this method will not convert
- * any other types to byte arrays.
- *
- * @param key the value to get
- * @return the byte[] value, or null is the value is missing or not a byte[]
- */
- public byte[] getAsByteArray(String key) {
- Object value = mValues.get(key);
- if (value instanceof byte[]) {
- return (byte[]) value;
- } else {
- return null;
- }
- }
-
- /**
- * Returns a set of all of the keys and values
- *
- * @return a set of all of the keys and values
- */
- public Set<Map.Entry<String, Object>> valueSet() {
- return mValues.entrySet();
- }
-
- public static final Parcelable.Creator<ContentValues> CREATOR =
- new Parcelable.Creator<ContentValues>() {
- @SuppressWarnings({"deprecation", "unchecked"})
- public ContentValues createFromParcel(Parcel in) {
- // TODO - what ClassLoader should be passed to readHashMap?
- HashMap<String, Object> values = in.readHashMap(null);
- return new ContentValues(values);
- }
-
- public ContentValues[] newArray(int size) {
- return new ContentValues[size];
- }
- };
-
- public int describeContents() {
- return 0;
- }
-
- @SuppressWarnings("deprecation")
- public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeMap(mValues);
- }
-
- /**
- * Unsupported, here until we get proper bulk insert APIs.
- * {@hide}
- */
- @Deprecated
- public void putStringArrayList(String key, ArrayList<String> value) {
- mValues.put(key, value);
- }
-
- /**
- * Unsupported, here until we get proper bulk insert APIs.
- * {@hide}
- */
- @SuppressWarnings("unchecked")
- @Deprecated
- public ArrayList<String> getStringArrayList(String key) {
- return (ArrayList<String>) mValues.get(key);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- for (String name : mValues.keySet()) {
- String value = getAsString(name);
- if (sb.length() > 0) sb.append(" ");
- sb.append(name + "=" + value);
- }
- return sb.toString();
- }
-}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
deleted file mode 100644
index e0fe533..0000000
--- a/core/java/android/content/Context.java
+++ /dev/null
@@ -1,1654 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.AttributeSet;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Interface to global information about an application environment. This is
- * an abstract class whose implementation is provided by
- * the Android system. It
- * allows access to application-specific resources and classes, as well as
- * up-calls for application-level operations such as launching activities,
- * broadcasting and receiving intents, etc.
- */
-public abstract class Context {
- /**
- * File creation mode: the default mode, where the created file can only
- * be accessed by the calling application (or all applications sharing the
- * same user ID).
- * @see #MODE_WORLD_READABLE
- * @see #MODE_WORLD_WRITEABLE
- */
- public static final int MODE_PRIVATE = 0x0000;
- /**
- * File creation mode: allow all other applications to have read access
- * to the created file.
- * @see #MODE_PRIVATE
- * @see #MODE_WORLD_WRITEABLE
- */
- public static final int MODE_WORLD_READABLE = 0x0001;
- /**
- * File creation mode: allow all other applications to have write access
- * to the created file.
- * @see #MODE_PRIVATE
- * @see #MODE_WORLD_READABLE
- */
- public static final int MODE_WORLD_WRITEABLE = 0x0002;
- /**
- * File creation mode: for use with {@link #openFileOutput}, if the file
- * already exists then write data to the end of the existing file
- * instead of erasing it.
- * @see #openFileOutput
- */
- public static final int MODE_APPEND = 0x8000;
-
- /**
- * Flag for {@link #bindService}: automatically create the service as long
- * as the binding exists. Note that while this will create the service,
- * its {@link android.app.Service#onStart} method will still only be called due to an
- * explicit call to {@link #startService}. Even without that, though,
- * this still provides you with access to the service object while the
- * service is created.
- *
- * <p>Specifying this flag also tells the system to treat the service
- * as being as important as your own process -- that is, when deciding
- * which process should be killed to free memory, the service will only
- * be considered a candidate as long as the processes of any such bindings
- * is also a candidate to be killed. This is to avoid situations where
- * the service is being continually created and killed due to low memory.
- */
- public static final int BIND_AUTO_CREATE = 0x0001;
-
- /**
- * Flag for {@link #bindService}: include debugging help for mismatched
- * calls to unbind. When this flag is set, the callstack of the following
- * {@link #unbindService} call is retained, to be printed if a later
- * incorrect unbind call is made. Note that doing this requires retaining
- * information about the binding that was made for the lifetime of the app,
- * resulting in a leak -- this should only be used for debugging.
- */
- public static final int BIND_DEBUG_UNBIND = 0x0002;
-
- /** Return an AssetManager instance for your application's package. */
- public abstract AssetManager getAssets();
-
- /** Return a Resources instance for your application's package. */
- public abstract Resources getResources();
-
- /** Return PackageManager instance to find global package information. */
- public abstract PackageManager getPackageManager();
-
- /** Return a ContentResolver instance for your application's package. */
- public abstract ContentResolver getContentResolver();
-
- /**
- * Return the Looper for the main thread of the current process. This is
- * the thread used to dispatch calls to application components (activities,
- * services, etc).
- */
- public abstract Looper getMainLooper();
-
- /**
- * Return the context of the single, global Application object of the
- * current process.
- */
- public abstract Context getApplicationContext();
-
- /**
- * Return a localized, styled CharSequence from the application's package's
- * default string table.
- *
- * @param resId Resource id for the CharSequence text
- */
- public final CharSequence getText(int resId) {
- return getResources().getText(resId);
- }
-
- /**
- * Return a localized string from the application's package's
- * default string table.
- *
- * @param resId Resource id for the string
- */
- public final String getString(int resId) {
- return getResources().getString(resId);
- }
-
- /**
- * Return a localized formatted string from the application's package's
- * default string table, substituting the format arguments as defined in
- * {@link java.util.Formatter} and {@link java.lang.String#format}.
- *
- * @param resId Resource id for the format string
- * @param formatArgs The format arguments that will be used for substitution.
- */
-
- public final String getString(int resId, Object... formatArgs) {
- return getResources().getString(resId, formatArgs);
- }
-
- /**
- * Set the base theme for this context. Note that this should be called
- * before any views are instantiated in the Context (for example before
- * calling {@link android.app.Activity#setContentView} or
- * {@link android.view.LayoutInflater#inflate}).
- *
- * @param resid The style resource describing the theme.
- */
- public abstract void setTheme(int resid);
-
- /**
- * Return the Theme object associated with this Context.
- */
- public abstract Resources.Theme getTheme();
-
- /**
- * Retrieve styled attribute information in this Context's theme. See
- * {@link Resources.Theme#obtainStyledAttributes(int[])}
- * for more information.
- *
- * @see Resources.Theme#obtainStyledAttributes(int[])
- */
- public final TypedArray obtainStyledAttributes(
- int[] attrs) {
- return getTheme().obtainStyledAttributes(attrs);
- }
-
- /**
- * Retrieve styled attribute information in this Context's theme. See
- * {@link Resources.Theme#obtainStyledAttributes(int, int[])}
- * for more information.
- *
- * @see Resources.Theme#obtainStyledAttributes(int, int[])
- */
- public final TypedArray obtainStyledAttributes(
- int resid, int[] attrs) throws Resources.NotFoundException {
- return getTheme().obtainStyledAttributes(resid, attrs);
- }
-
- /**
- * Retrieve styled attribute information in this Context's theme. See
- * {@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)}
- * for more information.
- *
- * @see Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
- */
- public final TypedArray obtainStyledAttributes(
- AttributeSet set, int[] attrs) {
- return getTheme().obtainStyledAttributes(set, attrs, 0, 0);
- }
-
- /**
- * Retrieve styled attribute information in this Context's theme. See
- * {@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)}
- * for more information.
- *
- * @see Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
- */
- public final TypedArray obtainStyledAttributes(
- AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) {
- return getTheme().obtainStyledAttributes(
- set, attrs, defStyleAttr, defStyleRes);
- }
-
- /**
- * Return a class loader you can use to retrieve classes in this package.
- */
- public abstract ClassLoader getClassLoader();
-
- /** Return the name of this application's package. */
- public abstract String getPackageName();
-
- /**
- * {@hide}
- * Return the full path to this context's resource files. This is the ZIP files
- * containing the application's resources.
- *
- * <p>Note: this is not generally useful for applications, since they should
- * not be directly accessing the file system.
- *
- *
- * @return String Path to the resources.
- */
- public abstract String getPackageResourcePath();
-
- /**
- * {@hide}
- * Return the full path to this context's code and asset files. This is the ZIP files
- * containing the application's code and assets.
- *
- * <p>Note: this is not generally useful for applications, since they should
- * not be directly accessing the file system.
- *
- *
- * @return String Path to the code and assets.
- */
- public abstract String getPackageCodePath();
-
- /**
- * Retrieve and hold the contents of the preferences file 'name', returning
- * a SharedPreferences through which you can retrieve and modify its
- * values. Only one instance of the SharedPreferences object is returned
- * to any callers for the same name, meaning they will see each other's
- * edits as soon as they are made.
- *
- * @param name Desired preferences file. If a preferences file by this name
- * does not exist, it will be created when you retrieve an
- * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
- * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
- * default operation, {@link #MODE_WORLD_READABLE}
- * and {@link #MODE_WORLD_WRITEABLE} to control permissions.
- *
- * @return Returns the single SharedPreferences instance that can be used
- * to retrieve and modify the preference values.
- *
- * @see #MODE_PRIVATE
- * @see #MODE_WORLD_READABLE
- * @see #MODE_WORLD_WRITEABLE
- */
- public abstract SharedPreferences getSharedPreferences(String name,
- int mode);
-
- /**
- * Open a private file associated with this Context's application package
- * for reading.
- *
- * @param name The name of the file to open; can not contain path
- * separators.
- *
- * @return FileInputStream Resulting input stream.
- *
- * @see #openFileOutput
- * @see #fileList
- * @see #deleteFile
- * @see java.io.FileInputStream#FileInputStream(String)
- */
- public abstract FileInputStream openFileInput(String name)
- throws FileNotFoundException;
-
- /**
- * Open a private file associated with this Context's application package
- * for writing. Creates the file if it doesn't already exist.
- *
- * @param name The name of the file to open; can not contain path
- * separators.
- * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
- * default operation, {@link #MODE_APPEND} to append to an existing file,
- * {@link #MODE_WORLD_READABLE} and {@link #MODE_WORLD_WRITEABLE} to control
- * permissions.
- *
- * @return FileOutputStream Resulting output stream.
- *
- * @see #MODE_APPEND
- * @see #MODE_PRIVATE
- * @see #MODE_WORLD_READABLE
- * @see #MODE_WORLD_WRITEABLE
- * @see #openFileInput
- * @see #fileList
- * @see #deleteFile
- * @see java.io.FileOutputStream#FileOutputStream(String)
- */
- public abstract FileOutputStream openFileOutput(String name, int mode)
- throws FileNotFoundException;
-
- /**
- * Delete the given private file associated with this Context's
- * application package.
- *
- * @param name The name of the file to delete; can not contain path
- * separators.
- *
- * @return True if the file was successfully deleted; else
- * false.
- *
- * @see #openFileInput
- * @see #openFileOutput
- * @see #fileList
- * @see java.io.File#delete()
- */
- public abstract boolean deleteFile(String name);
-
- /**
- * Returns the absolute path on the filesystem where a file created with
- * {@link #openFileOutput} is stored.
- *
- * @param name The name of the file for which you would like to get
- * its path.
- *
- * @return Returns an absolute path to the given file.
- *
- * @see #openFileOutput
- * @see #getFilesDir
- * @see #getDir
- */
- public abstract File getFileStreamPath(String name);
-
- /**
- * Returns the absolute path to the directory on the filesystem where
- * files created with {@link #openFileOutput} are stored.
- *
- * @return Returns the path of the directory holding application files.
- *
- * @see #openFileOutput
- * @see #getFileStreamPath
- * @see #getDir
- */
- public abstract File getFilesDir();
-
- /**
- * Returns the absolute path to the application specific cache directory
- * on the filesystem. These files will be ones that get deleted first when the
- * device runs low on storage
- * There is no guarantee when these files will be deleted.
- *
- * @return Returns the path of the directory holding application cache files.
- *
- * @see #openFileOutput
- * @see #getFileStreamPath
- * @see #getDir
- */
- public abstract File getCacheDir();
-
- /**
- * Returns an array of strings naming the private files associated with
- * this Context's application package.
- *
- * @return Array of strings naming the private files.
- *
- * @see #openFileInput
- * @see #openFileOutput
- * @see #deleteFile
- */
- public abstract String[] fileList();
-
- /**
- * Retrieve, creating if needed, a new directory in which the application
- * can place its own custom data files. You can use the returned File
- * object to create and access files in this directory. Note that files
- * created through a File object will only be accessible by your own
- * application; you can only set the mode of the entire directory, not
- * of individual files.
- *
- * @param name Name of the directory to retrieve. This is a directory
- * that is created as part of your application data.
- * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
- * default operation, {@link #MODE_WORLD_READABLE} and
- * {@link #MODE_WORLD_WRITEABLE} to control permissions.
- *
- * @return Returns a File object for the requested directory. The directory
- * will have been created if it does not already exist.
- *
- * @see #openFileOutput(String, int)
- */
- public abstract File getDir(String name, int mode);
-
- /**
- * Open a new private SQLiteDatabase associated with this Context's
- * application package. Create the database file if it doesn't exist.
- *
- * @param name The name (unique in the application package) of the database.
- * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the
- * default operation, {@link #MODE_WORLD_READABLE}
- * and {@link #MODE_WORLD_WRITEABLE} to control permissions.
- * @param factory An optional factory class that is called to instantiate a
- * cursor when query is called.
- *
- * @return The contents of a newly created database with the given name.
- * @throws android.database.sqlite.SQLiteException if the database file could not be opened.
- *
- * @see #MODE_PRIVATE
- * @see #MODE_WORLD_READABLE
- * @see #MODE_WORLD_WRITEABLE
- * @see #deleteDatabase
- */
- public abstract SQLiteDatabase openOrCreateDatabase(String name,
- int mode, CursorFactory factory);
-
- /**
- * Delete an existing private SQLiteDatabase associated with this Context's
- * application package.
- *
- * @param name The name (unique in the application package) of the
- * database.
- *
- * @return True if the database was successfully deleted; else false.
- *
- * @see #openOrCreateDatabase
- */
- public abstract boolean deleteDatabase(String name);
-
- /**
- * Returns the absolute path on the filesystem where a database created with
- * {@link #openOrCreateDatabase} is stored.
- *
- * @param name The name of the database for which you would like to get
- * its path.
- *
- * @return Returns an absolute path to the given database.
- *
- * @see #openOrCreateDatabase
- */
- public abstract File getDatabasePath(String name);
-
- /**
- * Returns an array of strings naming the private databases associated with
- * this Context's application package.
- *
- * @return Array of strings naming the private databases.
- *
- * @see #openOrCreateDatabase
- * @see #deleteDatabase
- */
- public abstract String[] databaseList();
-
- /**
- * Like {@link #peekWallpaper}, but always returns a valid Drawable. If
- * no wallpaper is set, the system default wallpaper is returned.
- *
- * @return Returns a Drawable object that will draw the wallpaper.
- */
- public abstract Drawable getWallpaper();
-
- /**
- * Retrieve the current system wallpaper. This is returned as an
- * abstract Drawable that you can install in a View to display whatever
- * wallpaper the user has currently set. If there is no wallpaper set,
- * a null pointer is returned.
- *
- * @return Returns a Drawable object that will draw the wallpaper or a
- * null pointer if these is none.
- */
- public abstract Drawable peekWallpaper();
-
- /**
- * Returns the desired minimum width for the wallpaper. Callers of
- * {@link #setWallpaper(android.graphics.Bitmap)} or
- * {@link #setWallpaper(java.io.InputStream)} should check this value
- * beforehand to make sure the supplied wallpaper respects the desired
- * minimum width.
- *
- * If the returned value is <= 0, the caller should use the width of
- * the default display instead.
- *
- * @return The desired minimum width for the wallpaper. This value should
- * be honored by applications that set the wallpaper but it is not
- * mandatory.
- */
- public abstract int getWallpaperDesiredMinimumWidth();
-
- /**
- * Returns the desired minimum height for the wallpaper. Callers of
- * {@link #setWallpaper(android.graphics.Bitmap)} or
- * {@link #setWallpaper(java.io.InputStream)} should check this value
- * beforehand to make sure the supplied wallpaper respects the desired
- * minimum height.
- *
- * If the returned value is <= 0, the caller should use the height of
- * the default display instead.
- *
- * @return The desired minimum height for the wallpaper. This value should
- * be honored by applications that set the wallpaper but it is not
- * mandatory.
- */
- public abstract int getWallpaperDesiredMinimumHeight();
-
- /**
- * Change the current system wallpaper to a bitmap. The given bitmap is
- * converted to a PNG and stored as the wallpaper. On success, the intent
- * {@link Intent#ACTION_WALLPAPER_CHANGED} is broadcast.
- *
- * @param bitmap The bitmap to save.
- *
- * @throws IOException If an error occurs reverting to the default
- * wallpaper.
- */
- public abstract void setWallpaper(Bitmap bitmap) throws IOException;
-
- /**
- * Change the current system wallpaper to a specific byte stream. The
- * give InputStream is copied into persistent storage and will now be
- * used as the wallpaper. Currently it must be either a JPEG or PNG
- * image. On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED}
- * is broadcast.
- *
- * @param data A stream containing the raw data to install as a wallpaper.
- *
- * @throws IOException If an error occurs reverting to the default
- * wallpaper.
- */
- public abstract void setWallpaper(InputStream data) throws IOException;
-
- /**
- * Remove any currently set wallpaper, reverting to the system's default
- * wallpaper. On success, the intent {@link Intent#ACTION_WALLPAPER_CHANGED}
- * is broadcast.
- *
- * @throws IOException If an error occurs reverting to the default
- * wallpaper.
- */
- public abstract void clearWallpaper() throws IOException;
-
- /**
- * Launch a new activity. You will not receive any information about when
- * the activity exits.
- *
- * <p>Note that if this method is being called from outside of an
- * {@link android.app.Activity} Context, then the Intent must include
- * the {@link Intent#FLAG_ACTIVITY_NEW_TASK} launch flag. This is because,
- * without being started from an existing Activity, there is no existing
- * task in which to place the new activity and thus it needs to be placed
- * in its own separate task.
- *
- * <p>This method throws {@link ActivityNotFoundException}
- * if there was no Activity found to run the given Intent.
- *
- * @param intent The description of the activity to start.
- *
- * @throws ActivityNotFoundException
- *
- * @see PackageManager#resolveActivity
- */
- public abstract void startActivity(Intent intent);
-
- /**
- * Broadcast the given intent to all interested BroadcastReceivers. This
- * call is asynchronous; it returns immediately, and you will continue
- * executing while the receivers are run. No results are propagated from
- * receivers and receivers can not abort the broadcast. If you want
- * to allow receivers to propagate results or abort the broadcast, you must
- * send an ordered broadcast using
- * {@link #sendOrderedBroadcast(Intent, String)}.
- *
- * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
- *
- * @param intent The Intent to broadcast; all receivers matching this
- * Intent will receive the broadcast.
- *
- * @see android.content.BroadcastReceiver
- * @see #registerReceiver
- * @see #sendBroadcast(Intent, String)
- * @see #sendOrderedBroadcast(Intent, String)
- * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
- */
- public abstract void sendBroadcast(Intent intent);
-
- /**
- * Broadcast the given intent to all interested BroadcastReceivers, allowing
- * an optional required permission to be enforced. This
- * call is asynchronous; it returns immediately, and you will continue
- * executing while the receivers are run. No results are propagated from
- * receivers and receivers can not abort the broadcast. If you want
- * to allow receivers to propagate results or abort the broadcast, you must
- * send an ordered broadcast using
- * {@link #sendOrderedBroadcast(Intent, String)}.
- *
- * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
- *
- * @param intent The Intent to broadcast; all receivers matching this
- * Intent will receive the broadcast.
- * @param receiverPermission (optional) String naming a permissions that
- * a receiver must hold in order to receive your broadcast.
- * If null, no permission is required.
- *
- * @see android.content.BroadcastReceiver
- * @see #registerReceiver
- * @see #sendBroadcast(Intent)
- * @see #sendOrderedBroadcast(Intent, String)
- * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
- */
- public abstract void sendBroadcast(Intent intent,
- String receiverPermission);
-
- /**
- * Broadcast the given intent to all interested BroadcastReceivers, delivering
- * them one at a time to allow more preferred receivers to consume the
- * broadcast before it is delivered to less preferred receivers. This
- * call is asynchronous; it returns immediately, and you will continue
- * executing while the receivers are run.
- *
- * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
- *
- * @param intent The Intent to broadcast; all receivers matching this
- * Intent will receive the broadcast.
- * @param receiverPermission (optional) String naming a permissions that
- * a receiver must hold in order to receive your broadcast.
- * If null, no permission is required.
- *
- * @see android.content.BroadcastReceiver
- * @see #registerReceiver
- * @see #sendBroadcast(Intent)
- * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
- */
- public abstract void sendOrderedBroadcast(Intent intent,
- String receiverPermission);
-
- /**
- * Version of {@link #sendBroadcast(Intent)} that allows you to
- * receive data back from the broadcast. This is accomplished by
- * supplying your own BroadcastReceiver when calling, which will be
- * treated as a final receiver at the end of the broadcast -- its
- * {@link BroadcastReceiver#onReceive} method will be called with
- * the result values collected from the other receivers. If you use
- * an <var>resultReceiver</var> with this method, then the broadcast will
- * be serialized in the same way as calling
- * {@link #sendOrderedBroadcast(Intent, String)}.
- *
- * <p>Like {@link #sendBroadcast(Intent)}, this method is
- * asynchronous; it will return before
- * resultReceiver.onReceive() is called.
- *
- * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
- *
- * @param intent The Intent to broadcast; all receivers matching this
- * Intent will receive the broadcast.
- * @param receiverPermission String naming a permissions that
- * a receiver must hold in order to receive your broadcast.
- * If null, no permission is required.
- * @param resultReceiver Your own BroadcastReceiver to treat as the final
- * receiver of the broadcast.
- * @param scheduler A custom Handler with which to schedule the
- * resultReceiver callback; if null it will be
- * scheduled in the Context's main thread.
- * @param initialCode An initial value for the result code. Often
- * Activity.RESULT_OK.
- * @param initialData An initial value for the result data. Often
- * null.
- * @param initialExtras An initial value for the result extras. Often
- * null.
- *
- * @see #sendBroadcast(Intent)
- * @see #sendBroadcast(Intent, String)
- * @see #sendOrderedBroadcast(Intent, String)
- * @see #sendStickyBroadcast(Intent)
- * @see android.content.BroadcastReceiver
- * @see #registerReceiver
- * @see android.app.Activity#RESULT_OK
- */
- public abstract void sendOrderedBroadcast(Intent intent,
- String receiverPermission, BroadcastReceiver resultReceiver,
- Handler scheduler, int initialCode, String initialData,
- Bundle initialExtras);
-
- /**
- * Perform a {@link #sendBroadcast(Intent)} that is "sticky," meaning the
- * Intent you are sending stays around after the broadcast is complete,
- * so that others can quickly retrieve that data through the return
- * value of {@link #registerReceiver(BroadcastReceiver, IntentFilter)}. In
- * all other ways, this behaves the same as
- * {@link #sendBroadcast(Intent)}.
- *
- * <p>You must hold the {@link android.Manifest.permission#BROADCAST_STICKY}
- * permission in order to use this API. If you do not hold that
- * permission, {@link SecurityException} will be thrown.
- *
- * @param intent The Intent to broadcast; all receivers matching this
- * Intent will receive the broadcast, and the Intent will be held to
- * be re-broadcast to future receivers.
- *
- * @see #sendBroadcast(Intent)
- */
- public abstract void sendStickyBroadcast(Intent intent);
-
- /**
- * Remove the data previously sent with {@link #sendStickyBroadcast},
- * so that it is as if the sticky broadcast had never happened.
- *
- * <p>You must hold the {@link android.Manifest.permission#BROADCAST_STICKY}
- * permission in order to use this API. If you do not hold that
- * permission, {@link SecurityException} will be thrown.
- *
- * @param intent The Intent that was previously broadcast.
- *
- * @see #sendStickyBroadcast
- */
- public abstract void removeStickyBroadcast(Intent intent);
-
- /**
- * Register an BroadcastReceiver to be run in the main activity thread. The
- * <var>receiver</var> will be called with any broadcast Intent that
- * matches <var>filter</var>, in the main application thread.
- *
- * <p>The system may broadcast Intents that are "sticky" -- these stay
- * around after the broadcast as finished, to be sent to any later
- * registrations. If your IntentFilter matches one of these sticky
- * Intents, that Intent will be returned by this function
- * <strong>and</strong> sent to your <var>receiver</var> as if it had just
- * been broadcast.
- *
- * <p>There may be multiple sticky Intents that match <var>filter</var>,
- * in which case each of these will be sent to <var>receiver</var>. In
- * this case, only one of these can be returned directly by the function;
- * which of these that is returned is arbitrarily decided by the system.
- *
- * <p>If you know the Intent your are registering for is sticky, you can
- * supply null for your <var>receiver</var>. In this case, no receiver is
- * registered -- the function simply returns the sticky Intent that
- * matches <var>filter</var>. In the case of multiple matches, the same
- * rules as described above apply.
- *
- * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
- *
- * <p class="note">Note: this method <em>can not be called from an
- * {@link BroadcastReceiver} component</em>. It is okay, however, to use
- * this method from another BroadcastReceiver that has itself been registered with
- * {@link #registerReceiver}, since the lifetime of such an BroadcastReceiver
- * is tied to another object (the one that registered it).</p>
- *
- * @param receiver The BroadcastReceiver to handle the broadcast.
- * @param filter Selects the Intent broadcasts to be received.
- *
- * @return The first sticky intent found that matches <var>filter</var>,
- * or null if there are none.
- *
- * @see #registerReceiver(BroadcastReceiver, IntentFilter, String, Handler)
- * @see #sendBroadcast
- * @see #unregisterReceiver
- */
- public abstract Intent registerReceiver(BroadcastReceiver receiver,
- IntentFilter filter);
-
- /**
- * Register to receive intent broadcasts, to run in the context of
- * <var>scheduler</var>. See
- * {@link #registerReceiver(BroadcastReceiver, IntentFilter)} for more
- * information. This allows you to enforce permissions on who can
- * broadcast intents to your receiver, or have the receiver run in
- * a different thread than the main application thread.
- *
- * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
- *
- * @param receiver The BroadcastReceiver to handle the broadcast.
- * @param filter Selects the Intent broadcasts to be received.
- * @param broadcastPermission String naming a permissions that a
- * broadcaster must hold in order to send an Intent to you. If null,
- * no permission is required.
- * @param scheduler Handler identifying the thread that will receive
- * the Intent. If null, the main thread of the process will be used.
- *
- * @return The first sticky intent found that matches <var>filter</var>,
- * or null if there are none.
- *
- * @see #registerReceiver(BroadcastReceiver, IntentFilter)
- * @see #sendBroadcast
- * @see #unregisterReceiver
- */
- public abstract Intent registerReceiver(BroadcastReceiver receiver,
- IntentFilter filter,
- String broadcastPermission,
- Handler scheduler);
-
- /**
- * Unregister a previously registered BroadcastReceiver. <em>All</em>
- * filters that have been registered for this BroadcastReceiver will be
- * removed.
- *
- * @param receiver The BroadcastReceiver to unregister.
- *
- * @see #registerReceiver
- */
- public abstract void unregisterReceiver(BroadcastReceiver receiver);
-
- /**
- * Request that a given application service be started. The Intent
- * can either contain the complete class name of a specific service
- * implementation to start, or an abstract definition through the
- * action and other fields of the kind of service to start. If this service
- * is not already running, it will be instantiated and started (creating a
- * process for it if needed); if it is running then it remains running.
- *
- * <p>Every call to this method will result in a corresponding call to
- * the target service's {@link android.app.Service#onStart} method,
- * with the <var>intent</var> given here. This provides a convenient way
- * to submit jobs to a service without having to bind and call on to its
- * interface.
- *
- * <p>Using startService() overrides the default service lifetime that is
- * managed by {@link #bindService}: it requires the service to remain
- * running until {@link #stopService} is called, regardless of whether
- * any clients are connected to it. Note that calls to startService()
- * are not nesting: no matter how many times you call startService(),
- * a single call to {@link #stopService} will stop it.
- *
- * <p>The system attempts to keep running services around as much as
- * possible. The only time they should be stopped is if the current
- * foreground application is using so many resources that the service needs
- * to be killed. If any errors happen in the service's process, it will
- * automatically be restarted.
- *
- * <p>This function will throw {@link SecurityException} if you do not
- * have permission to start the given service.
- *
- * @param service Identifies the service to be started. The Intent may
- * specify either an explicit component name to start, or a logical
- * description (action, category, etc) to match an
- * {@link IntentFilter} published by a service. Additional values
- * may be included in the Intent extras to supply arguments along with
- * this specific start call.
- *
- * @return If the service is being started or is already running, the
- * {@link ComponentName} of the actual service that was started is
- * returned; else if the service does not exist null is returned.
- *
- * @throws SecurityException
- *
- * @see #stopService
- * @see #bindService
- */
- public abstract ComponentName startService(Intent service);
-
- /**
- * Request that a given application service be stopped. If the service is
- * not running, nothing happens. Otherwise it is stopped. Note that calls
- * to startService() are not counted -- this stops the service no matter
- * how many times it was started.
- *
- * <p>Note that if a stopped service still has {@link ServiceConnection}
- * objects bound to it with the {@link #BIND_AUTO_CREATE} set, it will
- * not be destroyed until all of these bindings are removed. See
- * the {@link android.app.Service} documentation for more details on a
- * service's lifecycle.
- *
- * <p>This function will throw {@link SecurityException} if you do not
- * have permission to stop the given service.
- *
- * @param service Description of the service to be stopped. The Intent may
- * specify either an explicit component name to start, or a logical
- * description (action, category, etc) to match an
- * {@link IntentFilter} published by a service.
- *
- * @return If there is a service matching the given Intent that is already
- * running, then it is stopped and true is returned; else false is returned.
- *
- * @throws SecurityException
- *
- * @see #startService
- */
- public abstract boolean stopService(Intent service);
-
- /**
- * Connect to an application service, creating it if needed. This defines
- * a dependency between your application and the service. The given
- * <var>conn</var> will receive the service object when its created and be
- * told if it dies and restarts. The service will be considered required
- * by the system only for as long as the calling context exists. For
- * example, if this Context is an Activity that is stopped, the service will
- * not be required to continue running until the Activity is resumed.
- *
- * <p>This function will throw {@link SecurityException} if you do not
- * have permission to bind to the given service.
- *
- * <p class="note">Note: this method <em>can not be called from an
- * {@link BroadcastReceiver} component</em>. A pattern you can use to
- * communicate from an BroadcastReceiver to a Service is to call
- * {@link #startService} with the arguments containing the command to be
- * sent, with the service calling its
- * {@link android.app.Service#stopSelf(int)} method when done executing
- * that command. See the API demo App/Service/Service Start Arguments
- * Controller for an illustration of this. It is okay, however, to use
- * this method from an BroadcastReceiver that has been registered with
- * {@link #registerReceiver}, since the lifetime of this BroadcastReceiver
- * is tied to another object (the one that registered it).</p>
- *
- * @param service Identifies the service to connect to. The Intent may
- * specify either an explicit component name, or a logical
- * description (action, category, etc) to match an
- * {@link IntentFilter} published by a service.
- * @param conn Receives information as the service is started and stopped.
- * @param flags Operation options for the binding. May be 0 or
- * {@link #BIND_AUTO_CREATE}.
- * @return If you have successfully bound to the service, true is returned;
- * false is returned if the connection is not made so you will not
- * receive the service object.
- *
- * @throws SecurityException
- *
- * @see #unbindService
- * @see #startService
- * @see #BIND_AUTO_CREATE
- */
- public abstract boolean bindService(Intent service, ServiceConnection conn,
- int flags);
-
- /**
- * Disconnect from an application service. You will no longer receive
- * calls as the service is restarted, and the service is now allowed to
- * stop at any time.
- *
- * @param conn The connection interface previously supplied to
- * bindService().
- *
- * @see #bindService
- */
- public abstract void unbindService(ServiceConnection conn);
-
- /**
- * Start executing an {@link android.app.Instrumentation} class. The given
- * Instrumentation component will be run by killing its target application
- * (if currently running), starting the target process, instantiating the
- * instrumentation component, and then letting it drive the application.
- *
- * <p>This function is not synchronous -- it returns as soon as the
- * instrumentation has started and while it is running.
- *
- * <p>Instrumentation is normally only allowed to run against a package
- * that is either unsigned or signed with a signature that the
- * the instrumentation package is also signed with (ensuring the target
- * trusts the instrumentation).
- *
- * @param className Name of the Instrumentation component to be run.
- * @param profileFile Optional path to write profiling data as the
- * instrumentation runs, or null for no profiling.
- * @param arguments Additional optional arguments to pass to the
- * instrumentation, or null.
- *
- * @return Returns true if the instrumentation was successfully started,
- * else false if it could not be found.
- */
- public abstract boolean startInstrumentation(ComponentName className,
- String profileFile, Bundle arguments);
-
- /**
- * Return the handle to a system-level service by name. The class of the
- * returned object varies by the requested name. Currently available names
- * are:
- *
- * <dl>
- * <dt> {@link #WINDOW_SERVICE} ("window")
- * <dd> The top-level window manager in which you can place custom
- * windows. The returned object is a {@link android.view.WindowManager}.
- * <dt> {@link #LAYOUT_INFLATER_SERVICE} ("layout_inflater")
- * <dd> A {@link android.view.LayoutInflater} for inflating layout resources
- * in this context.
- * <dt> {@link #ACTIVITY_SERVICE} ("activity")
- * <dd> A {@link android.app.ActivityManager} for interacting with the
- * global activity state of the system.
- * <dt> {@link #POWER_SERVICE} ("power")
- * <dd> A {@link android.os.PowerManager} for controlling power
- * management.
- * <dt> {@link #ALARM_SERVICE} ("alarm")
- * <dd> A {@link android.app.AlarmManager} for receiving intents at the
- * time of your choosing.
- * <dt> {@link #NOTIFICATION_SERVICE} ("notification")
- * <dd> A {@link android.app.NotificationManager} for informing the user
- * of background events.
- * <dt> {@link #KEYGUARD_SERVICE} ("keyguard")
- * <dd> A {@link android.app.KeyguardManager} for controlling keyguard.
- * <dt> {@link #LOCATION_SERVICE} ("location")
- * <dd> A {@link android.location.LocationManager} for controlling location
- * (e.g., GPS) updates.
- * <dt> {@link #SEARCH_SERVICE} ("search")
- * <dd> A {@link android.app.SearchManager} for handling search.
- * <dt> {@link #VIBRATOR_SERVICE} ("vibrator")
- * <dd> A {@link android.os.Vibrator} for interacting with the vibrator
- * hardware.
- * <dt> {@link #CONNECTIVITY_SERVICE} ("connection")
- * <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for
- * handling management of network connections.
- * <dt> {@link #WIFI_SERVICE} ("wifi")
- * <dd> A {@link android.net.wifi.WifiManager WifiManager} for management of
- * Wi-Fi connectivity.
- * <dt> {@link #INPUT_METHOD_SERVICE} ("input_method")
- * <dd> An {@link android.view.inputmethod.InputMethodManager InputMethodManager}
- * for management of input methods.
- * </dl>
- *
- * <p>Note: System services obtained via this API may be closely associated with
- * the Context in which they are obtained from. In general, do not share the
- * service objects between various different contexts (Activities, Applications,
- * Services, Providers, etc.)
- *
- * @param name The name of the desired service.
- *
- * @return The service or null if the name does not exist.
- *
- * @see #WINDOW_SERVICE
- * @see android.view.WindowManager
- * @see #LAYOUT_INFLATER_SERVICE
- * @see android.view.LayoutInflater
- * @see #ACTIVITY_SERVICE
- * @see android.app.ActivityManager
- * @see #POWER_SERVICE
- * @see android.os.PowerManager
- * @see #ALARM_SERVICE
- * @see android.app.AlarmManager
- * @see #NOTIFICATION_SERVICE
- * @see android.app.NotificationManager
- * @see #KEYGUARD_SERVICE
- * @see android.app.KeyguardManager
- * @see #LOCATION_SERVICE
- * @see android.location.LocationManager
- * @see #SEARCH_SERVICE
- * @see android.app.SearchManager
- * @see #SENSOR_SERVICE
- * @see android.hardware.SensorManager
- * @see #VIBRATOR_SERVICE
- * @see android.os.Vibrator
- * @see #CONNECTIVITY_SERVICE
- * @see android.net.ConnectivityManager
- * @see #WIFI_SERVICE
- * @see android.net.wifi.WifiManager
- * @see #AUDIO_SERVICE
- * @see android.media.AudioManager
- * @see #TELEPHONY_SERVICE
- * @see android.telephony.TelephonyManager
- * @see #INPUT_METHOD_SERVICE
- * @see android.view.inputmethod.InputMethodManager
- */
- public abstract Object getSystemService(String name);
-
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.os.PowerManager} for controlling power management,
- * including "wake locks," which let you keep the device on while
- * you're running long tasks.
- */
- public static final String POWER_SERVICE = "power";
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.view.WindowManager} for accessing the system's window
- * manager.
- *
- * @see #getSystemService
- * @see android.view.WindowManager
- */
- public static final String WINDOW_SERVICE = "window";
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.view.LayoutInflater} for inflating layout resources in this
- * context.
- *
- * @see #getSystemService
- * @see android.view.LayoutInflater
- */
- public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.app.ActivityManager} for interacting with the global
- * system state.
- *
- * @see #getSystemService
- * @see android.app.ActivityManager
- */
- public static final String ACTIVITY_SERVICE = "activity";
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.app.AlarmManager} for receiving intents at a
- * time of your choosing.
- *
- * @see #getSystemService
- * @see android.app.AlarmManager
- */
- public static final String ALARM_SERVICE = "alarm";
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.app.NotificationManager} for informing the user of
- * background events.
- *
- * @see #getSystemService
- * @see android.app.NotificationManager
- */
- public static final String NOTIFICATION_SERVICE = "notification";
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.app.NotificationManager} for controlling keyguard.
- *
- * @see #getSystemService
- * @see android.app.KeyguardManager
- */
- public static final String KEYGUARD_SERVICE = "keyguard";
- /**
- * Use with {@link #getSystemService} to retrieve a {@link
- * android.location.LocationManager} for controlling location
- * updates.
- *
- * @see #getSystemService
- * @see android.location.LocationManager
- */
- public static final String LOCATION_SERVICE = "location";
- /**
- * Use with {@link #getSystemService} to retrieve a {@link
- * android.app.SearchManager} for handling searches.
- *
- * @see #getSystemService
- * @see android.app.SearchManager
- */
- public static final String SEARCH_SERVICE = "search";
- /**
- * Use with {@link #getSystemService} to retrieve a {@link
- * android.hardware.SensorManager} for accessing sensors.
- *
- * @see #getSystemService
- * @see android.hardware.SensorManager
- */
- public static final String SENSOR_SERVICE = "sensor";
- /**
- * Use with {@link #getSystemService} to retrieve a {@link
- * android.bluetooth.BluetoothDevice} for interacting with Bluetooth.
- *
- * @see #getSystemService
- * @see android.bluetooth.BluetoothDevice
- * @hide
- */
- public static final String BLUETOOTH_SERVICE = "bluetooth";
- /**
- * Use with {@link #getSystemService} to retrieve a
- * com.android.server.WallpaperService for accessing wallpapers.
- *
- * @see #getSystemService
- */
- public static final String WALLPAPER_SERVICE = "wallpaper";
- /**
- * Use with {@link #getSystemService} to retrieve a {@link
- * android.os.Vibrator} for interacting with the vibration hardware.
- *
- * @see #getSystemService
- * @see android.os.Vibrator
- */
- public static final String VIBRATOR_SERVICE = "vibrator";
- /**
- * Use with {@link #getSystemService} to retrieve a {@link
- * android.app.StatusBarManager} for interacting with the status bar.
- *
- * @see #getSystemService
- * @see android.app.StatusBarManager
- * @hide
- */
- public static final String STATUS_BAR_SERVICE = "statusbar";
-
- /**
- * Use with {@link #getSystemService} to retrieve a {@link
- * android.net.ConnectivityManager} for handling management of
- * network connections.
- *
- * @see #getSystemService
- * @see android.net.ConnectivityManager
- */
- public static final String CONNECTIVITY_SERVICE = "connectivity";
-
- /**
- * Use with {@link #getSystemService} to retrieve a {@link
- * android.net.wifi.WifiManager} for handling management of
- * Wi-Fi access.
- *
- * @see #getSystemService
- * @see android.net.wifi.WifiManager
- */
- public static final String WIFI_SERVICE = "wifi";
-
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.media.AudioManager} for handling management of volume,
- * ringer modes and audio routing.
- *
- * @see #getSystemService
- * @see android.media.AudioManager
- */
- public static final String AUDIO_SERVICE = "audio";
-
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.telephony.TelephonyManager} for handling management the
- * telephony features of the device.
- *
- * @see #getSystemService
- * @see android.telephony.TelephonyManager
- */
- public static final String TELEPHONY_SERVICE = "phone";
-
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.text.ClipboardManager} for accessing and modifying
- * the contents of the global clipboard.
- *
- * @see #getSystemService
- * @see android.text.ClipboardManager
- */
- public static final String CLIPBOARD_SERVICE = "clipboard";
-
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@link android.view.inputmethod.InputMethodManager} for accessing input
- * methods.
- *
- * @see #getSystemService
- */
- public static final String INPUT_METHOD_SERVICE = "input_method";
-
- /**
- * Use with {@link #getSystemService} to retrieve a
- * {@blink android.gadget.GadgetManager} for accessing wallpapers.
- *
- * @hide
- * @see #getSystemService
- */
- public static final String GADGET_SERVICE = "gadget";
-
- /**
- * Determine whether the given permission is allowed for a particular
- * process and user ID running in the system.
- *
- * @param permission The name of the permission being checked.
- * @param pid The process ID being checked against. Must be > 0.
- * @param uid The user ID being checked against. A uid of 0 is the root
- * user, which will pass every permission check.
- *
- * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the given
- * pid/uid is allowed that permission, or
- * {@link PackageManager#PERMISSION_DENIED} if it is not.
- *
- * @see PackageManager#checkPermission(String, String)
- * @see #checkCallingPermission
- */
- public abstract int checkPermission(String permission, int pid, int uid);
-
- /**
- * Determine whether the calling process of an IPC you are handling has been
- * granted a particular permission. This is basically the same as calling
- * {@link #checkPermission(String, int, int)} with the pid and uid returned
- * by {@link android.os.Binder#getCallingPid} and
- * {@link android.os.Binder#getCallingUid}. One important difference
- * is that if you are not currently processing an IPC, this function
- * will always fail. This is done to protect against accidentally
- * leaking permissions; you can use {@link #checkCallingOrSelfPermission}
- * to avoid this protection.
- *
- * @param permission The name of the permission being checked.
- *
- * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the calling
- * pid/uid is allowed that permission, or
- * {@link PackageManager#PERMISSION_DENIED} if it is not.
- *
- * @see PackageManager#checkPermission(String, String)
- * @see #checkPermission
- * @see #checkCallingOrSelfPermission
- */
- public abstract int checkCallingPermission(String permission);
-
- /**
- * Determine whether the calling process of an IPC <em>or you</em> have been
- * granted a particular permission. This is the same as
- * {@link #checkCallingPermission}, except it grants your own permissions
- * if you are not currently processing an IPC. Use with care!
- *
- * @param permission The name of the permission being checked.
- *
- * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the calling
- * pid/uid is allowed that permission, or
- * {@link PackageManager#PERMISSION_DENIED} if it is not.
- *
- * @see PackageManager#checkPermission(String, String)
- * @see #checkPermission
- * @see #checkCallingPermission
- */
- public abstract int checkCallingOrSelfPermission(String permission);
-
- /**
- * If the given permission is not allowed for a particular process
- * and user ID running in the system, throw a {@link SecurityException}.
- *
- * @param permission The name of the permission being checked.
- * @param pid The process ID being checked against. Must be &gt; 0.
- * @param uid The user ID being checked against. A uid of 0 is the root
- * user, which will pass every permission check.
- * @param message A message to include in the exception if it is thrown.
- *
- * @see #checkPermission(String, int, int)
- */
- public abstract void enforcePermission(
- String permission, int pid, int uid, String message);
-
- /**
- * If the calling process of an IPC you are handling has not been
- * granted a particular permission, throw a {@link
- * SecurityException}. This is basically the same as calling
- * {@link #enforcePermission(String, int, int, String)} with the
- * pid and uid returned by {@link android.os.Binder#getCallingPid}
- * and {@link android.os.Binder#getCallingUid}. One important
- * difference is that if you are not currently processing an IPC,
- * this function will always throw the SecurityException. This is
- * done to protect against accidentally leaking permissions; you
- * can use {@link #enforceCallingOrSelfPermission} to avoid this
- * protection.
- *
- * @param permission The name of the permission being checked.
- * @param message A message to include in the exception if it is thrown.
- *
- * @see #checkCallingPermission(String)
- */
- public abstract void enforceCallingPermission(
- String permission, String message);
-
- /**
- * If neither you nor the calling process of an IPC you are
- * handling has been granted a particular permission, throw a
- * {@link SecurityException}. This is the same as {@link
- * #enforceCallingPermission}, except it grants your own
- * permissions if you are not currently processing an IPC. Use
- * with care!
- *
- * @param permission The name of the permission being checked.
- * @param message A message to include in the exception if it is thrown.
- *
- * @see #checkCallingOrSelfPermission(String)
- */
- public abstract void enforceCallingOrSelfPermission(
- String permission, String message);
-
- /**
- * Grant permission to access a specific Uri to another package, regardless
- * of whether that package has general permission to access the Uri's
- * content provider. This can be used to grant specific, temporary
- * permissions, typically in response to user interaction (such as the
- * user opening an attachment that you would like someone else to
- * display).
- *
- * <p>Normally you should use {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
- * Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION
- * Intent.FLAG_GRANT_WRITE_URI_PERMISSION} with the Intent being used to
- * start an activity instead of this function directly. If you use this
- * function directly, you should be sure to call
- * {@link #revokeUriPermission} when the target should no longer be allowed
- * to access it.
- *
- * <p>To succeed, the content provider owning the Uri must have set the
- * {@link android.R.styleable#AndroidManifestProvider_grantUriPermissions
- * grantUriPermissions} attribute in its manifest or included the
- * {@link android.R.styleable#AndroidManifestGrantUriPermission
- * &lt;grant-uri-permissions&gt;} tag.
- *
- * @param toPackage The package you would like to allow to access the Uri.
- * @param uri The Uri you would like to grant access to.
- * @param modeFlags The desired access modes. Any combination of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
- * Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION
- * Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- *
- * @see #revokeUriPermission
- */
- public abstract void grantUriPermission(String toPackage, Uri uri,
- int modeFlags);
-
- /**
- * Remove all permissions to access a particular content provider Uri
- * that were previously added with {@link #grantUriPermission}. The given
- * Uri will match all previously granted Uris that are the same or a
- * sub-path of the given Uri. That is, revoking "content://foo/one" will
- * revoke both "content://foo/target" and "content://foo/target/sub", but not
- * "content://foo".
- *
- * @param uri The Uri you would like to revoke access to.
- * @param modeFlags The desired access modes. Any combination of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION
- * Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION
- * Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- *
- * @see #grantUriPermission
- */
- public abstract void revokeUriPermission(Uri uri, int modeFlags);
-
- /**
- * Determine whether a particular process and user ID has been granted
- * permission to access a specific URI. This only checks for permissions
- * that have been explicitly granted -- if the given process/uid has
- * more general access to the URI's content provider then this check will
- * always fail.
- *
- * @param uri The uri that is being checked.
- * @param pid The process ID being checked against. Must be &gt; 0.
- * @param uid The user ID being checked against. A uid of 0 is the root
- * user, which will pass every permission check.
- * @param modeFlags The type of access to grant. May be one or both of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- *
- * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the given
- * pid/uid is allowed to access that uri, or
- * {@link PackageManager#PERMISSION_DENIED} if it is not.
- *
- * @see #checkCallingUriPermission
- */
- public abstract int checkUriPermission(Uri uri, int pid, int uid, int modeFlags);
-
- /**
- * Determine whether the calling process and user ID has been
- * granted permission to access a specific URI. This is basically
- * the same as calling {@link #checkUriPermission(Uri, int, int,
- * int)} with the pid and uid returned by {@link
- * android.os.Binder#getCallingPid} and {@link
- * android.os.Binder#getCallingUid}. One important difference is
- * that if you are not currently processing an IPC, this function
- * will always fail.
- *
- * @param uri The uri that is being checked.
- * @param modeFlags The type of access to grant. May be one or both of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- *
- * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the caller
- * is allowed to access that uri, or
- * {@link PackageManager#PERMISSION_DENIED} if it is not.
- *
- * @see #checkUriPermission(Uri, int, int, int)
- */
- public abstract int checkCallingUriPermission(Uri uri, int modeFlags);
-
- /**
- * Determine whether the calling process of an IPC <em>or you</em> has been granted
- * permission to access a specific URI. This is the same as
- * {@link #checkCallingUriPermission}, except it grants your own permissions
- * if you are not currently processing an IPC. Use with care!
- *
- * @param uri The uri that is being checked.
- * @param modeFlags The type of access to grant. May be one or both of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- *
- * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the caller
- * is allowed to access that uri, or
- * {@link PackageManager#PERMISSION_DENIED} if it is not.
- *
- * @see #checkCallingUriPermission
- */
- public abstract int checkCallingOrSelfUriPermission(Uri uri, int modeFlags);
-
- /**
- * Check both a Uri and normal permission. This allows you to perform
- * both {@link #checkPermission} and {@link #checkUriPermission} in one
- * call.
- *
- * @param uri The Uri whose permission is to be checked, or null to not
- * do this check.
- * @param readPermission The permission that provides overall read access,
- * or null to not do this check.
- * @param writePermission The permission that provides overall write
- * acess, or null to not do this check.
- * @param pid The process ID being checked against. Must be &gt; 0.
- * @param uid The user ID being checked against. A uid of 0 is the root
- * user, which will pass every permission check.
- * @param modeFlags The type of access to grant. May be one or both of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- *
- * @return Returns {@link PackageManager#PERMISSION_GRANTED} if the caller
- * is allowed to access that uri or holds one of the given permissions, or
- * {@link PackageManager#PERMISSION_DENIED} if it is not.
- */
- public abstract int checkUriPermission(Uri uri, String readPermission,
- String writePermission, int pid, int uid, int modeFlags);
-
- /**
- * If a particular process and user ID has not been granted
- * permission to access a specific URI, throw {@link
- * SecurityException}. This only checks for permissions that have
- * been explicitly granted -- if the given process/uid has more
- * general access to the URI's content provider then this check
- * will always fail.
- *
- * @param uri The uri that is being checked.
- * @param pid The process ID being checked against. Must be &gt; 0.
- * @param uid The user ID being checked against. A uid of 0 is the root
- * user, which will pass every permission check.
- * @param modeFlags The type of access to grant. May be one or both of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- * @param message A message to include in the exception if it is thrown.
- *
- * @see #checkUriPermission(Uri, int, int, int)
- */
- public abstract void enforceUriPermission(
- Uri uri, int pid, int uid, int modeFlags, String message);
-
- /**
- * If the calling process and user ID has not been granted
- * permission to access a specific URI, throw {@link
- * SecurityException}. This is basically the same as calling
- * {@link #enforceUriPermission(Uri, int, int, int, String)} with
- * the pid and uid returned by {@link
- * android.os.Binder#getCallingPid} and {@link
- * android.os.Binder#getCallingUid}. One important difference is
- * that if you are not currently processing an IPC, this function
- * will always throw a SecurityException.
- *
- * @param uri The uri that is being checked.
- * @param modeFlags The type of access to grant. May be one or both of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- * @param message A message to include in the exception if it is thrown.
- *
- * @see #checkCallingUriPermission(Uri, int)
- */
- public abstract void enforceCallingUriPermission(
- Uri uri, int modeFlags, String message);
-
- /**
- * If the calling process of an IPC <em>or you</em> has not been
- * granted permission to access a specific URI, throw {@link
- * SecurityException}. This is the same as {@link
- * #enforceCallingUriPermission}, except it grants your own
- * permissions if you are not currently processing an IPC. Use
- * with care!
- *
- * @param uri The uri that is being checked.
- * @param modeFlags The type of access to grant. May be one or both of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- * @param message A message to include in the exception if it is thrown.
- *
- * @see #checkCallingOrSelfUriPermission(Uri, int)
- */
- public abstract void enforceCallingOrSelfUriPermission(
- Uri uri, int modeFlags, String message);
-
- /**
- * Enforce both a Uri and normal permission. This allows you to perform
- * both {@link #enforcePermission} and {@link #enforceUriPermission} in one
- * call.
- *
- * @param uri The Uri whose permission is to be checked, or null to not
- * do this check.
- * @param readPermission The permission that provides overall read access,
- * or null to not do this check.
- * @param writePermission The permission that provides overall write
- * acess, or null to not do this check.
- * @param pid The process ID being checked against. Must be &gt; 0.
- * @param uid The user ID being checked against. A uid of 0 is the root
- * user, which will pass every permission check.
- * @param modeFlags The type of access to grant. May be one or both of
- * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION Intent.FLAG_GRANT_READ_URI_PERMISSION} or
- * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION Intent.FLAG_GRANT_WRITE_URI_PERMISSION}.
- * @param message A message to include in the exception if it is thrown.
- *
- * @see #checkUriPermission(Uri, String, String, int, int, int)
- */
- public abstract void enforceUriPermission(
- Uri uri, String readPermission, String writePermission,
- int pid, int uid, int modeFlags, String message);
-
- /**
- * Flag for use with {@link #createPackageContext}: include the application
- * code with the context. This means loading code into the caller's
- * process, so that {@link #getClassLoader()} can be used to instantiate
- * the application's classes. Setting this flags imposes security
- * restrictions on what application context you can access; if the
- * requested application can not be safely loaded into your process,
- * java.lang.SecurityException will be thrown. If this flag is not set,
- * there will be no restrictions on the packages that can be loaded,
- * but {@link #getClassLoader} will always return the default system
- * class loader.
- */
- public static final int CONTEXT_INCLUDE_CODE = 0x00000001;
-
- /**
- * Flag for use with {@link #createPackageContext}: ignore any security
- * restrictions on the Context being requested, allowing it to always
- * be loaded. For use with {@link #CONTEXT_INCLUDE_CODE} to allow code
- * to be loaded into a process even when it isn't safe to do so. Use
- * with extreme care!
- */
- public static final int CONTEXT_IGNORE_SECURITY = 0x00000002;
-
- /**
- * Return a new Context object for the given application name. This
- * Context is the same as what the named application gets when it is
- * launched, containing the same resources and class loader. Each call to
- * this method returns a new instance of a Context object; Context objects
- * are not shared, however they share common state (Resources, ClassLoader,
- * etc) so the Context instance itself is fairly lightweight.
- *
- * <p>Throws {@link PackageManager.NameNotFoundException} if there is no
- * application with the given package name.
- *
- * <p>Throws {@link java.lang.SecurityException} if the Context requested
- * can not be loaded into the caller's process for security reasons (see
- * {@link #CONTEXT_INCLUDE_CODE} for more information}.
- *
- * @param packageName Name of the application's package.
- * @param flags Option flags, one of {@link #CONTEXT_INCLUDE_CODE}
- * or {@link #CONTEXT_IGNORE_SECURITY}.
- *
- * @return A Context for the application.
- *
- * @throws java.lang.SecurityException
- * @throws PackageManager.NameNotFoundException if there is no application with
- * the given package name
- */
- public abstract Context createPackageContext(String packageName,
- int flags) throws PackageManager.NameNotFoundException;
-}
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
deleted file mode 100644
index 36e1c34..0000000
--- a/core/java/android/content/ContextWrapper.java
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.content.pm.PackageManager;
-import android.content.res.AssetManager;
-import android.content.res.Resources;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.graphics.Bitmap;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-/**
- * Proxying implementation of Context that simply delegates all of its calls to
- * another Context. Can be subclassed to modify behavior without changing
- * the original Context.
- */
-public class ContextWrapper extends Context {
- Context mBase;
-
- public ContextWrapper(Context base) {
- mBase = base;
- }
-
- /**
- * Set the base context for this ContextWrapper. All calls will then be
- * delegated to the base context. Throws
- * IllegalStateException if a base context has already been set.
- *
- * @param base The new base context for this wrapper.
- */
- protected void attachBaseContext(Context base) {
- if (mBase != null) {
- throw new IllegalStateException("Base context already set");
- }
- mBase = base;
- }
-
- /**
- * @return the base context as set by the constructor or setBaseContext
- */
- public Context getBaseContext() {
- return mBase;
- }
-
- @Override
- public AssetManager getAssets() {
- return mBase.getAssets();
- }
-
- @Override
- public Resources getResources()
- {
- return mBase.getResources();
- }
-
- @Override
- public PackageManager getPackageManager() {
- return mBase.getPackageManager();
- }
-
- @Override
- public ContentResolver getContentResolver() {
- return mBase.getContentResolver();
- }
-
- @Override
- public Looper getMainLooper() {
- return mBase.getMainLooper();
- }
-
- @Override
- public Context getApplicationContext() {
- return mBase.getApplicationContext();
- }
-
- @Override
- public void setTheme(int resid) {
- mBase.setTheme(resid);
- }
-
- @Override
- public Resources.Theme getTheme() {
- return mBase.getTheme();
- }
-
- @Override
- public ClassLoader getClassLoader() {
- return mBase.getClassLoader();
- }
-
- @Override
- public String getPackageName() {
- return mBase.getPackageName();
- }
-
- @Override
- public String getPackageResourcePath() {
- return mBase.getPackageResourcePath();
- }
-
- @Override
- public String getPackageCodePath() {
- return mBase.getPackageCodePath();
- }
-
- @Override
- public SharedPreferences getSharedPreferences(String name, int mode) {
- return mBase.getSharedPreferences(name, mode);
- }
-
- @Override
- public FileInputStream openFileInput(String name)
- throws FileNotFoundException {
- return mBase.openFileInput(name);
- }
-
- @Override
- public FileOutputStream openFileOutput(String name, int mode)
- throws FileNotFoundException {
- return mBase.openFileOutput(name, mode);
- }
-
- @Override
- public boolean deleteFile(String name) {
- return mBase.deleteFile(name);
- }
-
- @Override
- public File getFileStreamPath(String name) {
- return mBase.getFileStreamPath(name);
- }
-
- @Override
- public String[] fileList() {
- return mBase.fileList();
- }
-
- @Override
- public File getFilesDir() {
- return mBase.getFilesDir();
- }
-
- @Override
- public File getCacheDir() {
- return mBase.getCacheDir();
- }
-
- @Override
- public File getDir(String name, int mode) {
- return mBase.getDir(name, mode);
- }
-
- @Override
- public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
- return mBase.openOrCreateDatabase(name, mode, factory);
- }
-
- @Override
- public boolean deleteDatabase(String name) {
- return mBase.deleteDatabase(name);
- }
-
- @Override
- public File getDatabasePath(String name) {
- return mBase.getDatabasePath(name);
- }
-
- @Override
- public String[] databaseList() {
- return mBase.databaseList();
- }
-
- @Override
- public Drawable getWallpaper() {
- return mBase.getWallpaper();
- }
-
- @Override
- public Drawable peekWallpaper() {
- return mBase.peekWallpaper();
- }
-
- @Override
- public int getWallpaperDesiredMinimumWidth() {
- return mBase.getWallpaperDesiredMinimumWidth();
- }
-
- @Override
- public int getWallpaperDesiredMinimumHeight() {
- return mBase.getWallpaperDesiredMinimumHeight();
- }
-
- @Override
- public void setWallpaper(Bitmap bitmap) throws IOException {
- mBase.setWallpaper(bitmap);
- }
-
- @Override
- public void setWallpaper(InputStream data) throws IOException {
- mBase.setWallpaper(data);
- }
-
- @Override
- public void clearWallpaper() throws IOException {
- mBase.clearWallpaper();
- }
-
- @Override
- public void startActivity(Intent intent) {
- mBase.startActivity(intent);
- }
-
- @Override
- public void sendBroadcast(Intent intent) {
- mBase.sendBroadcast(intent);
- }
-
- @Override
- public void sendBroadcast(Intent intent, String receiverPermission) {
- mBase.sendBroadcast(intent, receiverPermission);
- }
-
- @Override
- public void sendOrderedBroadcast(Intent intent,
- String receiverPermission) {
- mBase.sendOrderedBroadcast(intent, receiverPermission);
- }
-
- @Override
- public void sendOrderedBroadcast(
- Intent intent, String receiverPermission, BroadcastReceiver resultReceiver,
- Handler scheduler, int initialCode, String initialData,
- Bundle initialExtras) {
- mBase.sendOrderedBroadcast(intent, receiverPermission,
- resultReceiver, scheduler, initialCode,
- initialData, initialExtras);
- }
-
- @Override
- public void sendStickyBroadcast(Intent intent) {
- mBase.sendStickyBroadcast(intent);
- }
-
- @Override
- public void removeStickyBroadcast(Intent intent) {
- mBase.removeStickyBroadcast(intent);
- }
-
- @Override
- public Intent registerReceiver(
- BroadcastReceiver receiver, IntentFilter filter) {
- return mBase.registerReceiver(receiver, filter);
- }
-
- @Override
- public Intent registerReceiver(
- BroadcastReceiver receiver, IntentFilter filter,
- String broadcastPermission, Handler scheduler) {
- return mBase.registerReceiver(receiver, filter, broadcastPermission,
- scheduler);
- }
-
- @Override
- public void unregisterReceiver(BroadcastReceiver receiver) {
- mBase.unregisterReceiver(receiver);
- }
-
- @Override
- public ComponentName startService(Intent service) {
- return mBase.startService(service);
- }
-
- @Override
- public boolean stopService(Intent name) {
- return mBase.stopService(name);
- }
-
- @Override
- public boolean bindService(Intent service, ServiceConnection conn,
- int flags) {
- return mBase.bindService(service, conn, flags);
- }
-
- @Override
- public void unbindService(ServiceConnection conn) {
- mBase.unbindService(conn);
- }
-
- @Override
- public boolean startInstrumentation(ComponentName className,
- String profileFile, Bundle arguments) {
- return mBase.startInstrumentation(className, profileFile, arguments);
- }
-
- @Override
- public Object getSystemService(String name) {
- return mBase.getSystemService(name);
- }
-
- @Override
- public int checkPermission(String permission, int pid, int uid) {
- return mBase.checkPermission(permission, pid, uid);
- }
-
- @Override
- public int checkCallingPermission(String permission) {
- return mBase.checkCallingPermission(permission);
- }
-
- @Override
- public int checkCallingOrSelfPermission(String permission) {
- return mBase.checkCallingOrSelfPermission(permission);
- }
-
- @Override
- public void enforcePermission(
- String permission, int pid, int uid, String message) {
- mBase.enforcePermission(permission, pid, uid, message);
- }
-
- @Override
- public void enforceCallingPermission(String permission, String message) {
- mBase.enforceCallingPermission(permission, message);
- }
-
- @Override
- public void enforceCallingOrSelfPermission(
- String permission, String message) {
- mBase.enforceCallingOrSelfPermission(permission, message);
- }
-
- @Override
- public void grantUriPermission(String toPackage, Uri uri, int modeFlags) {
- mBase.grantUriPermission(toPackage, uri, modeFlags);
- }
-
- @Override
- public void revokeUriPermission(Uri uri, int modeFlags) {
- mBase.revokeUriPermission(uri, modeFlags);
- }
-
- @Override
- public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
- return mBase.checkUriPermission(uri, pid, uid, modeFlags);
- }
-
- @Override
- public int checkCallingUriPermission(Uri uri, int modeFlags) {
- return mBase.checkCallingUriPermission(uri, modeFlags);
- }
-
- @Override
- public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
- return mBase.checkCallingOrSelfUriPermission(uri, modeFlags);
- }
-
- @Override
- public int checkUriPermission(Uri uri, String readPermission,
- String writePermission, int pid, int uid, int modeFlags) {
- return mBase.checkUriPermission(uri, readPermission, writePermission,
- pid, uid, modeFlags);
- }
-
- @Override
- public void enforceUriPermission(
- Uri uri, int pid, int uid, int modeFlags, String message) {
- mBase.enforceUriPermission(uri, pid, uid, modeFlags, message);
- }
-
- @Override
- public void enforceCallingUriPermission(
- Uri uri, int modeFlags, String message) {
- mBase.enforceCallingUriPermission(uri, modeFlags, message);
- }
-
- @Override
- public void enforceCallingOrSelfUriPermission(
- Uri uri, int modeFlags, String message) {
- mBase.enforceCallingOrSelfUriPermission(uri, modeFlags, message);
- }
-
- @Override
- public void enforceUriPermission(
- Uri uri, String readPermission, String writePermission,
- int pid, int uid, int modeFlags, String message) {
- mBase.enforceUriPermission(
- uri, readPermission, writePermission, pid, uid, modeFlags,
- message);
- }
-
- @Override
- public Context createPackageContext(String packageName, int flags)
- throws PackageManager.NameNotFoundException {
- return mBase.createPackageContext(packageName, flags);
- }
-}
diff --git a/core/java/android/content/DefaultDataHandler.java b/core/java/android/content/DefaultDataHandler.java
deleted file mode 100644
index 863c9f6..0000000
--- a/core/java/android/content/DefaultDataHandler.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.net.Uri;
-import android.util.Xml;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Stack;
-
-/**
- * Inserts default data from InputStream, should be in XML format.
- * If the provider syncs data to the server, the imported data will be synced to the server.
- * <p>Samples:</p>
- * <br/>
- * Insert one row:
- * <pre>
- * &lt;row uri="content://contacts/people">
- * &lt;Col column = "name" value = "foo feebe "/>
- * &lt;Col column = "addr" value = "Tx"/>
- * &lt;/row></pre>
- * <br/>
- * Delete, it must be in order of uri, select, and arg:
- * <pre>
- * &lt;del uri="content://contacts/people" select="name=? and addr=?"
- * arg1 = "foo feebe" arg2 ="Tx"/></pre>
- * <br/>
- * Use first row's uri to insert into another table,
- * content://contacts/people/1/phones:
- * <pre>
- * &lt;row uri="content://contacts/people">
- * &lt;col column = "name" value = "foo feebe"/>
- * &lt;col column = "addr" value = "Tx"/>
- * &lt;row postfix="phones">
- * &lt;col column="number" value="512-514-6535"/>
- * &lt;/row>
- * &lt;row postfix="phones">
- * &lt;col column="cell" value="512-514-6535"/>
- * &lt;/row>
- * &lt;/row></pre>
- * <br/>
- * Insert multiple rows in to same table and same attributes:
- * <pre>
- * &lt;row uri="content://contacts/people" >
- * &lt;row>
- * &lt;col column= "name" value = "foo feebe"/>
- * &lt;col column= "addr" value = "Tx"/>
- * &lt;/row>
- * &lt;row>
- * &lt;/row>
- * &lt;/row></pre>
- *
- * @hide
- */
-public class DefaultDataHandler implements ContentInsertHandler {
- private final static String ROW = "row";
- private final static String COL = "col";
- private final static String URI_STR = "uri";
- private final static String POSTFIX = "postfix";
- private final static String DEL = "del";
- private final static String SELECT = "select";
- private final static String ARG = "arg";
-
- private Stack<Uri> mUris = new Stack<Uri>();
- private ContentValues mValues;
- private ContentResolver mContentResolver;
-
- public void insert(ContentResolver contentResolver, InputStream in)
- throws IOException, SAXException {
- mContentResolver = contentResolver;
- Xml.parse(in, Xml.Encoding.UTF_8, this);
- }
-
- public void insert(ContentResolver contentResolver, String in)
- throws SAXException {
- mContentResolver = contentResolver;
- Xml.parse(in, this);
- }
-
- private void parseRow(Attributes atts) throws SAXException {
- String uriStr = atts.getValue(URI_STR);
- Uri uri;
- if (uriStr != null) {
- // case 1
- uri = Uri.parse(uriStr);
- if (uri == null) {
- throw new SAXException("attribute " +
- atts.getValue(URI_STR) + " parsing failure");
- }
-
- } else if (mUris.size() > 0){
- // case 2
- String postfix = atts.getValue(POSTFIX);
- if (postfix != null) {
- uri = Uri.withAppendedPath(mUris.lastElement(),
- postfix);
- } else {
- uri = mUris.lastElement();
- }
- } else {
- throw new SAXException("attribute parsing failure");
- }
-
- mUris.push(uri);
-
- }
-
- private Uri insertRow() {
- Uri u = mContentResolver.insert(mUris.lastElement(), mValues);
- mValues = null;
- return u;
- }
-
- public void startElement(String uri, String localName, String name,
- Attributes atts) throws SAXException {
- if (ROW.equals(localName)) {
- if (mValues != null) {
- // case 2, <Col> before <Row> insert last uri
- if (mUris.empty()) {
- throw new SAXException("uri is empty");
- }
- Uri nextUri = insertRow();
- if (nextUri == null) {
- throw new SAXException("insert to uri " +
- mUris.lastElement().toString() + " failure");
- } else {
- // make sure the stack lastElement save uri for more than one row
- mUris.pop();
- mUris.push(nextUri);
- parseRow(atts);
- }
- } else {
- int attrLen = atts.getLength();
- if (attrLen == 0) {
- // case 3, share same uri as last level
- mUris.push(mUris.lastElement());
- } else {
- parseRow(atts);
- }
- }
- } else if (COL.equals(localName)) {
- int attrLen = atts.getLength();
- if (attrLen != 2) {
- throw new SAXException("illegal attributes number " + attrLen);
- }
- String key = atts.getValue(0);
- String value = atts.getValue(1);
- if (key != null && key.length() > 0 && value != null && value.length() > 0) {
- if (mValues == null) {
- mValues = new ContentValues();
- }
- mValues.put(key, value);
- } else {
- throw new SAXException("illegal attributes value");
- }
- } else if (DEL.equals(localName)){
- Uri u = Uri.parse(atts.getValue(URI_STR));
- if (u == null) {
- throw new SAXException("attribute " +
- atts.getValue(URI_STR) + " parsing failure");
- }
- int attrLen = atts.getLength() - 2;
- if (attrLen > 0) {
- String[] selectionArgs = new String[attrLen];
- for (int i = 0; i < attrLen; i++) {
- selectionArgs[i] = atts.getValue(i+2);
- }
- mContentResolver.delete(u, atts.getValue(1), selectionArgs);
- } else if (attrLen == 0){
- mContentResolver.delete(u, atts.getValue(1), null);
- } else {
- mContentResolver.delete(u, null, null);
- }
-
- } else {
- throw new SAXException("unknown element: " + localName);
- }
- }
-
- public void endElement(String uri, String localName, String name)
- throws SAXException {
- if (ROW.equals(localName)) {
- if (mUris.empty()) {
- throw new SAXException("uri mismatch");
- }
- if (mValues != null) {
- insertRow();
- }
- mUris.pop();
- }
- }
-
-
- public void characters(char[] ch, int start, int length)
- throws SAXException {
- // TODO Auto-generated method stub
-
- }
-
- public void endDocument() throws SAXException {
- // TODO Auto-generated method stub
-
- }
-
- public void endPrefixMapping(String prefix) throws SAXException {
- // TODO Auto-generated method stub
-
- }
-
- public void ignorableWhitespace(char[] ch, int start, int length)
- throws SAXException {
- // TODO Auto-generated method stub
-
- }
-
- public void processingInstruction(String target, String data)
- throws SAXException {
- // TODO Auto-generated method stub
-
- }
-
- public void setDocumentLocator(Locator locator) {
- // TODO Auto-generated method stub
-
- }
-
- public void skippedEntity(String name) throws SAXException {
- // TODO Auto-generated method stub
-
- }
-
- public void startDocument() throws SAXException {
- // TODO Auto-generated method stub
-
- }
-
- public void startPrefixMapping(String prefix, String uri)
- throws SAXException {
- // TODO Auto-generated method stub
-
- }
-
-}
diff --git a/core/java/android/content/DialogInterface.java b/core/java/android/content/DialogInterface.java
deleted file mode 100644
index 4afa294..0000000
--- a/core/java/android/content/DialogInterface.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.view.KeyEvent;
-
-/**
- *
- */
-public interface DialogInterface {
- /**
- * The identifier for the positive button.
- */
- public static final int BUTTON_POSITIVE = -1;
-
- /**
- * The identifier for the negative button.
- */
- public static final int BUTTON_NEGATIVE = -2;
-
- /**
- * The identifier for the neutral button.
- */
- public static final int BUTTON_NEUTRAL = -3;
-
- /**
- * @deprecated Use {@link #BUTTON_POSITIVE}
- */
- @Deprecated
- public static final int BUTTON1 = BUTTON_POSITIVE;
-
- /**
- * @deprecated Use {@link #BUTTON_NEGATIVE}
- */
- @Deprecated
- public static final int BUTTON2 = BUTTON_NEGATIVE;
-
- /**
- * @deprecated Use {@link #BUTTON_NEUTRAL}
- */
- @Deprecated
- public static final int BUTTON3 = BUTTON_NEUTRAL;
-
- public void cancel();
-
- public void dismiss();
-
- /**
- * Interface used to allow the creator of a dialog to run some code when the
- * dialog is canceled.
- * <p>
- * This will only be called when the dialog is canceled, if the creator
- * needs to know when it is dismissed in general, use
- * {@link DialogInterface.OnDismissListener}.
- */
- interface OnCancelListener {
- /**
- * This method will be invoked when the dialog is canceled.
- *
- * @param dialog The dialog that was canceled will be passed into the
- * method.
- */
- public void onCancel(DialogInterface dialog);
- }
-
- /**
- * Interface used to allow the creator of a dialog to run some code when the
- * dialog is dismissed.
- */
- interface OnDismissListener {
- /**
- * This method will be invoked when the dialog is dismissed.
- *
- * @param dialog The dialog that was dismissed will be passed into the
- * method.
- */
- public void onDismiss(DialogInterface dialog);
- }
-
- /**
- * Interface used to allow the creator of a dialog to run some code when an
- * item on the dialog is clicked..
- */
- interface OnClickListener {
- /**
- * This method will be invoked when a button in the dialog is clicked.
- *
- * @param dialog The dialog that received the click.
- * @param which The button that was clicked (e.g.
- * {@link DialogInterface#BUTTON1}) or the position
- * of the item clicked.
- */
- /* TODO: Change to use BUTTON_POSITIVE after API council */
- public void onClick(DialogInterface dialog, int which);
- }
-
- /**
- * Interface used to allow the creator of a dialog to run some code when an
- * item in a multi-choice dialog is clicked.
- */
- interface OnMultiChoiceClickListener {
- /**
- * This method will be invoked when an item in the dialog is clicked.
- *
- * @param dialog The dialog where the selection was made.
- * @param which The position of the item in the list that was clicked.
- * @param isChecked True if the click checked the item, else false.
- */
- public void onClick(DialogInterface dialog, int which, boolean isChecked);
- }
-
- /**
- * Interface definition for a callback to be invoked when a key event is
- * dispatched to this dialog. The callback will be invoked before the key
- * event is given to the dialog.
- */
- interface OnKeyListener {
- /**
- * Called when a key is dispatched to a dialog. This allows listeners to
- * get a chance to respond before the dialog.
- *
- * @param dialog The dialog the key has been dispatched to.
- * @param keyCode The code for the physical key that was pressed
- * @param event The KeyEvent object containing full information about
- * the event.
- * @return True if the listener has consumed the event, false otherwise.
- */
- public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event);
- }
-}
diff --git a/core/java/android/content/IContentProvider.java b/core/java/android/content/IContentProvider.java
deleted file mode 100644
index a6ef46f..0000000
--- a/core/java/android/content/IContentProvider.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.Cursor;
-import android.database.CursorWindow;
-import android.database.IBulkCursor;
-import android.database.IContentObserver;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.ParcelFileDescriptor;
-
-import java.io.FileNotFoundException;
-
-/**
- * The ipc interface to talk to a content provider.
- * @hide
- */
-public interface IContentProvider extends IInterface {
- /**
- * @hide - hide this because return type IBulkCursor and parameter
- * IContentObserver are system private classes.
- */
- public IBulkCursor bulkQuery(Uri url, String[] projection,
- String selection, String[] selectionArgs, String sortOrder, IContentObserver observer,
- CursorWindow window) throws RemoteException;
- public Cursor query(Uri url, String[] projection, String selection,
- String[] selectionArgs, String sortOrder) throws RemoteException;
- public String getType(Uri url) throws RemoteException;
- public Uri insert(Uri url, ContentValues initialValues)
- throws RemoteException;
- public int bulkInsert(Uri url, ContentValues[] initialValues) throws RemoteException;
- public int delete(Uri url, String selection, String[] selectionArgs)
- throws RemoteException;
- public int update(Uri url, ContentValues values, String selection,
- String[] selectionArgs) throws RemoteException;
- public ParcelFileDescriptor openFile(Uri url, String mode)
- throws RemoteException, FileNotFoundException;
- public ISyncAdapter getSyncAdapter() throws RemoteException;
-
- /* IPC constants */
- static final String descriptor = "android.content.IContentProvider";
-
- static final int QUERY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
- static final int GET_TYPE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
- static final int INSERT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 2;
- static final int DELETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 3;
- static final int UPDATE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 9;
- 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;
-}
diff --git a/core/java/android/content/IContentService.java b/core/java/android/content/IContentService.java
deleted file mode 100644
index a3047da..0000000
--- a/core/java/android/content/IContentService.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.IContentObserver;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Bundle;
-
-/**
- * {@hide}
- */
-public interface IContentService extends IInterface
-{
- public void registerContentObserver(Uri uri, boolean notifyForDescendentsn,
- IContentObserver observer) throws RemoteException;
- public void unregisterContentObserver(IContentObserver observer) throws RemoteException;
-
- public void notifyChange(Uri uri, IContentObserver observer,
- boolean observerWantsSelfNotifications, boolean syncToNetwork)
- throws RemoteException;
-
- public void startSync(Uri url, Bundle extras) throws RemoteException;
- public void cancelSync(Uri uri) throws RemoteException;
-
- static final String SERVICE_NAME = "content";
-
- /* IPC constants */
- static final String descriptor = "android.content.IContentService";
-
- static final int REGISTER_CONTENT_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
- static final int UNREGISTER_CHANGE_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 2;
- static final int NOTIFY_CHANGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 3;
- static final int START_SYNC_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 4;
- static final int CANCEL_SYNC_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 5;
-}
-
diff --git a/core/java/android/content/ISyncAdapter.aidl b/core/java/android/content/ISyncAdapter.aidl
deleted file mode 100644
index 671188c..0000000
--- a/core/java/android/content/ISyncAdapter.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.os.Bundle;
-import android.content.ISyncContext;
-
-/**
- * Interface used to control the sync activity on a SyncAdapter
- * @hide
- */
-oneway interface ISyncAdapter {
- /**
- * Initiate a sync for this account. SyncAdapter-specific parameters may
- * be specified in extras, which is guaranteed to not be null.
- *
- * @param syncContext the ISyncContext used to indicate the progress of the sync. When
- * the sync is finished (successfully or not) ISyncContext.onFinished() must be called.
- * @param account the account that should be synced
- * @param extras SyncAdapter-specific parameters
- */
- void startSync(ISyncContext syncContext, String account, in Bundle extras);
-
- /**
- * Cancel the most recently initiated sync. Due to race conditions, this may arrive
- * after the ISyncContext.onFinished() for that sync was called.
- */
- void cancelSync();
-}
diff --git a/core/java/android/content/ISyncContext.aidl b/core/java/android/content/ISyncContext.aidl
deleted file mode 100644
index 6d18a1c..0000000
--- a/core/java/android/content/ISyncContext.aidl
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.content.SyncResult;
-
-/**
- * Interface used by the SyncAdapter to indicate its progress.
- * @hide
- */
-interface ISyncContext {
- /**
- * Call to indicate that the SyncAdapter is making progress. E.g., if this SyncAdapter
- * downloads or sends records to/from the server, this may be called after each record
- * is downloaded or uploaded.
- */
- void sendHeartbeat();
-
- /**
- * Signal that the corresponding sync session is completed.
- * @param result information about this sync session
- */
- void onFinished(in SyncResult result);
-}
diff --git a/core/java/android/content/Intent.aidl b/core/java/android/content/Intent.aidl
deleted file mode 100644
index 568986b..0000000
--- a/core/java/android/content/Intent.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/content/Intent.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content;
-
-parcelable Intent;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
deleted file mode 100644
index c1c3b49..0000000
--- a/core/java/android/content/Intent.java
+++ /dev/null
@@ -1,4522 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-import android.util.Log;
-import com.android.internal.util.XmlUtils;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * An intent is an abstract description of an operation to be performed. It
- * can be used with {@link Context#startActivity(Intent) startActivity} to
- * launch an {@link android.app.Activity},
- * {@link android.content.Context#sendBroadcast(Intent) broadcastIntent} to
- * send it to any interested {@link BroadcastReceiver BroadcastReceiver} components,
- * and {@link android.content.Context#startService} or
- * {@link android.content.Context#bindService} to communicate with a
- * background {@link android.app.Service}.
- *
- * <p>An Intent provides a facility for performing late runtime binding between
- * the code in different applications. Its most significant use is in the
- * launching of activities, where it can be thought of as the glue between
- * activities. It is
- * basically a passive data structure holding an abstract description of an
- * action to be performed. The primary pieces of information in an intent
- * are:</p>
- *
- * <ul>
- * <li> <p><b>action</b> -- The general action to be performed, such as
- * {@link #ACTION_VIEW}, {@link #ACTION_EDIT}, {@link #ACTION_MAIN},
- * etc.</p>
- * </li>
- * <li> <p><b>data</b> -- The data to operate on, such as a person record
- * in the contacts database, expressed as a {@link android.net.Uri}.</p>
- * </li>
- * </ul>
- *
- *
- * <p>Some examples of action/data pairs are:</p>
- *
- * <ul>
- * <li> <p><b>{@link #ACTION_VIEW} <i>content://contacts/1</i></b> -- Display
- * information about the person whose identifier is "1".</p>
- * </li>
- * <li> <p><b>{@link #ACTION_DIAL} <i>content://contacts/1</i></b> -- Display
- * the phone dialer with the person filled in.</p>
- * </li>
- * <li> <p><b>{@link #ACTION_VIEW} <i>tel:123</i></b> -- Display
- * the phone dialer with the given number filled in. Note how the
- * VIEW action does what what is considered the most reasonable thing for
- * a particular URI.</p>
- * </li>
- * <li> <p><b>{@link #ACTION_DIAL} <i>tel:123</i></b> -- Display
- * the phone dialer with the given number filled in.</p>
- * </li>
- * <li> <p><b>{@link #ACTION_EDIT} <i>content://contacts/1</i></b> -- Edit
- * information about the person whose identifier is "1".</p>
- * </li>
- * <li> <p><b>{@link #ACTION_VIEW} <i>content://contacts/</i></b> -- Display
- * a list of people, which the user can browse through. This example is a
- * typical top-level entry into the Contacts application, showing you the
- * list of people. Selecting a particular person to view would result in a
- * new intent { <b>{@link #ACTION_VIEW} <i>content://contacts/N</i></b> }
- * being used to start an activity to display that person.</p>
- * </li>
- * </ul>
- *
- * <p>In addition to these primary attributes, there are a number of secondary
- * attributes that you can also include with an intent:</p>
- *
- * <ul>
- * <li> <p><b>category</b> -- Gives additional information about the action
- * to execute. For example, {@link #CATEGORY_LAUNCHER} means it should
- * appear in the Launcher as a top-level application, while
- * {@link #CATEGORY_ALTERNATIVE} means it should be included in a list
- * of alternative actions the user can perform on a piece of data.</p>
- * <li> <p><b>type</b> -- Specifies an explicit type (a MIME type) of the
- * intent data. Normally the type is inferred from the data itself.
- * By setting this attribute, you disable that evaluation and force
- * an explicit type.</p>
- * <li> <p><b>component</b> -- Specifies an explicit name of a component
- * class to use for the intent. Normally this is determined by looking
- * at the other information in the intent (the action, data/type, and
- * categories) and matching that with a component that can handle it.
- * If this attribute is set then none of the evaluation is performed,
- * and this component is used exactly as is. By specifying this attribute,
- * all of the other Intent attributes become optional.</p>
- * <li> <p><b>extras</b> -- This is a {@link Bundle} of any additional information.
- * This can be used to provide extended information to the component.
- * For example, if we have a action to send an e-mail message, we could
- * also include extra pieces of data here to supply a subject, body,
- * etc.</p>
- * </ul>
- *
- * <p>Here are some examples of other operations you can specify as intents
- * using these additional parameters:</p>
- *
- * <ul>
- * <li> <p><b>{@link #ACTION_MAIN} with category {@link #CATEGORY_HOME}</b> --
- * Launch the home screen.</p>
- * </li>
- * <li> <p><b>{@link #ACTION_GET_CONTENT} with MIME type
- * <i>{@link android.provider.Contacts.Phones#CONTENT_URI
- * vnd.android.cursor.item/phone}</i></b>
- * -- Display the list of people's phone numbers, allowing the user to
- * browse through them and pick one and return it to the parent activity.</p>
- * </li>
- * <li> <p><b>{@link #ACTION_GET_CONTENT} with MIME type
- * <i>*{@literal /}*</i> and category {@link #CATEGORY_OPENABLE}</b>
- * -- Display all pickers for data that can be opened with
- * {@link ContentResolver#openInputStream(Uri) ContentResolver.openInputStream()},
- * allowing the user to pick one of them and then some data inside of it
- * and returning the resulting URI to the caller. This can be used,
- * for example, in an e-mail application to allow the user to pick some
- * data to include as an attachment.</p>
- * </li>
- * </ul>
- *
- * <p>There are a variety of standard Intent action and category constants
- * defined in the Intent class, but applications can also define their own.
- * These strings use java style scoping, to ensure they are unique -- for
- * example, the standard {@link #ACTION_VIEW} is called
- * "android.app.action.VIEW".</p>
- *
- * <p>Put together, the set of actions, data types, categories, and extra data
- * defines a language for the system allowing for the expression of phrases
- * such as "call john smith's cell". As applications are added to the system,
- * they can extend this language by adding new actions, types, and categories, or
- * they can modify the behavior of existing phrases by supplying their own
- * activities that handle them.</p>
- *
- * <a name="IntentResolution"></a>
- * <h3>Intent Resolution</h3>
- *
- * <p>There are two primary forms of intents you will use.
- *
- * <ul>
- * <li> <p><b>Explicit Intents</b> have specified a component (via
- * {@link #setComponent} or {@link #setClass}), which provides the exact
- * class to be run. Often these will not include any other information,
- * simply being a way for an application to launch various internal
- * activities it has as the user interacts with the application.
- *
- * <li> <p><b>Implicit Intents</b> have not specified a component;
- * instead, they must include enough information for the system to
- * determine which of the available components is best to run for that
- * intent.
- * </ul>
- *
- * <p>When using implicit intents, given such an arbitrary intent we need to
- * know what to do with it. This is handled by the process of <em>Intent
- * resolution</em>, which maps an Intent to an {@link android.app.Activity},
- * {@link BroadcastReceiver}, or {@link android.app.Service} (or sometimes two or
- * more activities/receivers) that can handle it.</p>
- *
- * <p>The intent resolution mechanism basically revolves around matching an
- * Intent against all of the &lt;intent-filter&gt; descriptions in the
- * installed application packages. (Plus, in the case of broadcasts, any {@link BroadcastReceiver}
- * objects explicitly registered with {@link Context#registerReceiver}.) More
- * details on this can be found in the documentation on the {@link
- * IntentFilter} class.</p>
- *
- * <p>There are three pieces of information in the Intent that are used for
- * resolution: the action, type, and category. Using this information, a query
- * is done on the {@link PackageManager} for a component that can handle the
- * intent. The appropriate component is determined based on the intent
- * information supplied in the <code>AndroidManifest.xml</code> file as
- * follows:</p>
- *
- * <ul>
- * <li> <p>The <b>action</b>, if given, must be listed by the component as
- * one it handles.</p>
- * <li> <p>The <b>type</b> is retrieved from the Intent's data, if not
- * already supplied in the Intent. Like the action, if a type is
- * included in the intent (either explicitly or implicitly in its
- * data), then this must be listed by the component as one it handles.</p>
- * <li> For data that is not a <code>content:</code> URI and where no explicit
- * type is included in the Intent, instead the <b>scheme</b> of the
- * intent data (such as <code>http:</code> or <code>mailto:</code>) is
- * considered. Again like the action, if we are matching a scheme it
- * must be listed by the component as one it can handle.
- * <li> <p>The <b>categories</b>, if supplied, must <em>all</em> be listed
- * by the activity as categories it handles. That is, if you include
- * the categories {@link #CATEGORY_LAUNCHER} and
- * {@link #CATEGORY_ALTERNATIVE}, then you will only resolve to components
- * with an intent that lists <em>both</em> of those categories.
- * Activities will very often need to support the
- * {@link #CATEGORY_DEFAULT} so that they can be found by
- * {@link Context#startActivity Context.startActivity()}.</p>
- * </ul>
- *
- * <p>For example, consider the Note Pad sample application that
- * allows user to browse through a list of notes data and view details about
- * individual items. Text in italics indicate places were you would replace a
- * name with one specific to your own package.</p>
- *
- * <pre> &lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
- * package="<i>com.android.notepad</i>"&gt;
- * &lt;application android:icon="@drawable/app_notes"
- * android:label="@string/app_name"&gt;
- *
- * &lt;provider class=".NotePadProvider"
- * android:authorities="<i>com.google.provider.NotePad</i>" /&gt;
- *
- * &lt;activity class=".NotesList" android:label="@string/title_notes_list"&gt;
- * &lt;intent-filter&gt;
- * &lt;action android:value="android.intent.action.MAIN" /&gt;
- * &lt;category android:value="android.intent.category.LAUNCHER" /&gt;
- * &lt;/intent-filter&gt;
- * &lt;intent-filter&gt;
- * &lt;action android:value="android.intent.action.VIEW" /&gt;
- * &lt;action android:value="android.intent.action.EDIT" /&gt;
- * &lt;action android:value="android.intent.action.PICK" /&gt;
- * &lt;category android:value="android.intent.category.DEFAULT" /&gt;
- * &lt;type android:value="vnd.android.cursor.dir/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;
- * &lt;intent-filter&gt;
- * &lt;action android:value="android.intent.action.GET_CONTENT" /&gt;
- * &lt;category android:value="android.intent.category.DEFAULT" /&gt;
- * &lt;type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;
- * &lt;/activity&gt;
- *
- * &lt;activity class=".NoteEditor" android:label="@string/title_note"&gt;
- * &lt;intent-filter android:label="@string/resolve_edit"&gt;
- * &lt;action android:value="android.intent.action.VIEW" /&gt;
- * &lt;action android:value="android.intent.action.EDIT" /&gt;
- * &lt;category android:value="android.intent.category.DEFAULT" /&gt;
- * &lt;type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;
- *
- * &lt;intent-filter&gt;
- * &lt;action android:value="android.intent.action.INSERT" /&gt;
- * &lt;category android:value="android.intent.category.DEFAULT" /&gt;
- * &lt;type android:value="vnd.android.cursor.dir/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;
- *
- * &lt;/activity&gt;
- *
- * &lt;activity class=".TitleEditor" android:label="@string/title_edit_title"
- * android:theme="@android:style/Theme.Dialog"&gt;
- * &lt;intent-filter android:label="@string/resolve_title"&gt;
- * &lt;action android:value="<i>com.android.notepad.action.EDIT_TITLE</i>" /&gt;
- * &lt;category android:value="android.intent.category.DEFAULT" /&gt;
- * &lt;category android:value="android.intent.category.ALTERNATIVE" /&gt;
- * &lt;category android:value="android.intent.category.SELECTED_ALTERNATIVE" /&gt;
- * &lt;type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;
- * &lt;/activity&gt;
- *
- * &lt;/application&gt;
- * &lt;/manifest&gt;</pre>
- *
- * <p>The first activity,
- * <code>com.android.notepad.NotesList</code>, serves as our main
- * entry into the app. It can do three things as described by its three intent
- * templates:
- * <ol>
- * <li><pre>
- * &lt;intent-filter&gt;
- * &lt;action android:value="{@link #ACTION_MAIN android.intent.action.MAIN}" /&gt;
- * &lt;category android:value="{@link #CATEGORY_LAUNCHER android.intent.category.LAUNCHER}" /&gt;
- * &lt;/intent-filter&gt;</pre>
- * <p>This provides a top-level entry into the NotePad application: the standard
- * MAIN action is a main entry point (not requiring any other information in
- * the Intent), and the LAUNCHER category says that this entry point should be
- * listed in the application launcher.</p>
- * <li><pre>
- * &lt;intent-filter&gt;
- * &lt;action android:value="{@link #ACTION_VIEW android.intent.action.VIEW}" /&gt;
- * &lt;action android:value="{@link #ACTION_EDIT android.intent.action.EDIT}" /&gt;
- * &lt;action android:value="{@link #ACTION_PICK android.intent.action.PICK}" /&gt;
- * &lt;category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" /&gt;
- * &lt;type android:value="vnd.android.cursor.dir/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;</pre>
- * <p>This declares the things that the activity can do on a directory of
- * notes. The type being supported is given with the &lt;type&gt; tag, where
- * <code>vnd.android.cursor.dir/vnd.google.note</code> is a URI from which
- * a Cursor of zero or more items (<code>vnd.android.cursor.dir</code>) can
- * be retrieved which holds our note pad data (<code>vnd.google.note</code>).
- * The activity allows the user to view or edit the directory of data (via
- * the VIEW and EDIT actions), or to pick a particular note and return it
- * to the caller (via the PICK action). Note also the DEFAULT category
- * supplied here: this is <em>required</em> for the
- * {@link Context#startActivity Context.startActivity} method to resolve your
- * activity when its component name is not explicitly specified.</p>
- * <li><pre>
- * &lt;intent-filter&gt;
- * &lt;action android:value="{@link #ACTION_GET_CONTENT android.intent.action.GET_CONTENT}" /&gt;
- * &lt;category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" /&gt;
- * &lt;type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;</pre>
- * <p>This filter describes the ability return to the caller a note selected by
- * the user without needing to know where it came from. The data type
- * <code>vnd.android.cursor.item/vnd.google.note</code> is a URI from which
- * a Cursor of exactly one (<code>vnd.android.cursor.item</code>) item can
- * be retrieved which contains our note pad data (<code>vnd.google.note</code>).
- * The GET_CONTENT action is similar to the PICK action, where the activity
- * will return to its caller a piece of data selected by the user. Here,
- * however, the caller specifies the type of data they desire instead of
- * the type of data the user will be picking from.</p>
- * </ol>
- *
- * <p>Given these capabilities, the following intents will resolve to the
- * NotesList activity:</p>
- *
- * <ul>
- * <li> <p><b>{ action=android.app.action.MAIN }</b> matches all of the
- * activities that can be used as top-level entry points into an
- * application.</p>
- * <li> <p><b>{ action=android.app.action.MAIN,
- * category=android.app.category.LAUNCHER }</b> is the actual intent
- * used by the Launcher to populate its top-level list.</p>
- * <li> <p><b>{ action=android.app.action.VIEW
- * data=content://com.google.provider.NotePad/notes }</b>
- * displays a list of all the notes under
- * "content://com.google.provider.NotePad/notes", which
- * the user can browse through and see the details on.</p>
- * <li> <p><b>{ action=android.app.action.PICK
- * data=content://com.google.provider.NotePad/notes }</b>
- * provides a list of the notes under
- * "content://com.google.provider.NotePad/notes", from which
- * the user can pick a note whose data URL is returned back to the caller.</p>
- * <li> <p><b>{ action=android.app.action.GET_CONTENT
- * type=vnd.android.cursor.item/vnd.google.note }</b>
- * is similar to the pick action, but allows the caller to specify the
- * kind of data they want back so that the system can find the appropriate
- * activity to pick something of that data type.</p>
- * </ul>
- *
- * <p>The second activity,
- * <code>com.android.notepad.NoteEditor</code>, shows the user a single
- * note entry and allows them to edit it. It can do two things as described
- * by its two intent templates:
- * <ol>
- * <li><pre>
- * &lt;intent-filter android:label="@string/resolve_edit"&gt;
- * &lt;action android:value="{@link #ACTION_VIEW android.intent.action.VIEW}" /&gt;
- * &lt;action android:value="{@link #ACTION_EDIT android.intent.action.EDIT}" /&gt;
- * &lt;category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" /&gt;
- * &lt;type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;</pre>
- * <p>The first, primary, purpose of this activity is to let the user interact
- * with a single note, as decribed by the MIME type
- * <code>vnd.android.cursor.item/vnd.google.note</code>. The activity can
- * either VIEW a note or allow the user to EDIT it. Again we support the
- * DEFAULT category to allow the activity to be launched without explicitly
- * specifying its component.</p>
- * <li><pre>
- * &lt;intent-filter&gt;
- * &lt;action android:value="{@link #ACTION_INSERT android.intent.action.INSERT}" /&gt;
- * &lt;category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" /&gt;
- * &lt;type android:value="vnd.android.cursor.dir/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;</pre>
- * <p>The secondary use of this activity is to insert a new note entry into
- * an existing directory of notes. This is used when the user creates a new
- * note: the INSERT action is executed on the directory of notes, causing
- * this activity to run and have the user create the new note data which
- * it then adds to the content provider.</p>
- * </ol>
- *
- * <p>Given these capabilities, the following intents will resolve to the
- * NoteEditor activity:</p>
- *
- * <ul>
- * <li> <p><b>{ action=android.app.action.VIEW
- * data=content://com.google.provider.NotePad/notes/<var>{ID}</var> }</b>
- * shows the user the content of note <var>{ID}</var>.</p>
- * <li> <p><b>{ action=android.app.action.EDIT
- * data=content://com.google.provider.NotePad/notes/<var>{ID}</var> }</b>
- * allows the user to edit the content of note <var>{ID}</var>.</p>
- * <li> <p><b>{ action=android.app.action.INSERT
- * data=content://com.google.provider.NotePad/notes }</b>
- * creates a new, empty note in the notes list at
- * "content://com.google.provider.NotePad/notes"
- * and allows the user to edit it. If they keep their changes, the URI
- * of the newly created note is returned to the caller.</p>
- * </ul>
- *
- * <p>The last activity,
- * <code>com.android.notepad.TitleEditor</code>, allows the user to
- * edit the title of a note. This could be implemented as a class that the
- * application directly invokes (by explicitly setting its component in
- * the Intent), but here we show a way you can publish alternative
- * operations on existing data:</p>
- *
- * <pre>
- * &lt;intent-filter android:label="@string/resolve_title"&gt;
- * &lt;action android:value="<i>com.android.notepad.action.EDIT_TITLE</i>" /&gt;
- * &lt;category android:value="{@link #CATEGORY_DEFAULT android.intent.category.DEFAULT}" /&gt;
- * &lt;category android:value="{@link #CATEGORY_ALTERNATIVE android.intent.category.ALTERNATIVE}" /&gt;
- * &lt;category android:value="{@link #CATEGORY_SELECTED_ALTERNATIVE android.intent.category.SELECTED_ALTERNATIVE}" /&gt;
- * &lt;type android:value="vnd.android.cursor.item/<i>vnd.google.note</i>" /&gt;
- * &lt;/intent-filter&gt;</pre>
- *
- * <p>In the single intent template here, we
- * have created our own private action called
- * <code>com.android.notepad.action.EDIT_TITLE</code> which means to
- * edit the title of a note. It must be invoked on a specific note
- * (data type <code>vnd.android.cursor.item/vnd.google.note</code>) like the previous
- * view and edit actions, but here displays and edits the title contained
- * in the note data.
- *
- * <p>In addition to supporting the default category as usual, our title editor
- * also supports two other standard categories: ALTERNATIVE and
- * SELECTED_ALTERNATIVE. Implementing
- * these categories allows others to find the special action it provides
- * without directly knowing about it, through the
- * {@link android.content.pm.PackageManager#queryIntentActivityOptions} method, or
- * more often to build dynamic menu items with
- * {@link android.view.Menu#addIntentOptions}. Note that in the intent
- * template here was also supply an explicit name for the template
- * (via <code>android:label="@string/resolve_title"</code>) to better control
- * what the user sees when presented with this activity as an alternative
- * action to the data they are viewing.
- *
- * <p>Given these capabilities, the following intent will resolve to the
- * TitleEditor activity:</p>
- *
- * <ul>
- * <li> <p><b>{ action=com.android.notepad.action.EDIT_TITLE
- * data=content://com.google.provider.NotePad/notes/<var>{ID}</var> }</b>
- * displays and allows the user to edit the title associated
- * with note <var>{ID}</var>.</p>
- * </ul>
- *
- * <h3>Standard Activity Actions</h3>
- *
- * <p>These are the current standard actions that Intent defines for launching
- * activities (usually through {@link Context#startActivity}. The most
- * important, and by far most frequently used, are {@link #ACTION_MAIN} and
- * {@link #ACTION_EDIT}.
- *
- * <ul>
- * <li> {@link #ACTION_MAIN}
- * <li> {@link #ACTION_VIEW}
- * <li> {@link #ACTION_ATTACH_DATA}
- * <li> {@link #ACTION_EDIT}
- * <li> {@link #ACTION_PICK}
- * <li> {@link #ACTION_CHOOSER}
- * <li> {@link #ACTION_GET_CONTENT}
- * <li> {@link #ACTION_DIAL}
- * <li> {@link #ACTION_CALL}
- * <li> {@link #ACTION_SEND}
- * <li> {@link #ACTION_SENDTO}
- * <li> {@link #ACTION_ANSWER}
- * <li> {@link #ACTION_INSERT}
- * <li> {@link #ACTION_DELETE}
- * <li> {@link #ACTION_RUN}
- * <li> {@link #ACTION_SYNC}
- * <li> {@link #ACTION_PICK_ACTIVITY}
- * <li> {@link #ACTION_SEARCH}
- * <li> {@link #ACTION_WEB_SEARCH}
- * <li> {@link #ACTION_FACTORY_TEST}
- * </ul>
- *
- * <h3>Standard Broadcast Actions</h3>
- *
- * <p>These are the current standard actions that Intent defines for receiving
- * broadcasts (usually through {@link Context#registerReceiver} or a
- * &lt;receiver&gt; tag in a manifest).
- *
- * <ul>
- * <li> {@link #ACTION_TIME_TICK}
- * <li> {@link #ACTION_TIME_CHANGED}
- * <li> {@link #ACTION_TIMEZONE_CHANGED}
- * <li> {@link #ACTION_BOOT_COMPLETED}
- * <li> {@link #ACTION_PACKAGE_ADDED}
- * <li> {@link #ACTION_PACKAGE_CHANGED}
- * <li> {@link #ACTION_PACKAGE_REMOVED}
- * <li> {@link #ACTION_PACKAGE_RESTARTED}
- * <li> {@link #ACTION_PACKAGE_DATA_CLEARED}
- * <li> {@link #ACTION_UID_REMOVED}
- * <li> {@link #ACTION_BATTERY_CHANGED}
- * </ul>
- *
- * <h3>Standard Categories</h3>
- *
- * <p>These are the current standard categories that can be used to further
- * clarify an Intent via {@link #addCategory}.
- *
- * <ul>
- * <li> {@link #CATEGORY_DEFAULT}
- * <li> {@link #CATEGORY_BROWSABLE}
- * <li> {@link #CATEGORY_TAB}
- * <li> {@link #CATEGORY_ALTERNATIVE}
- * <li> {@link #CATEGORY_SELECTED_ALTERNATIVE}
- * <li> {@link #CATEGORY_LAUNCHER}
- * <li> {@link #CATEGORY_HOME}
- * <li> {@link #CATEGORY_PREFERENCE}
- * <li> {@link #CATEGORY_GADGET}
- * <li> {@link #CATEGORY_TEST}
- * </ul>
- *
- * <h3>Standard Extra Data</h3>
- *
- * <p>These are the current standard fields that can be used as extra data via
- * {@link #putExtra}.
- *
- * <ul>
- * <li> {@link #EXTRA_TEMPLATE}
- * <li> {@link #EXTRA_INTENT}
- * <li> {@link #EXTRA_STREAM}
- * <li> {@link #EXTRA_TEXT}
- * </ul>
- *
- * <h3>Flags</h3>
- *
- * <p>These are the possible flags that can be used in the Intent via
- * {@link #setFlags} and {@link #addFlags}. See {@link #setFlags} for a list
- * of all possible flags.
- */
-public class Intent implements Parcelable {
- // ---------------------------------------------------------------------
- // ---------------------------------------------------------------------
- // Standard intent activity actions (see action variable).
-
- /**
- * Activity Action: Start as a main entry point, does not expect to
- * receive data.
- * <p>Input: nothing
- * <p>Output: nothing
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_MAIN = "android.intent.action.MAIN";
-
- /**
- * Activity Action: Display the data to the user. This is the most common
- * action performed on data -- it is the generic action you can use on
- * a piece of data to get the most reasonable thing to occur. For example,
- * when used on a contacts entry it will view the entry; when used on a
- * mailto: URI it will bring up a compose window filled with the information
- * supplied by the URI; when used with a tel: URI it will invoke the
- * dialer.
- * <p>Input: {@link #getData} is URI from which to retrieve data.
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_VIEW = "android.intent.action.VIEW";
-
- /**
- * A synonym for {@link #ACTION_VIEW}, the "standard" action that is
- * performed on a piece of data.
- */
- public static final String ACTION_DEFAULT = ACTION_VIEW;
-
- /**
- * Used to indicate that some piece of data should be attached to some other
- * place. For example, image data could be attached to a contact. It is up
- * to the recipient to decide where the data should be attached; the intent
- * does not specify the ultimate destination.
- * <p>Input: {@link #getData} is URI of data to be attached.
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_ATTACH_DATA = "android.intent.action.ATTACH_DATA";
-
- /**
- * Activity Action: Provide explicit editable access to the given data.
- * <p>Input: {@link #getData} is URI of data to be edited.
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_EDIT = "android.intent.action.EDIT";
-
- /**
- * Activity Action: Pick an existing item, or insert a new item, and then edit it.
- * <p>Input: {@link #getType} is the desired MIME type of the item to create or edit.
- * The extras can contain type specific data to pass through to the editing/creating
- * activity.
- * <p>Output: The URI of the item that was picked. This must be a content:
- * URI so that any receiver can access it.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_INSERT_OR_EDIT = "android.intent.action.INSERT_OR_EDIT";
-
- /**
- * Activity Action: Pick an item from the data, returning what was selected.
- * <p>Input: {@link #getData} is URI containing a directory of data
- * (vnd.android.cursor.dir/*) from which to pick an item.
- * <p>Output: The URI of the item that was picked.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_PICK = "android.intent.action.PICK";
-
- /**
- * Activity Action: Creates a shortcut.
- * <p>Input: Nothing.</p>
- * <p>Output: An Intent representing the shortcut. The intent must contain three
- * extras: SHORTCUT_INTENT (value: Intent), SHORTCUT_NAME (value: String),
- * and SHORTCUT_ICON (value: Bitmap) or SHORTCUT_ICON_RESOURCE
- * (value: ShortcutIconResource).</p>
- *
- * @see #EXTRA_SHORTCUT_INTENT
- * @see #EXTRA_SHORTCUT_NAME
- * @see #EXTRA_SHORTCUT_ICON
- * @see #EXTRA_SHORTCUT_ICON_RESOURCE
- * @see android.content.Intent.ShortcutIconResource
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_CREATE_SHORTCUT = "android.intent.action.CREATE_SHORTCUT";
-
- /**
- * The name of the extra used to define the Intent of a shortcut.
- *
- * @see #ACTION_CREATE_SHORTCUT
- */
- public static final String EXTRA_SHORTCUT_INTENT = "android.intent.extra.shortcut.INTENT";
- /**
- * The name of the extra used to define the name of a shortcut.
- *
- * @see #ACTION_CREATE_SHORTCUT
- */
- public static final String EXTRA_SHORTCUT_NAME = "android.intent.extra.shortcut.NAME";
- /**
- * The name of the extra used to define the icon, as a Bitmap, of a shortcut.
- *
- * @see #ACTION_CREATE_SHORTCUT
- */
- public static final String EXTRA_SHORTCUT_ICON = "android.intent.extra.shortcut.ICON";
- /**
- * The name of the extra used to define the icon, as a ShortcutIconResource, of a shortcut.
- *
- * @see #ACTION_CREATE_SHORTCUT
- * @see android.content.Intent.ShortcutIconResource
- */
- public static final String EXTRA_SHORTCUT_ICON_RESOURCE =
- "android.intent.extra.shortcut.ICON_RESOURCE";
-
- /**
- * Represents a shortcut/live folder icon resource.
- *
- * @see Intent#ACTION_CREATE_SHORTCUT
- * @see Intent#EXTRA_SHORTCUT_ICON_RESOURCE
- * @see android.provider.LiveFolders#ACTION_CREATE_LIVE_FOLDER
- * @see android.provider.LiveFolders#EXTRA_LIVE_FOLDER_ICON
- */
- public static class ShortcutIconResource implements Parcelable {
- /**
- * The package name of the application containing the icon.
- */
- public String packageName;
-
- /**
- * The resource name of the icon, including package, name and type.
- */
- public String resourceName;
-
- /**
- * Creates a new ShortcutIconResource for the specified context and resource
- * identifier.
- *
- * @param context The context of the application.
- * @param resourceId The resource idenfitier for the icon.
- * @return A new ShortcutIconResource with the specified's context package name
- * and icon resource idenfitier.
- */
- public static ShortcutIconResource fromContext(Context context, int resourceId) {
- ShortcutIconResource icon = new ShortcutIconResource();
- icon.packageName = context.getPackageName();
- icon.resourceName = context.getResources().getResourceName(resourceId);
- return icon;
- }
-
- /**
- * Used to read a ShortcutIconResource from a Parcel.
- */
- public static final Parcelable.Creator<ShortcutIconResource> CREATOR =
- new Parcelable.Creator<ShortcutIconResource>() {
-
- public ShortcutIconResource createFromParcel(Parcel source) {
- ShortcutIconResource icon = new ShortcutIconResource();
- icon.packageName = source.readString();
- icon.resourceName = source.readString();
- return icon;
- }
-
- public ShortcutIconResource[] newArray(int size) {
- return new ShortcutIconResource[size];
- }
- };
-
- /**
- * No special parcel contents.
- */
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(packageName);
- dest.writeString(resourceName);
- }
-
- @Override
- public String toString() {
- return resourceName;
- }
- }
-
- /**
- * Activity Action: Display an activity chooser, allowing the user to pick
- * what they want to before proceeding. This can be used as an alternative
- * to the standard activity picker that is displayed by the system when
- * you try to start an activity with multiple possible matches, with these
- * differences in behavior:
- * <ul>
- * <li>You can specify the title that will appear in the activity chooser.
- * <li>The user does not have the option to make one of the matching
- * activities a preferred activity, and all possible activities will
- * always be shown even if one of them is currently marked as the
- * preferred activity.
- * </ul>
- * <p>
- * This action should be used when the user will naturally expect to
- * select an activity in order to proceed. An example if when not to use
- * it is when the user clicks on a "mailto:" link. They would naturally
- * expect to go directly to their mail app, so startActivity() should be
- * called directly: it will
- * either launch the current preferred app, or put up a dialog allowing the
- * user to pick an app to use and optionally marking that as preferred.
- * <p>
- * In contrast, if the user is selecting a menu item to send a picture
- * they are viewing to someone else, there are many different things they
- * may want to do at this point: send it through e-mail, upload it to a
- * web service, etc. In this case the CHOOSER action should be used, to
- * always present to the user a list of the things they can do, with a
- * nice title given by the caller such as "Send this photo with:".
- * <p>
- * As a convenience, an Intent of this form can be created with the
- * {@link #createChooser} function.
- * <p>Input: No data should be specified. get*Extra must have
- * a {@link #EXTRA_INTENT} field containing the Intent being executed,
- * and can optionally have a {@link #EXTRA_TITLE} field containing the
- * title text to display in the chooser.
- * <p>Output: Depends on the protocol of {@link #EXTRA_INTENT}.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_CHOOSER = "android.intent.action.CHOOSER";
-
- /**
- * Convenience function for creating a {@link #ACTION_CHOOSER} Intent.
- *
- * @param target The Intent that the user will be selecting an activity
- * to perform.
- * @param title Optional title that will be displayed in the chooser.
- * @return Return a new Intent object that you can hand to
- * {@link Context#startActivity(Intent) Context.startActivity()} and
- * related methods.
- */
- public static Intent createChooser(Intent target, CharSequence title) {
- Intent intent = new Intent(ACTION_CHOOSER);
- intent.putExtra(EXTRA_INTENT, target);
- if (title != null) {
- intent.putExtra(EXTRA_TITLE, title);
- }
- return intent;
- }
- /**
- * Activity Action: Allow the user to select a particular kind of data and
- * return it. This is different than {@link #ACTION_PICK} in that here we
- * just say what kind of data is desired, not a URI of existing data from
- * which the user can pick. A ACTION_GET_CONTENT could allow the user to
- * create the data as it runs (for example taking a picture or recording a
- * sound), let them browser over the web and download the desired data,
- * etc.
- * <p>
- * There are two main ways to use this action: if you want an specific kind
- * of data, such as a person contact, you set the MIME type to the kind of
- * data you want and launch it with {@link Context#startActivity(Intent)}.
- * The system will then launch the best application to select that kind
- * of data for you.
- * <p>
- * You may also be interested in any of a set of types of content the user
- * can pick. For example, an e-mail application that wants to allow the
- * user to add an attachment to an e-mail message can use this action to
- * bring up a list of all of the types of content the user can attach.
- * <p>
- * In this case, you should wrap the GET_CONTENT intent with a chooser
- * (through {@link #createChooser}), which will give the proper interface
- * for the user to pick how to send your data and allow you to specify
- * a prompt indicating what they are doing. You will usually specify a
- * broad MIME type (such as image/* or {@literal *}/*), resulting in a
- * broad range of content types the user can select from.
- * <p>
- * When using such a broad GET_CONTENT action, it is often desireable to
- * only pick from data that can be represented as a stream. This is
- * accomplished by requiring the {@link #CATEGORY_OPENABLE} in the Intent.
- * <p>
- * Input: {@link #getType} is the desired MIME type to retrieve. Note
- * that no URI is supplied in the intent, as there are no constraints on
- * where the returned data originally comes from. You may also include the
- * {@link #CATEGORY_OPENABLE} if you can only accept data that can be
- * opened as a stream.
- * <p>
- * Output: The URI of the item that was picked. This must be a content:
- * URI so that any receiver can access it.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_GET_CONTENT = "android.intent.action.GET_CONTENT";
- /**
- * Activity Action: Dial a number as specified by the data. This shows a
- * UI with the number being dialed, allowing the user to explicitly
- * initiate the call.
- * <p>Input: If nothing, an empty dialer is started; else {@link #getData}
- * is URI of a phone number to be dialed or a tel: URI of an explicit phone
- * number.
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_DIAL = "android.intent.action.DIAL";
- /**
- * Activity Action: Perform a call to someone specified by the data.
- * <p>Input: If nothing, an empty dialer is started; else {@link #getData}
- * is URI of a phone number to be dialed or a tel: URI of an explicit phone
- * number.
- * <p>Output: nothing.
- *
- * <p>Note: there will be restrictions on which applications can initiate a
- * call; most applications should use the {@link #ACTION_DIAL}.
- * <p>Note: this Intent <strong>cannot</strong> be used to call emergency
- * numbers. Applications can <strong>dial</strong> emergency numbers using
- * {@link #ACTION_DIAL}, however.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_CALL = "android.intent.action.CALL";
- /**
- * Activity Action: Perform a call to an emergency number specified by the
- * data.
- * <p>Input: {@link #getData} is URI of a phone number to be dialed or a
- * tel: URI of an explicit phone number.
- * <p>Output: nothing.
- * @hide
- */
- public static final String ACTION_CALL_EMERGENCY = "android.intent.action.CALL_EMERGENCY";
- /**
- * Activity action: Perform a call to any number (emergency or not)
- * specified by the data.
- * <p>Input: {@link #getData} is URI of a phone number to be dialed or a
- * tel: URI of an explicit phone number.
- * <p>Output: nothing.
- * @hide
- */
- public static final String ACTION_CALL_PRIVILEGED = "android.intent.action.CALL_PRIVILEGED";
- /**
- * Activity Action: Send a message to someone specified by the data.
- * <p>Input: {@link #getData} is URI describing the target.
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_SENDTO = "android.intent.action.SENDTO";
- /**
- * Activity Action: Deliver some data to someone else. Who the data is
- * being delivered to is not specified; it is up to the receiver of this
- * action to ask the user where the data should be sent.
- * <p>
- * When launching a SEND intent, you should usually wrap it in a chooser
- * (through {@link #createChooser}), which will give the proper interface
- * for the user to pick how to send your data and allow you to specify
- * a prompt indicating what they are doing.
- * <p>
- * Input: {@link #getType} is the MIME type of the data being sent.
- * get*Extra can have either a {@link #EXTRA_TEXT}
- * or {@link #EXTRA_STREAM} field, containing the data to be sent. If
- * using EXTRA_TEXT, the MIME type should be "text/plain"; otherwise it
- * should be the MIME type of the data in EXTRA_STREAM. Use {@literal *}/*
- * if the MIME type is unknown (this will only allow senders that can
- * handle generic data streams).
- * <p>
- * Optional standard extras, which may be interpreted by some recipients as
- * appropriate, are: {@link #EXTRA_EMAIL}, {@link #EXTRA_CC},
- * {@link #EXTRA_BCC}, {@link #EXTRA_SUBJECT}.
- * <p>
- * Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_SEND = "android.intent.action.SEND";
- /**
- * Activity Action: Handle an incoming phone call.
- * <p>Input: nothing.
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_ANSWER = "android.intent.action.ANSWER";
- /**
- * Activity Action: Insert an empty item into the given container.
- * <p>Input: {@link #getData} is URI of the directory (vnd.android.cursor.dir/*)
- * in which to place the data.
- * <p>Output: URI of the new data that was created.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_INSERT = "android.intent.action.INSERT";
- /**
- * Activity Action: Delete the given data from its container.
- * <p>Input: {@link #getData} is URI of data to be deleted.
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_DELETE = "android.intent.action.DELETE";
- /**
- * Activity Action: Run the data, whatever that means.
- * <p>Input: ? (Note: this is currently specific to the test harness.)
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_RUN = "android.intent.action.RUN";
- /**
- * Activity Action: Perform a data synchronization.
- * <p>Input: ?
- * <p>Output: ?
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_SYNC = "android.intent.action.SYNC";
- /**
- * Activity Action: Pick an activity given an intent, returning the class
- * selected.
- * <p>Input: get*Extra field {@link #EXTRA_INTENT} is an Intent
- * used with {@link PackageManager#queryIntentActivities} to determine the
- * set of activities from which to pick.
- * <p>Output: Class name of the activity that was selected.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_PICK_ACTIVITY = "android.intent.action.PICK_ACTIVITY";
- /**
- * Activity Action: Perform a search.
- * <p>Input: {@link android.app.SearchManager#QUERY getStringExtra(SearchManager.QUERY)}
- * is the text to search for. If empty, simply
- * enter your search results Activity with the search UI activated.
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_SEARCH = "android.intent.action.SEARCH";
- /**
- * Activity Action: Perform a web search.
- * <p>
- * Input: {@link android.app.SearchManager#QUERY
- * getStringExtra(SearchManager.QUERY)} is the text to search for. If it is
- * a url starts with http or https, the site will be opened. If it is plain
- * text, Google search will be applied.
- * <p>
- * Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
- /**
- * Activity Action: List all available applications
- * <p>Input: Nothing.
- * <p>Output: nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_ALL_APPS = "android.intent.action.ALL_APPS";
- /**
- * Activity Action: Show settings for choosing wallpaper
- * <p>Input: Nothing.
- * <p>Output: Nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_SET_WALLPAPER = "android.intent.action.SET_WALLPAPER";
-
- /**
- * Activity Action: Show activity for reporting a bug.
- * <p>Input: Nothing.
- * <p>Output: Nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_BUG_REPORT = "android.intent.action.BUG_REPORT";
-
- /**
- * Activity Action: Main entry point for factory tests. Only used when
- * the device is booting in factory test node. The implementing package
- * must be installed in the system image.
- * <p>Input: nothing
- * <p>Output: nothing
- */
- public static final String ACTION_FACTORY_TEST = "android.intent.action.FACTORY_TEST";
-
- /**
- * Activity Action: The user pressed the "call" button to go to the dialer
- * or other appropriate UI for placing a call.
- * <p>Input: Nothing.
- * <p>Output: Nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_CALL_BUTTON = "android.intent.action.CALL_BUTTON";
-
- /**
- * Activity Action: Start Voice Command.
- * <p>Input: Nothing.
- * <p>Output: Nothing.
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_VOICE_COMMAND = "android.intent.action.VOICE_COMMAND";
-
- // ---------------------------------------------------------------------
- // ---------------------------------------------------------------------
- // Standard intent broadcast actions (see action variable).
-
- /**
- * Broadcast Action: Sent after the screen turns off.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_SCREEN_OFF = "android.intent.action.SCREEN_OFF";
- /**
- * Broadcast Action: Sent after the screen turns on.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_SCREEN_ON = "android.intent.action.SCREEN_ON";
- /**
- * Broadcast Action: The current time has changed. Sent every
- * minute. You can <em>not</em> receive this through components declared
- * in manifests, only by exlicitly registering for it with
- * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
- * Context.registerReceiver()}.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TIME_TICK = "android.intent.action.TIME_TICK";
- /**
- * Broadcast Action: The time was set.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TIME_CHANGED = "android.intent.action.TIME_SET";
- /**
- * Broadcast Action: The date has changed.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED";
- /**
- * Broadcast Action: The timezone has changed. The intent will have the following extra values:</p>
- * <ul>
- * <li><em>time-zone</em> - The java.util.TimeZone.getID() value identifying the new time zone.</li>
- * </ul>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_TIMEZONE_CHANGED = "android.intent.action.TIMEZONE_CHANGED";
- /**
- * Alarm Changed Action: This is broadcast when the AlarmClock
- * application's alarm is set or unset. It is used by the
- * AlarmClock application and the StatusBar service.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_ALARM_CHANGED = "android.intent.action.ALARM_CHANGED";
- /**
- * Sync State Changed Action: This is broadcast when the sync starts or stops or when one has
- * been failing for a long time. It is used by the SyncManager and the StatusBar service.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_SYNC_STATE_CHANGED
- = "android.intent.action.SYNC_STATE_CHANGED";
- /**
- * Broadcast Action: This is broadcast once, after the system has finished
- * booting. It can be used to perform application-specific initialization,
- * such as installing alarms. You must hold the
- * {@link android.Manifest.permission#RECEIVE_BOOT_COMPLETED} permission
- * in order to receive this broadcast.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
- /**
- * Broadcast Action: This is broadcast when a user action should request a
- * temporary system dialog to dismiss. Some examples of temporary system
- * dialogs are the notification window-shade and the recent tasks dialog.
- */
- public static final String ACTION_CLOSE_SYSTEM_DIALOGS = "android.intent.action.CLOSE_SYSTEM_DIALOGS";
- /**
- * Broadcast Action: Trigger the download and eventual installation
- * of a package.
- * <p>Input: {@link #getData} is the URI of the package file to download.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL";
- /**
- * Broadcast Action: A new application package has been installed on the
- * device. The data contains the name of the package.
- * <p>My include the following extras:
- * <ul>
- * <li> {@link #EXTRA_UID} containing the integer uid assigned to the new package.
- * <li> {@link #EXTRA_REPLACING} is set to true if this is following
- * an {@link #ACTION_PACKAGE_REMOVED} broadcast for the same package.
- * </ul>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_PACKAGE_ADDED = "android.intent.action.PACKAGE_ADDED";
- /**
- * Broadcast Action: An existing application package has been removed from
- * the device. The data contains the name of the package. The package
- * that is being installed does <em>not</em> receive this Intent.
- * <ul>
- * <li> {@link #EXTRA_UID} containing the integer uid previously assigned
- * to the package.
- * <li> {@link #EXTRA_DATA_REMOVED} is set to true if the entire
- * application -- data and code -- is being removed.
- * <li> {@link #EXTRA_REPLACING} is set to true if this will be followed
- * by an {@link #ACTION_PACKAGE_ADDED} broadcast for the same package.
- * </ul>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_PACKAGE_REMOVED = "android.intent.action.PACKAGE_REMOVED";
- /**
- * Broadcast Action: An existing application package has been changed (e.g. a component has been
- * enabled or disabled. The data contains the name of the package.
- * <ul>
- * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package.
- * </ul>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_PACKAGE_CHANGED = "android.intent.action.PACKAGE_CHANGED";
- /**
- * Broadcast Action: The user has restarted a package, and all of its
- * processes have been killed. All runtime state
- * associated with it (processes, alarms, notifications, etc) should
- * be removed. The data contains the name of the package.
- * <ul>
- * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package.
- * </ul>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_PACKAGE_RESTARTED = "android.intent.action.PACKAGE_RESTARTED";
- /**
- * Broadcast Action: The user has cleared the data of a package. This should
- * be preceded by {@link #ACTION_PACKAGE_RESTARTED}, after which all of
- * its persistent data is erased and this broadcast sent. The data contains
- * the name of the package.
- * <ul>
- * <li> {@link #EXTRA_UID} containing the integer uid assigned to the package.
- * </ul>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_PACKAGE_DATA_CLEARED = "android.intent.action.PACKAGE_DATA_CLEARED";
- /**
- * Broadcast Action: A user ID has been removed from the system. The user
- * ID number is stored in the extra data under {@link #EXTRA_UID}.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_UID_REMOVED = "android.intent.action.UID_REMOVED";
- /**
- * Broadcast Action: The current system wallpaper has changed. See
- * {@link Context#getWallpaper} for retrieving the new wallpaper.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_WALLPAPER_CHANGED = "android.intent.action.WALLPAPER_CHANGED";
- /**
- * Broadcast Action: The current device {@link android.content.res.Configuration}
- * (orientation, locale, etc) has changed. When such a change happens, the
- * UIs (view hierarchy) will need to be rebuilt based on this new
- * information; for the most part, applications don't need to worry about
- * this, because the system will take care of stopping and restarting the
- * application to make sure it sees the new changes. Some system code that
- * can not be restarted will need to watch for this action and handle it
- * appropriately.
- *
- * @see android.content.res.Configuration
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED";
- /**
- * Broadcast Action: The charging state, or charge level of the battery has
- * changed.
- *
- * <p class="note">
- * You can <em>not</em> receive this through components declared
- * in manifests, only by exlicitly registering for it with
- * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
- * Context.registerReceiver()}.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_BATTERY_CHANGED = "android.intent.action.BATTERY_CHANGED";
- /**
- * Broadcast Action: Indicates low battery condition on the device.
- * This broadcast corresponds to the "Low battery warning" system dialog.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
- /**
- * Broadcast Action: Indicates low memory condition on the device
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW";
- /**
- * Broadcast Action: Indicates low memory condition on the device no longer exists
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK";
- /**
- * Broadcast Action: Indicates low memory condition notification acknowledged by user
- * and package management should be started.
- * This is triggered by the user from the ACTION_DEVICE_STORAGE_LOW
- * notification.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE";
- /**
- * Broadcast Action: The device has entered USB Mass Storage mode.
- * This is used mainly for the USB Settings panel.
- * Apps should listen for ACTION_MEDIA_MOUNTED and ACTION_MEDIA_UNMOUNTED broadcasts to be notified
- * when the SD card file system is mounted or unmounted
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_UMS_CONNECTED = "android.intent.action.UMS_CONNECTED";
-
- /**
- * Broadcast Action: The device has exited USB Mass Storage mode.
- * This is used mainly for the USB Settings panel.
- * Apps should listen for ACTION_MEDIA_MOUNTED and ACTION_MEDIA_UNMOUNTED broadcasts to be notified
- * when the SD card file system is mounted or unmounted
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_UMS_DISCONNECTED = "android.intent.action.UMS_DISCONNECTED";
-
- /**
- * Broadcast Action: External media has been removed.
- * The path to the mount point for the removed media is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_REMOVED = "android.intent.action.MEDIA_REMOVED";
-
- /**
- * Broadcast Action: External media is present, but not mounted at its mount point.
- * The path to the mount point for the removed media is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_UNMOUNTED = "android.intent.action.MEDIA_UNMOUNTED";
-
- /**
- * Broadcast Action: External media is present, and being disk-checked
- * The path to the mount point for the checking media is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_CHECKING = "android.intent.action.MEDIA_CHECKING";
-
- /**
- * Broadcast Action: External media is present, but is using an incompatible fs (or is blank)
- * The path to the mount point for the checking media is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_NOFS = "android.intent.action.MEDIA_NOFS";
-
- /**
- * Broadcast Action: External media is present and mounted at its mount point.
- * The path to the mount point for the removed media is contained in the Intent.mData field.
- * The Intent contains an extra with name "read-only" and Boolean value to indicate if the
- * media was mounted read only.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_MOUNTED = "android.intent.action.MEDIA_MOUNTED";
-
- /**
- * Broadcast Action: External media is unmounted because it is being shared via USB mass storage.
- * The path to the mount point for the removed media is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_SHARED = "android.intent.action.MEDIA_SHARED";
-
- /**
- * Broadcast Action: External media was removed from SD card slot, but mount point was not unmounted.
- * The path to the mount point for the removed media is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_BAD_REMOVAL = "android.intent.action.MEDIA_BAD_REMOVAL";
-
- /**
- * Broadcast Action: External media is present but cannot be mounted.
- * The path to the mount point for the removed media is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_UNMOUNTABLE = "android.intent.action.MEDIA_UNMOUNTABLE";
-
- /**
- * Broadcast Action: User has expressed the desire to remove the external storage media.
- * Applications should close all files they have open within the mount point when they receive this intent.
- * The path to the mount point for the media to be ejected is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_EJECT = "android.intent.action.MEDIA_EJECT";
-
- /**
- * Broadcast Action: The media scanner has started scanning a directory.
- * The path to the directory being scanned is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_SCANNER_STARTED = "android.intent.action.MEDIA_SCANNER_STARTED";
-
- /**
- * Broadcast Action: The media scanner has finished scanning a directory.
- * The path to the scanned directory is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_SCANNER_FINISHED = "android.intent.action.MEDIA_SCANNER_FINISHED";
-
- /**
- * Broadcast Action: Request the media scanner to scan a file and add it to the media database.
- * The path to the file is contained in the Intent.mData field.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_SCANNER_SCAN_FILE = "android.intent.action.MEDIA_SCANNER_SCAN_FILE";
-
- /**
- * Broadcast Action: The "Media Button" was pressed. Includes a single
- * extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that
- * caused the broadcast.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_MEDIA_BUTTON = "android.intent.action.MEDIA_BUTTON";
-
- /**
- * Broadcast Action: The "Camera Button" was pressed. Includes a single
- * extra field, {@link #EXTRA_KEY_EVENT}, containing the key event that
- * caused the broadcast.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_CAMERA_BUTTON = "android.intent.action.CAMERA_BUTTON";
-
- // *** NOTE: @todo(*) The following really should go into a more domain-specific
- // location; they are not general-purpose actions.
-
- /**
- * Broadcast Action: An GTalk connection has been established.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_GTALK_SERVICE_CONNECTED =
- "android.intent.action.GTALK_CONNECTED";
-
- /**
- * Broadcast Action: An GTalk connection has been disconnected.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_GTALK_SERVICE_DISCONNECTED =
- "android.intent.action.GTALK_DISCONNECTED";
-
- /**
- * Broadcast Action: An input method has been changed.
- * {@hide pending API Council approval}
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_INPUT_METHOD_CHANGED =
- "android.intent.action.INPUT_METHOD_CHANGED";
-
- /**
- * <p>Broadcast Action: The user has switched the phone into or out of Airplane Mode. One or
- * more radios have been turned off or on. The intent will have the following extra value:</p>
- * <ul>
- * <li><em>state</em> - A boolean value indicating whether Airplane Mode is on. If true,
- * then cell radio and possibly other radios such as bluetooth or WiFi may have also been
- * turned off</li>
- * </ul>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_AIRPLANE_MODE_CHANGED = "android.intent.action.AIRPLANE_MODE";
-
- /**
- * Broadcast Action: Some content providers have parts of their namespace
- * where they publish new events or items that the user may be especially
- * interested in. For these things, they may broadcast this action when the
- * set of interesting items change.
- *
- * For example, GmailProvider sends this notification when the set of unread
- * mail in the inbox changes.
- *
- * <p>The data of the intent identifies which part of which provider
- * changed. When queried through the content resolver, the data URI will
- * return the data set in question.
- *
- * <p>The intent will have the following extra values:
- * <ul>
- * <li><em>count</em> - The number of items in the data set. This is the
- * same as the number of items in the cursor returned by querying the
- * data URI. </li>
- * </ul>
- *
- * This intent will be sent at boot (if the count is non-zero) and when the
- * data set changes. It is possible for the data set to change without the
- * count changing (for example, if a new unread message arrives in the same
- * sync operation in which a message is archived). The phone should still
- * ring/vibrate/etc as normal in this case.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_PROVIDER_CHANGED =
- "android.intent.action.PROVIDER_CHANGED";
-
- /**
- * Broadcast Action: Wired Headset plugged in or unplugged.
- *
- * <p>The intent will have the following extra values:
- * <ul>
- * <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
- * <li><em>name</em> - Headset type, human readable string </li>
- * </ul>
- * </ul>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_HEADSET_PLUG =
- "android.intent.action.HEADSET_PLUG";
-
- /**
- * Broadcast Action: An outgoing call is about to be placed.
- *
- * <p>The Intent will have the following extra value:
- * <ul>
- * <li><em>{@link android.content.Intent#EXTRA_PHONE_NUMBER}</em> -
- * the phone number originally intended to be dialed.</li>
- * </ul>
- * <p>Once the broadcast is finished, the resultData is used as the actual
- * number to call. If <code>null</code>, no call will be placed.</p>
- * <p>It is perfectly acceptable for multiple receivers to process the
- * outgoing call in turn: for example, a parental control application
- * might verify that the user is authorized to place the call at that
- * time, then a number-rewriting application might add an area code if
- * one was not specified.</p>
- * <p>For consistency, any receiver whose purpose is to prohibit phone
- * calls should have a priority of 0, to ensure it will see the final
- * phone number to be dialed.
- * Any receiver whose purpose is to rewrite phone numbers to be called
- * should have a positive priority.
- * Negative priorities are reserved for the system for this broadcast;
- * using them may cause problems.</p>
- * <p>Any BroadcastReceiver receiving this Intent <em>must not</em>
- * abort the broadcast.</p>
- * <p>Emergency calls cannot be intercepted using this mechanism, and
- * other calls cannot be modified to call emergency numbers using this
- * mechanism.
- * <p>You must hold the
- * {@link android.Manifest.permission#PROCESS_OUTGOING_CALLS}
- * permission to receive this Intent.</p>
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_NEW_OUTGOING_CALL =
- "android.intent.action.NEW_OUTGOING_CALL";
-
- /**
- * Broadcast Action: Have the device reboot. This is only for use by
- * system code.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_REBOOT =
- "android.intent.action.REBOOT";
-
- // ---------------------------------------------------------------------
- // ---------------------------------------------------------------------
- // Standard intent categories (see addCategory()).
-
- /**
- * Set if the activity should be an option for the default action
- * (center press) to perform on a piece of data. Setting this will
- * hide from the user any activities without it set when performing an
- * action on some data. Note that this is normal -not- set in the
- * Intent when initiating an action -- it is for use in intent filters
- * specified in packages.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_DEFAULT = "android.intent.category.DEFAULT";
- /**
- * Activities that can be safely invoked from a browser must support this
- * category. For example, if the user is viewing a web page or an e-mail
- * and clicks on a link in the text, the Intent generated execute that
- * link will require the BROWSABLE category, so that only activities
- * supporting this category will be considered as possible actions. By
- * supporting this category, you are promising that there is nothing
- * damaging (without user intervention) that can happen by invoking any
- * matching Intent.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_BROWSABLE = "android.intent.category.BROWSABLE";
- /**
- * Set if the activity should be considered as an alternative action to
- * the data the user is currently viewing. See also
- * {@link #CATEGORY_SELECTED_ALTERNATIVE} for an alternative action that
- * applies to the selection in a list of items.
- *
- * <p>Supporting this category means that you would like your activity to be
- * displayed in the set of alternative things the user can do, usually as
- * part of the current activity's options menu. You will usually want to
- * include a specific label in the &lt;intent-filter&gt; of this action
- * describing to the user what it does.
- *
- * <p>The action of IntentFilter with this category is important in that it
- * describes the specific action the target will perform. This generally
- * should not be a generic action (such as {@link #ACTION_VIEW}, but rather
- * a specific name such as "com.android.camera.action.CROP. Only one
- * alternative of any particular action will be shown to the user, so using
- * a specific action like this makes sure that your alternative will be
- * displayed while also allowing other applications to provide their own
- * overrides of that particular action.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_ALTERNATIVE = "android.intent.category.ALTERNATIVE";
- /**
- * Set if the activity should be considered as an alternative selection
- * action to the data the user has currently selected. This is like
- * {@link #CATEGORY_ALTERNATIVE}, but is used in activities showing a list
- * of items from which the user can select, giving them alternatives to the
- * default action that will be performed on it.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_SELECTED_ALTERNATIVE = "android.intent.category.SELECTED_ALTERNATIVE";
- /**
- * Intended to be used as a tab inside of an containing TabActivity.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_TAB = "android.intent.category.TAB";
- /**
- * This activity can be embedded inside of another activity that is hosting
- * gadgets.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_GADGET = "android.intent.category.GADGET";
- /**
- * Should be displayed in the top-level launcher.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_LAUNCHER = "android.intent.category.LAUNCHER";
- /**
- * This is the home activity, that is the first activity that is displayed
- * when the device boots.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_HOME = "android.intent.category.HOME";
- /**
- * This activity is a preference panel.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_PREFERENCE = "android.intent.category.PREFERENCE";
- /**
- * This activity is a development preference panel.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_DEVELOPMENT_PREFERENCE = "android.intent.category.DEVELOPMENT_PREFERENCE";
- /**
- * Capable of running inside a parent activity container.
- *
- * <p>Note: being removed in favor of more explicit categories such as
- * CATEGORY_GADGET
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_EMBED = "android.intent.category.EMBED";
- /**
- * This activity may be exercised by the monkey or other automated test tools.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_MONKEY = "android.intent.category.MONKEY";
- /**
- * To be used as a test (not part of the normal user experience).
- */
- public static final String CATEGORY_TEST = "android.intent.category.TEST";
- /**
- * To be used as a unit test (run through the Test Harness).
- */
- public static final String CATEGORY_UNIT_TEST = "android.intent.category.UNIT_TEST";
- /**
- * To be used as an sample code example (not part of the normal user
- * experience).
- */
- public static final String CATEGORY_SAMPLE_CODE = "android.intent.category.SAMPLE_CODE";
- /**
- * Used to indicate that a GET_CONTENT intent only wants URIs that can be opened with
- * ContentResolver.openInputStream. Openable URIs must support the columns in OpenableColumns
- * when queried, though it is allowable for those columns to be blank.
- */
- @SdkConstant(SdkConstantType.INTENT_CATEGORY)
- public static final String CATEGORY_OPENABLE = "android.intent.category.OPENABLE";
-
- /**
- * To be used as code under test for framework instrumentation tests.
- */
- public static final String CATEGORY_FRAMEWORK_INSTRUMENTATION_TEST =
- "android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST";
- // ---------------------------------------------------------------------
- // ---------------------------------------------------------------------
- // Standard extra data keys.
-
- /**
- * The initial data to place in a newly created record. Use with
- * {@link #ACTION_INSERT}. The data here is a Map containing the same
- * fields as would be given to the underlying ContentProvider.insert()
- * call.
- */
- public static final String EXTRA_TEMPLATE = "android.intent.extra.TEMPLATE";
-
- /**
- * A constant CharSequence that is associated with the Intent, used with
- * {@link #ACTION_SEND} to supply the literal data to be sent. Note that
- * this may be a styled CharSequence, so you must use
- * {@link Bundle#getCharSequence(String) Bundle.getCharSequence()} to
- * retrieve it.
- */
- public static final String EXTRA_TEXT = "android.intent.extra.TEXT";
-
- /**
- * A content: URI holding a stream of data associated with the Intent,
- * used with {@link #ACTION_SEND} to supply the data being sent.
- */
- public static final String EXTRA_STREAM = "android.intent.extra.STREAM";
-
- /**
- * A String[] holding e-mail addresses that should be delivered to.
- */
- public static final String EXTRA_EMAIL = "android.intent.extra.EMAIL";
-
- /**
- * A String[] holding e-mail addresses that should be carbon copied.
- */
- public static final String EXTRA_CC = "android.intent.extra.CC";
-
- /**
- * A String[] holding e-mail addresses that should be blind carbon copied.
- */
- public static final String EXTRA_BCC = "android.intent.extra.BCC";
-
- /**
- * A constant string holding the desired subject line of a message.
- */
- public static final String EXTRA_SUBJECT = "android.intent.extra.SUBJECT";
-
- /**
- * An Intent describing the choices you would like shown with
- * {@link #ACTION_PICK_ACTIVITY}.
- */
- public static final String EXTRA_INTENT = "android.intent.extra.INTENT";
-
- /**
- * A CharSequence dialog title to provide to the user when used with a
- * {@link #ACTION_CHOOSER}.
- */
- public static final String EXTRA_TITLE = "android.intent.extra.TITLE";
-
- /**
- * A {@link android.view.KeyEvent} object containing the event that
- * triggered the creation of the Intent it is in.
- */
- public static final String EXTRA_KEY_EVENT = "android.intent.extra.KEY_EVENT";
-
- /**
- * Used as an boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED} or
- * {@link android.content.Intent#ACTION_PACKAGE_CHANGED} intents to override the default action
- * of restarting the application.
- */
- public static final String EXTRA_DONT_KILL_APP = "android.intent.extra.DONT_KILL_APP";
-
- /**
- * A String holding the phone number originally entered in
- * {@link android.content.Intent#ACTION_NEW_OUTGOING_CALL}, or the actual
- * number to call in a {@link android.content.Intent#ACTION_CALL}.
- */
- public static final String EXTRA_PHONE_NUMBER = "android.intent.extra.PHONE_NUMBER";
- /**
- * Used as an int extra field in {@link android.content.Intent#ACTION_UID_REMOVED}
- * intents to supply the uid the package had been assigned. Also an optional
- * extra in {@link android.content.Intent#ACTION_PACKAGE_REMOVED} or
- * {@link android.content.Intent#ACTION_PACKAGE_CHANGED} for the same
- * purpose.
- */
- public static final String EXTRA_UID = "android.intent.extra.UID";
-
- /**
- * Used as a boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED}
- * intents to indicate whether this represents a full uninstall (removing
- * both the code and its data) or a partial uninstall (leaving its data,
- * implying that this is an update).
- */
- public static final String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED";
-
- /**
- * Used as a boolean extra field in {@link android.content.Intent#ACTION_PACKAGE_REMOVED}
- * intents to indicate that this is a replacement of the package, so this
- * broadcast will immediately be followed by an add broadcast for a
- * different version of the same package.
- */
- public static final String EXTRA_REPLACING = "android.intent.extra.REPLACING";
-
- /**
- * Used as an int extra field in {@link android.app.AlarmManager} intents
- * to tell the application being invoked how many pending alarms are being
- * delievered with the intent. For one-shot alarms this will always be 1.
- * For recurring alarms, this might be greater than 1 if the device was
- * asleep or powered off at the time an earlier alarm would have been
- * delivered.
- */
- public static final String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
-
- /**
- * Used as an int extra field in {@link android.content.Intent#ACTION_VOICE_COMMAND}
- * intents to request which audio route the voice command should prefer.
- * The value should be a route from {@link android.media.AudioManager}, for
- * example ROUTE_BLUETOOTH_SCO. Providing this value is optional.
- * {@hide pending API Council approval}
- */
- public static final String EXTRA_AUDIO_ROUTE = "android.intent.extra.AUDIO_ROUTE";
-
- // ---------------------------------------------------------------------
- // ---------------------------------------------------------------------
- // Intent flags (see mFlags variable).
-
- /**
- * If set, the recipient of this Intent will be granted permission to
- * perform read operations on the Uri in the Intent's data.
- */
- public static final int FLAG_GRANT_READ_URI_PERMISSION = 0x00000001;
- /**
- * If set, the recipient of this Intent will be granted permission to
- * perform write operations on the Uri in the Intent's data.
- */
- public static final int FLAG_GRANT_WRITE_URI_PERMISSION = 0x00000002;
- /**
- * Can be set by the caller to indicate that this Intent is coming from
- * a background operation, not from direct user interaction.
- */
- public static final int FLAG_FROM_BACKGROUND = 0x00000004;
- /**
- * A flag you can enable for debugging: when set, log messages will be
- * printed during the resolution of this intent to show you what has
- * been found to create the final resolved list.
- */
- public static final int FLAG_DEBUG_LOG_RESOLUTION = 0x00000008;
-
- /**
- * If set, the new activity is not kept in the history stack. As soon as
- * the user navigates away from it, the activity is finished. This may also
- * be set with the {@link android.R.styleable#AndroidManifestActivity_noHistory
- * noHistory} attribute.
- */
- public static final int FLAG_ACTIVITY_NO_HISTORY = 0x40000000;
- /**
- * If set, the activity will not be launched if it is already running
- * at the top of the history stack.
- */
- public static final int FLAG_ACTIVITY_SINGLE_TOP = 0x20000000;
- /**
- * If set, this activity will become the start of a new task on this
- * history stack. A task (from the activity that started it to the
- * next task activity) defines an atomic group of activities that the
- * user can move to. Tasks can be moved to the foreground and background;
- * all of the activities inside of a particular task always remain in
- * the same order. See
- * <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals:
- * Activities and Tasks</a> for more details on tasks.
- *
- * <p>This flag is generally used by activities that want
- * to present a "launcher" style behavior: they give the user a list of
- * separate things that can be done, which otherwise run completely
- * independently of the activity launching them.
- *
- * <p>When using this flag, if a task is already running for the activity
- * you are now starting, then a new activity will not be started; instead,
- * the current task will simply be brought to the front of the screen with
- * the state it was last in. See {@link #FLAG_ACTIVITY_MULTIPLE_TASK} for a flag
- * to disable this behavior.
- *
- * <p>This flag can not be used when the caller is requesting a result from
- * the activity being launched.
- */
- public static final int FLAG_ACTIVITY_NEW_TASK = 0x10000000;
- /**
- * <strong>Do not use this flag unless you are implementing your own
- * top-level application launcher.</strong> Used in conjunction with
- * {@link #FLAG_ACTIVITY_NEW_TASK} to disable the
- * behavior of bringing an existing task to the foreground. When set,
- * a new task is <em>always</em> started to host the Activity for the
- * Intent, regardless of whether there is already an existing task running
- * the same thing.
- *
- * <p><strong>Because the default system does not include graphical task management,
- * you should not use this flag unless you provide some way for a user to
- * return back to the tasks you have launched.</strong>
- *
- * <p>This flag is ignored if
- * {@link #FLAG_ACTIVITY_NEW_TASK} is not set.
- *
- * <p>See <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals:
- * Activities and Tasks</a> for more details on tasks.
- */
- public static final int FLAG_ACTIVITY_MULTIPLE_TASK = 0x08000000;
- /**
- * If set, and the activity being launched is already running in the
- * current task, then instead of launching a new instance of that activity,
- * all of the other activities on top of it will be closed and this Intent
- * will be delivered to the (now on top) old activity as a new Intent.
- *
- * <p>For example, consider a task consisting of the activities: A, B, C, D.
- * If D calls startActivity() with an Intent that resolves to the component
- * of activity B, then C and D will be finished and B receive the given
- * Intent, resulting in the stack now being: A, B.
- *
- * <p>The currently running instance of task B in the above example will
- * either receive the new intent you are starting here in its
- * onNewIntent() method, or be itself finished and restarted with the
- * new intent. If it has declared its launch mode to be "multiple" (the
- * default) it will be finished and re-created; for all other launch modes
- * it will receive the Intent in the current instance.
- *
- * <p>This launch mode can also be used to good effect in conjunction with
- * {@link #FLAG_ACTIVITY_NEW_TASK}: if used to start the root activity
- * of a task, it will bring any currently running instance of that task
- * to the foreground, and then clear it to its root state. This is
- * especially useful, for example, when launching an activity from the
- * notification manager.
- *
- * <p>See <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals:
- * Activities and Tasks</a> for more details on tasks.
- */
- public static final int FLAG_ACTIVITY_CLEAR_TOP = 0x04000000;
- /**
- * If set and this intent is being used to launch a new activity from an
- * existing one, then the reply target of the existing activity will be
- * transfered to the new activity. This way the new activity can call
- * {@link android.app.Activity#setResult} and have that result sent back to
- * the reply target of the original activity.
- */
- public static final int FLAG_ACTIVITY_FORWARD_RESULT = 0x02000000;
- /**
- * If set and this intent is being used to launch a new activity from an
- * existing one, the current activity will not be counted as the top
- * activity for deciding whether the new intent should be delivered to
- * the top instead of starting a new one. The previous activity will
- * be used as the top, with the assumption being that the current activity
- * will finish itself immediately.
- */
- public static final int FLAG_ACTIVITY_PREVIOUS_IS_TOP = 0x01000000;
- /**
- * If set, the new activity is not kept in the list of recently launched
- * activities.
- */
- public static final int FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS = 0x00800000;
- /**
- * This flag is not normally set by application code, but set for you by
- * the system as described in the
- * {@link android.R.styleable#AndroidManifestActivity_launchMode
- * launchMode} documentation for the singleTask mode.
- */
- public static final int FLAG_ACTIVITY_BROUGHT_TO_FRONT = 0x00400000;
- /**
- * If set, and this activity is either being started in a new task or
- * bringing to the top an existing task, then it will be launched as
- * the front door of the task. This will result in the application of
- * any affinities needed to have that task in the proper state (either
- * moving activities to or from it), or simply resetting that task to
- * its initial state if needed.
- */
- public static final int FLAG_ACTIVITY_RESET_TASK_IF_NEEDED = 0x00200000;
- /**
- * This flag is not normally set by application code, but set for you by
- * the system if this activity is being launched from history
- * (longpress home key).
- */
- public static final int FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY = 0x00100000;
- /**
- * If set, this marks a point in the task's activity stack that should
- * be cleared when the task is reset. That is, the next time the task
- * is broad to the foreground with
- * {@link #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED} (typically as a result of
- * the user re-launching it from home), this activity and all on top of
- * it will be finished so that the user does not return to them, but
- * instead returns to whatever activity preceeded it.
- *
- * <p>This is useful for cases where you have a logical break in your
- * application. For example, an e-mail application may have a command
- * to view an attachment, which launches an image view activity to
- * display it. This activity should be part of the e-mail application's
- * task, since it is a part of the task the user is involved in. However,
- * if the user leaves that task, and later selects the e-mail app from
- * home, we may like them to return to the conversation they were
- * viewing, not the picture attachment, since that is confusing. By
- * setting this flag when launching the image viewer, that viewer and
- * any activities it starts will be removed the next time the user returns
- * to mail.
- */
- public static final int FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET = 0x00080000;
- /**
- * If set, this flag will prevent the normal {@link android.app.Activity#onUserLeaveHint}
- * callback from occurring on the current frontmost activity before it is
- * paused as the newly-started activity is brought to the front.
- *
- * <p>Typically, an activity can rely on that callback to indicate that an
- * explicit user action has caused their activity to be moved out of the
- * foreground. The callback marks an appropriate point in the activity's
- * lifecycle for it to dismiss any notifications that it intends to display
- * "until the user has seen them," such as a blinking LED.
- *
- * <p>If an activity is ever started via any non-user-driven events such as
- * phone-call receipt or an alarm handler, this flag should be passed to {@link
- * Context#startActivity Context.startActivity}, ensuring that the pausing
- * activity does not think the user has acknowledged its notification.
- */
- public static final int FLAG_ACTIVITY_NO_USER_ACTION = 0x00040000;
- /**
- * If set in an Intent passed to {@link Context#startActivity Context.startActivity()},
- * this flag will cause the launched activity to be brought to the front of its
- * task's history stack if it is already running.
- *
- * <p>For example, consider a task consisting of four activities: A, B, C, D.
- * If D calls startActivity() with an Intent that resolves to the component
- * of activity B, then B will be brought to the front of the history stack,
- * with this resulting order: A, C, D, B.
- *
- * This flag will be ignored if {@link #FLAG_ACTIVITY_CLEAR_TOP} is also
- * specified.
- */
- public static final int FLAG_ACTIVITY_REORDER_TO_FRONT = 0X00020000;
- /**
- * If set, when sending a broadcast only registered receivers will be
- * called -- no BroadcastReceiver components will be launched.
- */
- public static final int FLAG_RECEIVER_REGISTERED_ONLY = 0x40000000;
- /**
- * If set, when sending a broadcast <i>before boot has completed</i> only
- * registered receivers will be called -- no BroadcastReceiver components
- * will be launched. Sticky intent state will be recorded properly even
- * if no receivers wind up being called. If {@link #FLAG_RECEIVER_REGISTERED_ONLY}
- * is specified in the broadcast intent, this flag is unnecessary.
- *
- * <p>This flag is only for use by system sevices as a convenience to
- * avoid having to implement a more complex mechanism around detection
- * of boot completion.
- *
- * @hide
- */
- public static final int FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT = 0x20000000;
-
- // ---------------------------------------------------------------------
-
- private String mAction;
- private Uri mData;
- private String mType;
- private ComponentName mComponent;
- private int mFlags;
- private HashSet<String> mCategories;
- private Bundle mExtras;
-
- // ---------------------------------------------------------------------
-
- /**
- * Create an empty intent.
- */
- public Intent() {
- }
-
- /**
- * Copy constructor.
- */
- public Intent(Intent o) {
- this.mAction = o.mAction;
- this.mData = o.mData;
- this.mType = o.mType;
- this.mComponent = o.mComponent;
- this.mFlags = o.mFlags;
- if (o.mCategories != null) {
- this.mCategories = new HashSet<String>(o.mCategories);
- }
- if (o.mExtras != null) {
- this.mExtras = new Bundle(o.mExtras);
- }
- }
-
- @Override
- public Object clone() {
- return new Intent(this);
- }
-
- private Intent(Intent o, boolean all) {
- this.mAction = o.mAction;
- this.mData = o.mData;
- this.mType = o.mType;
- this.mComponent = o.mComponent;
- if (o.mCategories != null) {
- this.mCategories = new HashSet<String>(o.mCategories);
- }
- }
-
- /**
- * Make a clone of only the parts of the Intent that are relevant for
- * filter matching: the action, data, type, component, and categories.
- */
- public Intent cloneFilter() {
- return new Intent(this, false);
- }
-
- /**
- * Create an intent with a given action. All other fields (data, type,
- * class) are null. Note that the action <em>must</em> be in a
- * namespace because Intents are used globally in the system -- for
- * example the system VIEW action is android.intent.action.VIEW; an
- * application's custom action would be something like
- * com.google.app.myapp.CUSTOM_ACTION.
- *
- * @param action The Intent action, such as ACTION_VIEW.
- */
- public Intent(String action) {
- mAction = action;
- }
-
- /**
- * Create an intent with a given action and for a given data url. Note
- * that the action <em>must</em> be in a namespace because Intents are
- * used globally in the system -- for example the system VIEW action is
- * android.intent.action.VIEW; an application's custom action would be
- * something like com.google.app.myapp.CUSTOM_ACTION.
- *
- * @param action The Intent action, such as ACTION_VIEW.
- * @param uri The Intent data URI.
- */
- public Intent(String action, Uri uri) {
- mAction = action;
- mData = uri;
- }
-
- /**
- * Create an intent for a specific component. All other fields (action, data,
- * type, class) are null, though they can be modified later with explicit
- * calls. This provides a convenient way to create an intent that is
- * intended to execute a hard-coded class name, rather than relying on the
- * system to find an appropriate class for you; see {@link #setComponent}
- * for more information on the repercussions of this.
- *
- * @param packageContext A Context of the application package implementing
- * this class.
- * @param cls The component class that is to be used for the intent.
- *
- * @see #setClass
- * @see #setComponent
- * @see #Intent(String, android.net.Uri , Context, Class)
- */
- public Intent(Context packageContext, Class<?> cls) {
- mComponent = new ComponentName(packageContext, cls);
- }
-
- /**
- * Create an intent for a specific component with a specified action and data.
- * This is equivalent using {@link #Intent(String, android.net.Uri)} to
- * construct the Intent and then calling {@link #setClass} to set its
- * class.
- *
- * @param action The Intent action, such as ACTION_VIEW.
- * @param uri The Intent data URI.
- * @param packageContext A Context of the application package implementing
- * this class.
- * @param cls The component class that is to be used for the intent.
- *
- * @see #Intent(String, android.net.Uri)
- * @see #Intent(Context, Class)
- * @see #setClass
- * @see #setComponent
- */
- public Intent(String action, Uri uri,
- Context packageContext, Class<?> cls) {
- mAction = action;
- mData = uri;
- mComponent = new ComponentName(packageContext, cls);
- }
-
- /**
- * Create an intent from a URI. This URI may encode the action,
- * category, and other intent fields, if it was returned by toURI(). If
- * the Intent was not generate by toURI(), its data will be the entire URI
- * and its action will be ACTION_VIEW.
- *
- * <p>The URI given here must not be relative -- that is, it must include
- * the scheme and full path.
- *
- * @param uri The URI to turn into an Intent.
- *
- * @return Intent The newly created Intent object.
- *
- * @see #toURI
- */
- public static Intent getIntent(String uri) throws URISyntaxException {
- int i = 0;
- try {
- // simple case
- i = uri.lastIndexOf("#");
- if (i == -1) return new Intent(ACTION_VIEW, Uri.parse(uri));
-
- // old format Intent URI
- if (!uri.startsWith("#Intent;", i)) return getIntentOld(uri);
-
- // new format
- Intent intent = new Intent(ACTION_VIEW);
-
- // fetch data part, if present
- if (i > 0) {
- intent.mData = Uri.parse(uri.substring(0, i));
- }
- i += "#Intent;".length();
-
- // loop over contents of Intent, all name=value;
- while (!uri.startsWith("end", i)) {
- int eq = uri.indexOf('=', i);
- int semi = uri.indexOf(';', eq);
- String value = uri.substring(eq + 1, semi);
-
- // action
- if (uri.startsWith("action=", i)) {
- intent.mAction = value;
- }
-
- // categories
- else if (uri.startsWith("category=", i)) {
- intent.addCategory(value);
- }
-
- // type
- else if (uri.startsWith("type=", i)) {
- intent.mType = value;
- }
-
- // launch flags
- else if (uri.startsWith("launchFlags=", i)) {
- intent.mFlags = Integer.decode(value).intValue();
- }
-
- // component
- else if (uri.startsWith("component=", i)) {
- intent.mComponent = ComponentName.unflattenFromString(value);
- }
-
- // extra
- else {
- String key = Uri.decode(uri.substring(i + 2, eq));
- value = Uri.decode(value);
- // create Bundle if it doesn't already exist
- if (intent.mExtras == null) intent.mExtras = new Bundle();
- Bundle b = intent.mExtras;
- // add EXTRA
- if (uri.startsWith("S.", i)) b.putString(key, value);
- else if (uri.startsWith("B.", i)) b.putBoolean(key, Boolean.parseBoolean(value));
- else if (uri.startsWith("b.", i)) b.putByte(key, Byte.parseByte(value));
- else if (uri.startsWith("c.", i)) b.putChar(key, value.charAt(0));
- else if (uri.startsWith("d.", i)) b.putDouble(key, Double.parseDouble(value));
- else if (uri.startsWith("f.", i)) b.putFloat(key, Float.parseFloat(value));
- else if (uri.startsWith("i.", i)) b.putInt(key, Integer.parseInt(value));
- else if (uri.startsWith("l.", i)) b.putLong(key, Long.parseLong(value));
- else if (uri.startsWith("s.", i)) b.putShort(key, Short.parseShort(value));
- else throw new URISyntaxException(uri, "unknown EXTRA type", i);
- }
-
- // move to the next item
- i = semi + 1;
- }
-
- return intent;
-
- } catch (IndexOutOfBoundsException e) {
- throw new URISyntaxException(uri, "illegal Intent URI format", i);
- }
- }
-
- public static Intent getIntentOld(String uri) throws URISyntaxException {
- Intent intent;
-
- int i = uri.lastIndexOf('#');
- if (i >= 0) {
- Uri data = null;
- String action = null;
- if (i > 0) {
- data = Uri.parse(uri.substring(0, i));
- }
-
- i++;
-
- if (uri.regionMatches(i, "action(", 0, 7)) {
- i += 7;
- int j = uri.indexOf(')', i);
- action = uri.substring(i, j);
- i = j + 1;
- }
-
- intent = new Intent(action, data);
-
- if (uri.regionMatches(i, "categories(", 0, 11)) {
- i += 11;
- int j = uri.indexOf(')', i);
- while (i < j) {
- int sep = uri.indexOf('!', i);
- if (sep < 0) sep = j;
- if (i < sep) {
- intent.addCategory(uri.substring(i, sep));
- }
- i = sep + 1;
- }
- i = j + 1;
- }
-
- if (uri.regionMatches(i, "type(", 0, 5)) {
- i += 5;
- int j = uri.indexOf(')', i);
- intent.mType = uri.substring(i, j);
- i = j + 1;
- }
-
- if (uri.regionMatches(i, "launchFlags(", 0, 12)) {
- i += 12;
- int j = uri.indexOf(')', i);
- intent.mFlags = Integer.decode(uri.substring(i, j)).intValue();
- i = j + 1;
- }
-
- if (uri.regionMatches(i, "component(", 0, 10)) {
- i += 10;
- int j = uri.indexOf(')', i);
- int sep = uri.indexOf('!', i);
- if (sep >= 0 && sep < j) {
- String pkg = uri.substring(i, sep);
- String cls = uri.substring(sep + 1, j);
- intent.mComponent = new ComponentName(pkg, cls);
- }
- i = j + 1;
- }
-
- if (uri.regionMatches(i, "extras(", 0, 7)) {
- i += 7;
-
- final int closeParen = uri.indexOf(')', i);
- if (closeParen == -1) throw new URISyntaxException(uri,
- "EXTRA missing trailing ')'", i);
-
- while (i < closeParen) {
- // fetch the key value
- int j = uri.indexOf('=', i);
- if (j <= i + 1 || i >= closeParen) {
- throw new URISyntaxException(uri, "EXTRA missing '='", i);
- }
- char type = uri.charAt(i);
- i++;
- String key = uri.substring(i, j);
- i = j + 1;
-
- // get type-value
- j = uri.indexOf('!', i);
- if (j == -1 || j >= closeParen) j = closeParen;
- if (i >= j) throw new URISyntaxException(uri, "EXTRA missing '!'", i);
- String value = uri.substring(i, j);
- i = j;
-
- // create Bundle if it doesn't already exist
- if (intent.mExtras == null) intent.mExtras = new Bundle();
-
- // add item to bundle
- try {
- switch (type) {
- case 'S':
- intent.mExtras.putString(key, Uri.decode(value));
- break;
- case 'B':
- intent.mExtras.putBoolean(key, Boolean.parseBoolean(value));
- break;
- case 'b':
- intent.mExtras.putByte(key, Byte.parseByte(value));
- break;
- case 'c':
- intent.mExtras.putChar(key, Uri.decode(value).charAt(0));
- break;
- case 'd':
- intent.mExtras.putDouble(key, Double.parseDouble(value));
- break;
- case 'f':
- intent.mExtras.putFloat(key, Float.parseFloat(value));
- break;
- case 'i':
- intent.mExtras.putInt(key, Integer.parseInt(value));
- break;
- case 'l':
- intent.mExtras.putLong(key, Long.parseLong(value));
- break;
- case 's':
- intent.mExtras.putShort(key, Short.parseShort(value));
- break;
- default:
- throw new URISyntaxException(uri, "EXTRA has unknown type", i);
- }
- } catch (NumberFormatException e) {
- throw new URISyntaxException(uri, "EXTRA value can't be parsed", i);
- }
-
- char ch = uri.charAt(i);
- if (ch == ')') break;
- if (ch != '!') throw new URISyntaxException(uri, "EXTRA missing '!'", i);
- i++;
- }
- }
-
- if (intent.mAction == null) {
- // By default, if no action is specified, then use VIEW.
- intent.mAction = ACTION_VIEW;
- }
-
- } else {
- intent = new Intent(ACTION_VIEW, Uri.parse(uri));
- }
-
- return intent;
- }
-
- /**
- * Retrieve the general action to be performed, such as
- * {@link #ACTION_VIEW}. The action describes the general way the rest of
- * the information in the intent should be interpreted -- most importantly,
- * what to do with the data returned by {@link #getData}.
- *
- * @return The action of this intent or null if none is specified.
- *
- * @see #setAction
- */
- public String getAction() {
- return mAction;
- }
-
- /**
- * Retrieve data this intent is operating on. This URI specifies the name
- * of the data; often it uses the content: scheme, specifying data in a
- * content provider. Other schemes may be handled by specific activities,
- * such as http: by the web browser.
- *
- * @return The URI of the data this intent is targeting or null.
- *
- * @see #getScheme
- * @see #setData
- */
- public Uri getData() {
- return mData;
- }
-
- /**
- * The same as {@link #getData()}, but returns the URI as an encoded
- * String.
- */
- public String getDataString() {
- return mData != null ? mData.toString() : null;
- }
-
- /**
- * Return the scheme portion of the intent's data. If the data is null or
- * does not include a scheme, null is returned. Otherwise, the scheme
- * prefix without the final ':' is returned, i.e. "http".
- *
- * <p>This is the same as calling getData().getScheme() (and checking for
- * null data).
- *
- * @return The scheme of this intent.
- *
- * @see #getData
- */
- public String getScheme() {
- return mData != null ? mData.getScheme() : null;
- }
-
- /**
- * Retrieve any explicit MIME type included in the intent. This is usually
- * null, as the type is determined by the intent data.
- *
- * @return If a type was manually set, it is returned; else null is
- * returned.
- *
- * @see #resolveType(ContentResolver)
- * @see #setType
- */
- public String getType() {
- return mType;
- }
-
- /**
- * Return the MIME data type of this intent. If the type field is
- * explicitly set, that is simply returned. Otherwise, if the data is set,
- * the type of that data is returned. If neither fields are set, a null is
- * returned.
- *
- * @return The MIME type of this intent.
- *
- * @see #getType
- * @see #resolveType(ContentResolver)
- */
- public String resolveType(Context context) {
- return resolveType(context.getContentResolver());
- }
-
- /**
- * Return the MIME data type of this intent. If the type field is
- * explicitly set, that is simply returned. Otherwise, if the data is set,
- * the type of that data is returned. If neither fields are set, a null is
- * returned.
- *
- * @param resolver A ContentResolver that can be used to determine the MIME
- * type of the intent's data.
- *
- * @return The MIME type of this intent.
- *
- * @see #getType
- * @see #resolveType(Context)
- */
- public String resolveType(ContentResolver resolver) {
- if (mType != null) {
- return mType;
- }
- if (mData != null) {
- if ("content".equals(mData.getScheme())) {
- return resolver.getType(mData);
- }
- }
- return null;
- }
-
- /**
- * Return the MIME data type of this intent, only if it will be needed for
- * intent resolution. This is not generally useful for application code;
- * it is used by the frameworks for communicating with back-end system
- * services.
- *
- * @param resolver A ContentResolver that can be used to determine the MIME
- * type of the intent's data.
- *
- * @return The MIME type of this intent, or null if it is unknown or not
- * needed.
- */
- public String resolveTypeIfNeeded(ContentResolver resolver) {
- if (mComponent != null) {
- return mType;
- }
- return resolveType(resolver);
- }
-
- /**
- * Check if an category exists in the intent.
- *
- * @param category The category to check.
- *
- * @return boolean True if the intent contains the category, else false.
- *
- * @see #getCategories
- * @see #addCategory
- */
- public boolean hasCategory(String category) {
- return mCategories != null && mCategories.contains(category);
- }
-
- /**
- * Return the set of all categories in the intent. If there are no categories,
- * returns NULL.
- *
- * @return Set The set of categories you can examine. Do not modify!
- *
- * @see #hasCategory
- * @see #addCategory
- */
- public Set<String> getCategories() {
- return mCategories;
- }
-
- /**
- * Sets the ClassLoader that will be used when unmarshalling
- * any Parcelable values from the extras of this Intent.
- *
- * @param loader a ClassLoader, or null to use the default loader
- * at the time of unmarshalling.
- */
- public void setExtrasClassLoader(ClassLoader loader) {
- if (mExtras != null) {
- mExtras.setClassLoader(loader);
- }
- }
-
- /**
- * Returns true if an extra value is associated with the given name.
- * @param name the extra's name
- * @return true if the given extra is present.
- */
- public boolean hasExtra(String name) {
- return mExtras != null && mExtras.containsKey(name);
- }
-
- /**
- * Returns true if the Intent's extras contain a parcelled file descriptor.
- * @return true if the Intent contains a parcelled file descriptor.
- */
- public boolean hasFileDescriptors() {
- return mExtras != null && mExtras.hasFileDescriptors();
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if none was found.
- *
- * @deprecated
- * @hide
- */
- @Deprecated
- public Object getExtra(String name) {
- return getExtra(name, null);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- * @param defaultValue the value to be returned if no value of the desired
- * type is stored with the given name.
- *
- * @return the value of an item that previously added with putExtra()
- * or the default value if none was found.
- *
- * @see #putExtra(String, boolean)
- */
- public boolean getBooleanExtra(String name, boolean defaultValue) {
- return mExtras == null ? defaultValue :
- mExtras.getBoolean(name, defaultValue);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- * @param defaultValue the value to be returned if no value of the desired
- * type is stored with the given name.
- *
- * @return the value of an item that previously added with putExtra()
- * or the default value if none was found.
- *
- * @see #putExtra(String, byte)
- */
- public byte getByteExtra(String name, byte defaultValue) {
- return mExtras == null ? defaultValue :
- mExtras.getByte(name, defaultValue);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- * @param defaultValue the value to be returned if no value of the desired
- * type is stored with the given name.
- *
- * @return the value of an item that previously added with putExtra()
- * or the default value if none was found.
- *
- * @see #putExtra(String, short)
- */
- public short getShortExtra(String name, short defaultValue) {
- return mExtras == null ? defaultValue :
- mExtras.getShort(name, defaultValue);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- * @param defaultValue the value to be returned if no value of the desired
- * type is stored with the given name.
- *
- * @return the value of an item that previously added with putExtra()
- * or the default value if none was found.
- *
- * @see #putExtra(String, char)
- */
- public char getCharExtra(String name, char defaultValue) {
- return mExtras == null ? defaultValue :
- mExtras.getChar(name, defaultValue);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- * @param defaultValue the value to be returned if no value of the desired
- * type is stored with the given name.
- *
- * @return the value of an item that previously added with putExtra()
- * or the default value if none was found.
- *
- * @see #putExtra(String, int)
- */
- public int getIntExtra(String name, int defaultValue) {
- return mExtras == null ? defaultValue :
- mExtras.getInt(name, defaultValue);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- * @param defaultValue the value to be returned if no value of the desired
- * type is stored with the given name.
- *
- * @return the value of an item that previously added with putExtra()
- * or the default value if none was found.
- *
- * @see #putExtra(String, long)
- */
- public long getLongExtra(String name, long defaultValue) {
- return mExtras == null ? defaultValue :
- mExtras.getLong(name, defaultValue);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- * @param defaultValue the value to be returned if no value of the desired
- * type is stored with the given name.
- *
- * @return the value of an item that previously added with putExtra(),
- * or the default value if no such item is present
- *
- * @see #putExtra(String, float)
- */
- public float getFloatExtra(String name, float defaultValue) {
- return mExtras == null ? defaultValue :
- mExtras.getFloat(name, defaultValue);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- * @param defaultValue the value to be returned if no value of the desired
- * type is stored with the given name.
- *
- * @return the value of an item that previously added with putExtra()
- * or the default value if none was found.
- *
- * @see #putExtra(String, double)
- */
- public double getDoubleExtra(String name, double defaultValue) {
- return mExtras == null ? defaultValue :
- mExtras.getDouble(name, defaultValue);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no String value was found.
- *
- * @see #putExtra(String, String)
- */
- public String getStringExtra(String name) {
- return mExtras == null ? null : mExtras.getString(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no CharSequence value was found.
- *
- * @see #putExtra(String, CharSequence)
- */
- public CharSequence getCharSequenceExtra(String name) {
- return mExtras == null ? null : mExtras.getCharSequence(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no Parcelable value was found.
- *
- * @see #putExtra(String, Parcelable)
- */
- public <T extends Parcelable> T getParcelableExtra(String name) {
- return mExtras == null ? null : mExtras.<T>getParcelable(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no Parcelable[] value was found.
- *
- * @see #putExtra(String, Parcelable[])
- */
- public Parcelable[] getParcelableArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getParcelableArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no ArrayList<Parcelable> value was found.
- *
- * @see #putParcelableArrayListExtra(String, ArrayList)
- */
- public <T extends Parcelable> ArrayList<T> getParcelableArrayListExtra(String name) {
- return mExtras == null ? null : mExtras.<T>getParcelableArrayList(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no Serializable value was found.
- *
- * @see #putExtra(String, Serializable)
- */
- public Serializable getSerializableExtra(String name) {
- return mExtras == null ? null : mExtras.getSerializable(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no ArrayList<Integer> value was found.
- *
- * @see #putIntegerArrayListExtra(String, ArrayList)
- */
- public ArrayList<Integer> getIntegerArrayListExtra(String name) {
- return mExtras == null ? null : mExtras.getIntegerArrayList(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no ArrayList<String> value was found.
- *
- * @see #putStringArrayListExtra(String, ArrayList)
- */
- public ArrayList<String> getStringArrayListExtra(String name) {
- return mExtras == null ? null : mExtras.getStringArrayList(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no boolean array value was found.
- *
- * @see #putExtra(String, boolean[])
- */
- public boolean[] getBooleanArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getBooleanArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no byte array value was found.
- *
- * @see #putExtra(String, byte[])
- */
- public byte[] getByteArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getByteArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no short array value was found.
- *
- * @see #putExtra(String, short[])
- */
- public short[] getShortArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getShortArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no char array value was found.
- *
- * @see #putExtra(String, char[])
- */
- public char[] getCharArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getCharArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no int array value was found.
- *
- * @see #putExtra(String, int[])
- */
- public int[] getIntArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getIntArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no long array value was found.
- *
- * @see #putExtra(String, long[])
- */
- public long[] getLongArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getLongArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no float array value was found.
- *
- * @see #putExtra(String, float[])
- */
- public float[] getFloatArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getFloatArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no double array value was found.
- *
- * @see #putExtra(String, double[])
- */
- public double[] getDoubleArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getDoubleArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no String array value was found.
- *
- * @see #putExtra(String, String[])
- */
- public String[] getStringArrayExtra(String name) {
- return mExtras == null ? null : mExtras.getStringArray(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no Bundle value was found.
- *
- * @see #putExtra(String, Bundle)
- */
- public Bundle getBundleExtra(String name) {
- return mExtras == null ? null : mExtras.getBundle(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- *
- * @return the value of an item that previously added with putExtra()
- * or null if no IBinder value was found.
- *
- * @see #putExtra(String, IBinder)
- *
- * @deprecated
- * @hide
- */
- @Deprecated
- public IBinder getIBinderExtra(String name) {
- return mExtras == null ? null : mExtras.getIBinder(name);
- }
-
- /**
- * Retrieve extended data from the intent.
- *
- * @param name The name of the desired item.
- * @param defaultValue The default value to return in case no item is
- * associated with the key 'name'
- *
- * @return the value of an item that previously added with putExtra()
- * or defaultValue if none was found.
- *
- * @see #putExtra
- *
- * @deprecated
- * @hide
- */
- @Deprecated
- public Object getExtra(String name, Object defaultValue) {
- Object result = defaultValue;
- if (mExtras != null) {
- Object result2 = mExtras.get(name);
- if (result2 != null) {
- result = result2;
- }
- }
-
- return result;
- }
-
- /**
- * Retrieves a map of extended data from the intent.
- *
- * @return the map of all extras previously added with putExtra(),
- * or null if none have been added.
- */
- public Bundle getExtras() {
- return (mExtras != null)
- ? new Bundle(mExtras)
- : null;
- }
-
- /**
- * Retrieve any special flags associated with this intent. You will
- * normally just set them with {@link #setFlags} and let the system
- * take the appropriate action with them.
- *
- * @return int The currently set flags.
- *
- * @see #setFlags
- */
- public int getFlags() {
- return mFlags;
- }
-
- /**
- * Retrieve the concrete component associated with the intent. When receiving
- * an intent, this is the component that was found to best handle it (that is,
- * yourself) and will always be non-null; in all other cases it will be
- * null unless explicitly set.
- *
- * @return The name of the application component to handle the intent.
- *
- * @see #resolveActivity
- * @see #setComponent
- */
- public ComponentName getComponent() {
- return mComponent;
- }
-
- /**
- * Return the Activity component that should be used to handle this intent.
- * The appropriate component is determined based on the information in the
- * intent, evaluated as follows:
- *
- * <p>If {@link #getComponent} returns an explicit class, that is returned
- * without any further consideration.
- *
- * <p>The activity must handle the {@link Intent#CATEGORY_DEFAULT} Intent
- * category to be considered.
- *
- * <p>If {@link #getAction} is non-NULL, the activity must handle this
- * action.
- *
- * <p>If {@link #resolveType} returns non-NULL, the activity must handle
- * this type.
- *
- * <p>If {@link #addCategory} has added any categories, the activity must
- * handle ALL of the categories specified.
- *
- * <p>If there are no activities that satisfy all of these conditions, a
- * null string is returned.
- *
- * <p>If multiple activities are found to satisfy the intent, the one with
- * the highest priority will be used. If there are multiple activities
- * with the same priority, the system will either pick the best activity
- * based on user preference, or resolve to a system class that will allow
- * the user to pick an activity and forward from there.
- *
- * <p>This method is implemented simply by calling
- * {@link PackageManager#resolveActivity} with the "defaultOnly" parameter
- * true.</p>
- * <p> This API is called for you as part of starting an activity from an
- * intent. You do not normally need to call it yourself.</p>
- *
- * @param pm The package manager with which to resolve the Intent.
- *
- * @return Name of the component implementing an activity that can
- * display the intent.
- *
- * @see #setComponent
- * @see #getComponent
- * @see #resolveActivityInfo
- */
- public ComponentName resolveActivity(PackageManager pm) {
- if (mComponent != null) {
- return mComponent;
- }
-
- ResolveInfo info = pm.resolveActivity(
- this, PackageManager.MATCH_DEFAULT_ONLY);
- if (info != null) {
- return new ComponentName(
- info.activityInfo.applicationInfo.packageName,
- info.activityInfo.name);
- }
-
- return null;
- }
-
- /**
- * Resolve the Intent into an {@link ActivityInfo}
- * describing the activity that should execute the intent. Resolution
- * follows the same rules as described for {@link #resolveActivity}, but
- * you get back the completely information about the resolved activity
- * instead of just its class name.
- *
- * @param pm The package manager with which to resolve the Intent.
- * @param flags Addition information to retrieve as per
- * {@link PackageManager#getActivityInfo(ComponentName, int)
- * PackageManager.getActivityInfo()}.
- *
- * @return PackageManager.ActivityInfo
- *
- * @see #resolveActivity
- */
- public ActivityInfo resolveActivityInfo(PackageManager pm, int flags) {
- ActivityInfo ai = null;
- if (mComponent != null) {
- try {
- ai = pm.getActivityInfo(mComponent, flags);
- } catch (PackageManager.NameNotFoundException e) {
- // ignore
- }
- } else {
- ResolveInfo info = pm.resolveActivity(
- this, PackageManager.MATCH_DEFAULT_ONLY);
- if (info != null) {
- ai = info.activityInfo;
- }
- }
-
- return ai;
- }
-
- /**
- * Set the general action to be performed.
- *
- * @param action An action name, such as ACTION_VIEW. Application-specific
- * actions should be prefixed with the vendor's package name.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #getAction
- */
- public Intent setAction(String action) {
- mAction = action;
- return this;
- }
-
- /**
- * Set the data this intent is operating on. This method automatically
- * clears any type that was previously set by {@link #setType}.
- *
- * @param data The URI of the data this intent is now targeting.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #getData
- * @see #setType
- * @see #setDataAndType
- */
- public Intent setData(Uri data) {
- mData = data;
- mType = null;
- return this;
- }
-
- /**
- * Set an explicit MIME data type. This is used to create intents that
- * only specify a type and not data, for example to indicate the type of
- * data to return. This method automatically clears any data that was
- * previously set by {@link #setData}.
- *
- * @param type The MIME type of the data being handled by this intent.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #getType
- * @see #setData
- * @see #setDataAndType
- */
- public Intent setType(String type) {
- mData = null;
- mType = type;
- return this;
- }
-
- /**
- * (Usually optional) Set the data for the intent along with an explicit
- * MIME data type. This method should very rarely be used -- it allows you
- * to override the MIME type that would ordinarily be inferred from the
- * data with your own type given here.
- *
- * @param data The URI of the data this intent is now targeting.
- * @param type The MIME type of the data being handled by this intent.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #setData
- * @see #setType
- */
- public Intent setDataAndType(Uri data, String type) {
- mData = data;
- mType = type;
- return this;
- }
-
- /**
- * Add a new category to the intent. Categories provide additional detail
- * about the action the intent is perform. When resolving an intent, only
- * activities that provide <em>all</em> of the requested categories will be
- * used.
- *
- * @param category The desired category. This can be either one of the
- * predefined Intent categories, or a custom category in your own
- * namespace.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #hasCategory
- * @see #removeCategory
- */
- public Intent addCategory(String category) {
- if (mCategories == null) {
- mCategories = new HashSet<String>();
- }
- mCategories.add(category);
- return this;
- }
-
- /**
- * Remove an category from an intent.
- *
- * @param category The category to remove.
- *
- * @see #addCategory
- */
- public void removeCategory(String category) {
- if (mCategories != null) {
- mCategories.remove(category);
- if (mCategories.size() == 0) {
- mCategories = null;
- }
- }
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The boolean data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getBooleanExtra(String, boolean)
- */
- public Intent putExtra(String name, boolean value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putBoolean(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The byte data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getByteExtra(String, byte)
- */
- public Intent putExtra(String name, byte value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putByte(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The char data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getCharExtra(String, char)
- */
- public Intent putExtra(String name, char value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putChar(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The short data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getShortExtra(String, short)
- */
- public Intent putExtra(String name, short value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putShort(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The integer data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getIntExtra(String, int)
- */
- public Intent putExtra(String name, int value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putInt(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The long data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getLongExtra(String, long)
- */
- public Intent putExtra(String name, long value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putLong(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The float data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getFloatExtra(String, float)
- */
- public Intent putExtra(String name, float value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putFloat(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The double data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getDoubleExtra(String, double)
- */
- public Intent putExtra(String name, double value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putDouble(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The String data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getStringExtra(String)
- */
- public Intent putExtra(String name, String value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putString(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The CharSequence data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getCharSequenceExtra(String)
- */
- public Intent putExtra(String name, CharSequence value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putCharSequence(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The Parcelable data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getParcelableExtra(String)
- */
- public Intent putExtra(String name, Parcelable value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putParcelable(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The Parcelable[] data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getParcelableArrayExtra(String)
- */
- public Intent putExtra(String name, Parcelable[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putParcelableArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The ArrayList<Parcelable> data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getParcelableArrayListExtra(String)
- */
- public Intent putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putParcelableArrayList(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The ArrayList<Integer> data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getIntegerArrayListExtra(String)
- */
- public Intent putIntegerArrayListExtra(String name, ArrayList<Integer> value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putIntegerArrayList(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The ArrayList<String> data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getStringArrayListExtra(String)
- */
- public Intent putStringArrayListExtra(String name, ArrayList<String> value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putStringArrayList(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The Serializable data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getSerializableExtra(String)
- */
- public Intent putExtra(String name, Serializable value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putSerializable(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The boolean array data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getBooleanArrayExtra(String)
- */
- public Intent putExtra(String name, boolean[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putBooleanArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The byte array data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getByteArrayExtra(String)
- */
- public Intent putExtra(String name, byte[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putByteArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The short array data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getShortArrayExtra(String)
- */
- public Intent putExtra(String name, short[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putShortArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The char array data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getCharArrayExtra(String)
- */
- public Intent putExtra(String name, char[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putCharArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The int array data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getIntArrayExtra(String)
- */
- public Intent putExtra(String name, int[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putIntArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The byte array data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getLongArrayExtra(String)
- */
- public Intent putExtra(String name, long[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putLongArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The float array data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getFloatArrayExtra(String)
- */
- public Intent putExtra(String name, float[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putFloatArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The double array data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getDoubleArrayExtra(String)
- */
- public Intent putExtra(String name, double[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putDoubleArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The String array data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getStringArrayExtra(String)
- */
- public Intent putExtra(String name, String[] value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putStringArray(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The Bundle data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getBundleExtra(String)
- */
- public Intent putExtra(String name, Bundle value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putBundle(name, value);
- return this;
- }
-
- /**
- * Add extended data to the intent. The name must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param name The name of the extra data, with package prefix.
- * @param value The IBinder data value.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #putExtras
- * @see #removeExtra
- * @see #getIBinderExtra(String)
- *
- * @deprecated
- * @hide
- */
- @Deprecated
- public Intent putExtra(String name, IBinder value) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putIBinder(name, value);
- return this;
- }
-
- /**
- * Copy all extras in 'src' in to this intent.
- *
- * @param src Contains the extras to copy.
- *
- * @see #putExtra
- */
- public Intent putExtras(Intent src) {
- if (src.mExtras != null) {
- if (mExtras == null) {
- mExtras = new Bundle(src.mExtras);
- } else {
- mExtras.putAll(src.mExtras);
- }
- }
- return this;
- }
-
- /**
- * Add a set of extended data to the intent. The keys must include a package
- * prefix, for example the app com.android.contacts would use names
- * like "com.android.contacts.ShowAll".
- *
- * @param extras The Bundle of extras to add to this intent.
- *
- * @see #putExtra
- * @see #removeExtra
- */
- public Intent putExtras(Bundle extras) {
- if (mExtras == null) {
- mExtras = new Bundle();
- }
- mExtras.putAll(extras);
- return this;
- }
-
- /**
- * Completely replace the extras in the Intent with the extras in the
- * given Intent.
- *
- * @param src The exact extras contained in this Intent are copied
- * into the target intent, replacing any that were previously there.
- */
- public Intent replaceExtras(Intent src) {
- mExtras = src.mExtras != null ? new Bundle(src.mExtras) : null;
- return this;
- }
-
- /**
- * Completely replace the extras in the Intent with the given Bundle of
- * extras.
- *
- * @param extras The new set of extras in the Intent, or null to erase
- * all extras.
- */
- public Intent replaceExtras(Bundle extras) {
- mExtras = extras != null ? new Bundle(extras) : null;
- return this;
- }
-
- /**
- * Remove extended data from the intent.
- *
- * @see #putExtra
- */
- public void removeExtra(String name) {
- if (mExtras != null) {
- mExtras.remove(name);
- if (mExtras.size() == 0) {
- mExtras = null;
- }
- }
- }
-
- /**
- * Set special flags controlling how this intent is handled. Most values
- * here depend on the type of component being executed by the Intent,
- * specifically the FLAG_ACTIVITY_* flags are all for use with
- * {@link Context#startActivity Context.startActivity()} and the
- * FLAG_RECEIVER_* flags are all for use with
- * {@link Context#sendBroadcast(Intent) Context.sendBroadcast()}.
- *
- * <p>See the <a href="{@docRoot}guide/topics/fundamentals.html#acttask">Application Fundamentals:
- * Activities and Tasks</a> documentation for important information on how some of these options impact
- * the behavior of your application.
- *
- * @param flags The desired flags.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #getFlags
- * @see #addFlags
- *
- * @see #FLAG_GRANT_READ_URI_PERMISSION
- * @see #FLAG_GRANT_WRITE_URI_PERMISSION
- * @see #FLAG_DEBUG_LOG_RESOLUTION
- * @see #FLAG_FROM_BACKGROUND
- * @see #FLAG_ACTIVITY_BROUGHT_TO_FRONT
- * @see #FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
- * @see #FLAG_ACTIVITY_CLEAR_TOP
- * @see #FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
- * @see #FLAG_ACTIVITY_FORWARD_RESULT
- * @see #FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
- * @see #FLAG_ACTIVITY_MULTIPLE_TASK
- * @see #FLAG_ACTIVITY_NEW_TASK
- * @see #FLAG_ACTIVITY_NO_HISTORY
- * @see #FLAG_ACTIVITY_NO_USER_ACTION
- * @see #FLAG_ACTIVITY_PREVIOUS_IS_TOP
- * @see #FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
- * @see #FLAG_ACTIVITY_SINGLE_TOP
- * @see #FLAG_RECEIVER_REGISTERED_ONLY
- */
- public Intent setFlags(int flags) {
- mFlags = flags;
- return this;
- }
-
- /**
- * Add additional flags to the intent (or with existing flags
- * value).
- *
- * @param flags The new flags to set.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #setFlags
- */
- public Intent addFlags(int flags) {
- mFlags |= flags;
- return this;
- }
-
- /**
- * (Usually optional) Explicitly set the component to handle the intent.
- * If left with the default value of null, the system will determine the
- * appropriate class to use based on the other fields (action, data,
- * type, categories) in the Intent. If this class is defined, the
- * specified class will always be used regardless of the other fields. You
- * should only set this value when you know you absolutely want a specific
- * class to be used; otherwise it is better to let the system find the
- * appropriate class so that you will respect the installed applications
- * and user preferences.
- *
- * @param component The name of the application component to handle the
- * intent, or null to let the system find one for you.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #setClass
- * @see #setClassName(Context, String)
- * @see #setClassName(String, String)
- * @see #getComponent
- * @see #resolveActivity
- */
- public Intent setComponent(ComponentName component) {
- mComponent = component;
- return this;
- }
-
- /**
- * Convenience for calling {@link #setComponent} with an
- * explicit class name.
- *
- * @param packageContext A Context of the application package implementing
- * this class.
- * @param className The name of a class inside of the application package
- * that will be used as the component for this Intent.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #setComponent
- * @see #setClass
- */
- public Intent setClassName(Context packageContext, String className) {
- mComponent = new ComponentName(packageContext, className);
- return this;
- }
-
- /**
- * Convenience for calling {@link #setComponent} with an
- * explicit application package name and class name.
- *
- * @param packageName The name of the package implementing the desired
- * component.
- * @param className The name of a class inside of the application package
- * that will be used as the component for this Intent.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #setComponent
- * @see #setClass
- */
- public Intent setClassName(String packageName, String className) {
- mComponent = new ComponentName(packageName, className);
- return this;
- }
-
- /**
- * Convenience for calling {@link #setComponent(ComponentName)} with the
- * name returned by a {@link Class} object.
- *
- * @param packageContext A Context of the application package implementing
- * this class.
- * @param cls The class name to set, equivalent to
- * <code>setClassName(context, cls.getName())</code>.
- *
- * @return Returns the same Intent object, for chaining multiple calls
- * into a single statement.
- *
- * @see #setComponent
- */
- public Intent setClass(Context packageContext, Class<?> cls) {
- mComponent = new ComponentName(packageContext, cls);
- return this;
- }
-
- /**
- * Use with {@link #fillIn} to allow the current action value to be
- * overwritten, even if it is already set.
- */
- public static final int FILL_IN_ACTION = 1<<0;
-
- /**
- * Use with {@link #fillIn} to allow the current data or type value
- * overwritten, even if it is already set.
- */
- public static final int FILL_IN_DATA = 1<<1;
-
- /**
- * Use with {@link #fillIn} to allow the current categories to be
- * overwritten, even if they are already set.
- */
- public static final int FILL_IN_CATEGORIES = 1<<2;
-
- /**
- * Use with {@link #fillIn} to allow the current component value to be
- * overwritten, even if it is already set.
- */
- public static final int FILL_IN_COMPONENT = 1<<3;
-
- /**
- * Copy the contents of <var>other</var> in to this object, but only
- * where fields are not defined by this object. For purposes of a field
- * being defined, the following pieces of data in the Intent are
- * considered to be separate fields:
- *
- * <ul>
- * <li> action, as set by {@link #setAction}.
- * <li> data URI and MIME type, as set by {@link #setData(Uri)},
- * {@link #setType(String)}, or {@link #setDataAndType(Uri, String)}.
- * <li> categories, as set by {@link #addCategory}.
- * <li> component, as set by {@link #setComponent(ComponentName)} or
- * related methods.
- * <li> each top-level name in the associated extras.
- * </ul>
- *
- * <p>In addition, you can use the {@link #FILL_IN_ACTION},
- * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, and
- * {@link #FILL_IN_COMPONENT} to override the restriction where the
- * corresponding field will not be replaced if it is already set.
- *
- * <p>For example, consider Intent A with {data="foo", categories="bar"}
- * and Intent B with {action="gotit", data-type="some/thing",
- * categories="one","two"}.
- *
- * <p>Calling A.fillIn(B, Intent.FILL_IN_DATA) will result in A now
- * containing: {action="gotit", data-type="some/thing",
- * categories="bar"}.
- *
- * @param other Another Intent whose values are to be used to fill in
- * the current one.
- * @param flags Options to control which fields can be filled in.
- *
- * @return Returns a bit mask of {@link #FILL_IN_ACTION},
- * {@link #FILL_IN_DATA}, {@link #FILL_IN_CATEGORIES}, and
- * {@link #FILL_IN_COMPONENT} indicating which fields were changed.
- */
- public int fillIn(Intent other, int flags) {
- int changes = 0;
- if ((mAction == null && other.mAction == null)
- || (flags&FILL_IN_ACTION) != 0) {
- mAction = other.mAction;
- changes |= FILL_IN_ACTION;
- }
- if ((mData == null && mType == null &&
- (other.mData != null || other.mType != null))
- || (flags&FILL_IN_DATA) != 0) {
- mData = other.mData;
- mType = other.mType;
- changes |= FILL_IN_DATA;
- }
- if ((mCategories == null && other.mCategories == null)
- || (flags&FILL_IN_CATEGORIES) != 0) {
- if (other.mCategories != null) {
- mCategories = new HashSet<String>(other.mCategories);
- }
- changes |= FILL_IN_CATEGORIES;
- }
- if ((mComponent == null && other.mComponent == null)
- || (flags&FILL_IN_COMPONENT) != 0) {
- mComponent = other.mComponent;
- changes |= FILL_IN_COMPONENT;
- }
- mFlags |= other.mFlags;
- if (mExtras == null) {
- if (other.mExtras != null) {
- mExtras = new Bundle(other.mExtras);
- }
- } else if (other.mExtras != null) {
- try {
- Bundle newb = new Bundle(other.mExtras);
- newb.putAll(mExtras);
- mExtras = newb;
- } catch (RuntimeException e) {
- // Modifying the extras can cause us to unparcel the contents
- // of the bundle, and if we do this in the system process that
- // may fail. We really should handle this (i.e., the Bundle
- // impl shouldn't be on top of a plain map), but for now just
- // ignore it and keep the original contents. :(
- Log.w("Intent", "Failure filling in extras", e);
- }
- }
- return changes;
- }
-
- /**
- * Wrapper class holding an Intent and implementing comparisons on it for
- * the purpose of filtering. The class implements its
- * {@link #equals equals()} and {@link #hashCode hashCode()} methods as
- * simple calls to {@link Intent#filterEquals(Intent)} filterEquals()} and
- * {@link android.content.Intent#filterHashCode()} filterHashCode()}
- * on the wrapped Intent.
- */
- public static final class FilterComparison {
- private final Intent mIntent;
- private final int mHashCode;
-
- public FilterComparison(Intent intent) {
- mIntent = intent;
- mHashCode = intent.filterHashCode();
- }
-
- /**
- * Return the Intent that this FilterComparison represents.
- * @return Returns the Intent held by the FilterComparison. Do
- * not modify!
- */
- public Intent getIntent() {
- return mIntent;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof FilterComparison) {
- Intent other = ((FilterComparison)obj).mIntent;
- return mIntent.filterEquals(other);
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- return mHashCode;
- }
- }
-
- /**
- * Determine if two intents are the same for the purposes of intent
- * resolution (filtering). That is, if their action, data, type,
- * class, and categories are the same. This does <em>not</em> compare
- * any extra data included in the intents.
- *
- * @param other The other Intent to compare against.
- *
- * @return Returns true if action, data, type, class, and categories
- * are the same.
- */
- public boolean filterEquals(Intent other) {
- if (other == null) {
- return false;
- }
- if (mAction != other.mAction) {
- if (mAction != null) {
- if (!mAction.equals(other.mAction)) {
- return false;
- }
- } else {
- if (!other.mAction.equals(mAction)) {
- return false;
- }
- }
- }
- if (mData != other.mData) {
- if (mData != null) {
- if (!mData.equals(other.mData)) {
- return false;
- }
- } else {
- if (!other.mData.equals(mData)) {
- return false;
- }
- }
- }
- if (mType != other.mType) {
- if (mType != null) {
- if (!mType.equals(other.mType)) {
- return false;
- }
- } else {
- if (!other.mType.equals(mType)) {
- return false;
- }
- }
- }
- if (mComponent != other.mComponent) {
- if (mComponent != null) {
- if (!mComponent.equals(other.mComponent)) {
- return false;
- }
- } else {
- if (!other.mComponent.equals(mComponent)) {
- return false;
- }
- }
- }
- if (mCategories != other.mCategories) {
- if (mCategories != null) {
- if (!mCategories.equals(other.mCategories)) {
- return false;
- }
- } else {
- if (!other.mCategories.equals(mCategories)) {
- return false;
- }
- }
- }
-
- return true;
- }
-
- /**
- * Generate hash code that matches semantics of filterEquals().
- *
- * @return Returns the hash value of the action, data, type, class, and
- * categories.
- *
- * @see #filterEquals
- */
- public int filterHashCode() {
- int code = 0;
- if (mAction != null) {
- code += mAction.hashCode();
- }
- if (mData != null) {
- code += mData.hashCode();
- }
- if (mType != null) {
- code += mType.hashCode();
- }
- if (mComponent != null) {
- code += mComponent.hashCode();
- }
- if (mCategories != null) {
- code += mCategories.hashCode();
- }
- return code;
- }
-
- @Override
- public String toString() {
- StringBuilder b = new StringBuilder();
-
- b.append("Intent {");
- if (mAction != null) b.append(" action=").append(mAction);
- if (mCategories != null) {
- b.append(" categories={");
- Iterator<String> i = mCategories.iterator();
- boolean didone = false;
- while (i.hasNext()) {
- if (didone) b.append(",");
- didone = true;
- b.append(i.next());
- }
- b.append("}");
- }
- if (mData != null) b.append(" data=").append(mData);
- if (mType != null) b.append(" type=").append(mType);
- if (mFlags != 0) b.append(" flags=0x").append(Integer.toHexString(mFlags));
- if (mComponent != null) b.append(" comp=").append(mComponent.toShortString());
- if (mExtras != null) b.append(" (has extras)");
- b.append(" }");
-
- return b.toString();
- }
-
- public String toURI() {
- StringBuilder uri = new StringBuilder(mData != null ? mData.toString() : "");
-
- uri.append("#Intent;");
-
- if (mAction != null) {
- uri.append("action=").append(mAction).append(';');
- }
- if (mCategories != null) {
- for (String category : mCategories) {
- uri.append("category=").append(category).append(';');
- }
- }
- if (mType != null) {
- uri.append("type=").append(mType).append(';');
- }
- if (mFlags != 0) {
- uri.append("launchFlags=0x").append(Integer.toHexString(mFlags)).append(';');
- }
- if (mComponent != null) {
- uri.append("component=").append(mComponent.flattenToShortString()).append(';');
- }
- if (mExtras != null) {
- for (String key : mExtras.keySet()) {
- final Object value = mExtras.get(key);
- char entryType =
- value instanceof String ? 'S' :
- value instanceof Boolean ? 'B' :
- value instanceof Byte ? 'b' :
- value instanceof Character ? 'c' :
- value instanceof Double ? 'd' :
- value instanceof Float ? 'f' :
- value instanceof Integer ? 'i' :
- value instanceof Long ? 'l' :
- value instanceof Short ? 's' :
- '\0';
-
- if (entryType != '\0') {
- uri.append(entryType);
- uri.append('.');
- uri.append(Uri.encode(key));
- uri.append('=');
- uri.append(Uri.encode(value.toString()));
- uri.append(';');
- }
- }
- }
-
- uri.append("end");
-
- return uri.toString();
- }
-
- public int describeContents() {
- return (mExtras != null) ? mExtras.describeContents() : 0;
- }
-
- public void writeToParcel(Parcel out, int flags) {
- out.writeString(mAction);
- Uri.writeToParcel(out, mData);
- out.writeString(mType);
- out.writeInt(mFlags);
- ComponentName.writeToParcel(mComponent, out);
-
- if (mCategories != null) {
- out.writeInt(mCategories.size());
- for (String category : mCategories) {
- out.writeString(category);
- }
- } else {
- out.writeInt(0);
- }
-
- out.writeBundle(mExtras);
- }
-
- public static final Parcelable.Creator<Intent> CREATOR
- = new Parcelable.Creator<Intent>() {
- public Intent createFromParcel(Parcel in) {
- return new Intent(in);
- }
- public Intent[] newArray(int size) {
- return new Intent[size];
- }
- };
-
- private Intent(Parcel in) {
- readFromParcel(in);
- }
-
- public void readFromParcel(Parcel in) {
- mAction = in.readString();
- mData = Uri.CREATOR.createFromParcel(in);
- mType = in.readString();
- mFlags = in.readInt();
- mComponent = ComponentName.readFromParcel(in);
-
- int N = in.readInt();
- if (N > 0) {
- mCategories = new HashSet<String>();
- int i;
- for (i=0; i<N; i++) {
- mCategories.add(in.readString());
- }
- } else {
- mCategories = null;
- }
-
- mExtras = in.readBundle();
- }
-
- /**
- * Parses the "intent" element (and its children) from XML and instantiates
- * an Intent object. The given XML parser should be located at the tag
- * where parsing should start (often named "intent"), from which the
- * basic action, data, type, and package and class name will be
- * retrieved. The function will then parse in to any child elements,
- * looking for <category android:name="xxx"> tags to add categories and
- * <extra android:name="xxx" android:value="yyy"> to attach extra data
- * to the intent.
- *
- * @param resources The Resources to use when inflating resources.
- * @param parser The XML parser pointing at an "intent" tag.
- * @param attrs The AttributeSet interface for retrieving extended
- * attribute data at the current <var>parser</var> location.
- * @return An Intent object matching the XML data.
- * @throws XmlPullParserException If there was an XML parsing error.
- * @throws IOException If there was an I/O error.
- */
- public static Intent parseIntent(Resources resources, XmlPullParser parser, AttributeSet attrs)
- throws XmlPullParserException, IOException {
- Intent intent = new Intent();
-
- TypedArray sa = resources.obtainAttributes(attrs,
- com.android.internal.R.styleable.Intent);
-
- intent.setAction(sa.getString(com.android.internal.R.styleable.Intent_action));
-
- String data = sa.getString(com.android.internal.R.styleable.Intent_data);
- String mimeType = sa.getString(com.android.internal.R.styleable.Intent_mimeType);
- intent.setDataAndType(data != null ? Uri.parse(data) : null, mimeType);
-
- String packageName = sa.getString(com.android.internal.R.styleable.Intent_targetPackage);
- String className = sa.getString(com.android.internal.R.styleable.Intent_targetClass);
- if (packageName != null && className != null) {
- intent.setComponent(new ComponentName(packageName, className));
- }
-
- sa.recycle();
-
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
-
- String nodeName = parser.getName();
- if (nodeName.equals("category")) {
- sa = resources.obtainAttributes(attrs,
- com.android.internal.R.styleable.IntentCategory);
- String cat = sa.getString(com.android.internal.R.styleable.IntentCategory_name);
- sa.recycle();
-
- if (cat != null) {
- intent.addCategory(cat);
- }
- XmlUtils.skipCurrentTag(parser);
-
- } else if (nodeName.equals("extra")) {
- if (intent.mExtras == null) {
- intent.mExtras = new Bundle();
- }
- resources.parseBundleExtra("extra", attrs, intent.mExtras);
- XmlUtils.skipCurrentTag(parser);
-
- } else {
- XmlUtils.skipCurrentTag(parser);
- }
- }
-
- return intent;
- }
-}
diff --git a/core/java/android/content/IntentFilter.aidl b/core/java/android/content/IntentFilter.aidl
deleted file mode 100644
index a9bcd5e..0000000
--- a/core/java/android/content/IntentFilter.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-parcelable IntentFilter;
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
deleted file mode 100644
index e81bc86..0000000
--- a/core/java/android/content/IntentFilter.java
+++ /dev/null
@@ -1,1408 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.Set;
-
-import android.net.Uri;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PatternMatcher;
-import android.util.AndroidException;
-import android.util.Config;
-import android.util.Log;
-import android.util.Printer;
-import com.android.internal.util.XmlUtils;
-
-/**
- * Structured description of Intent values to be matched. An IntentFilter can
- * match against actions, categories, and data (either via its type, scheme,
- * and/or path) in an Intent. It also includes a "priority" value which is
- * used to order multiple matching filters.
- *
- * <p>IntentFilter objects are often created in XML as part of a package's
- * {@link android.R.styleable#AndroidManifest AndroidManifest.xml} file,
- * using {@link android.R.styleable#AndroidManifestIntentFilter intent-filter}
- * tags.
- *
- * <p>There are three Intent characteristics you can filter on: the
- * <em>action</em>, <em>data</em>, and <em>categories</em>. For each of these
- * characteristics you can provide
- * multiple possible matching values (via {@link #addAction},
- * {@link #addDataType}, {@link #addDataScheme} {@link #addDataAuthority},
- * {@link #addDataPath}, and {@link #addCategory}, respectively).
- * For actions, the field
- * will not be tested if no values have been given (treating it as a wildcard);
- * if no data characteristics are specified, however, then the filter will
- * only match intents that contain no data.
- *
- * <p>The data characteristic is
- * itself divided into three attributes: type, scheme, authority, and path.
- * Any that are
- * specified must match the contents of the Intent. If you specify a scheme
- * but no type, only Intent that does not have a type (such as mailto:) will
- * match; a content: URI will never match because they always have a MIME type
- * that is supplied by their content provider. Specifying a type with no scheme
- * has somewhat special meaning: it will match either an Intent with no URI
- * field, or an Intent with a content: or file: URI. If you specify neither,
- * then only an Intent with no data or type will match. To specify an authority,
- * you must also specify one or more schemes that it is associated with.
- * To specify a path, you also must specify both one or more authorities and
- * one or more schemes it is associated with.
- *
- * <p>A match is based on the following rules. Note that
- * for an IntentFilter to match an Intent, three conditions must hold:
- * the <strong>action</strong> and <strong>category</strong> must match, and
- * the data (both the <strong>data type</strong> and
- * <strong>data scheme+authority+path</strong> if specified) must match.
- *
- * <p><strong>Action</strong> matches if any of the given values match the
- * Intent action, <em>or</em> if no actions were specified in the filter.
- *
- * <p><strong>Data Type</strong> matches if any of the given values match the
- * Intent type. The Intent
- * type is determined by calling {@link Intent#resolveType}. A wildcard can be
- * used for the MIME sub-type, in both the Intent and IntentFilter, so that the
- * type "audio/*" will match "audio/mpeg", "audio/aiff", "audio/*", etc.
- *
- * <p><strong>Data Scheme</strong> matches if any of the given values match the
- * Intent data's scheme.
- * The Intent scheme is determined by calling {@link Intent#getData}
- * and {@link android.net.Uri#getScheme} on that URI.
- *
- * <p><strong>Data Authority</strong> matches if any of the given values match
- * the Intent's data authority <em>and</em> one of the data scheme's in the filter
- * has matched the Intent, <em>or</em> no authories were supplied in the filter.
- * The Intent authority is determined by calling
- * {@link Intent#getData} and {@link android.net.Uri#getAuthority} on that URI.
- *
- * <p><strong>Data Path</strong> matches if any of the given values match the
- * Intent's data path <em>and</em> both a scheme and authority in the filter
- * has matched against the Intent, <em>or</em> no paths were supplied in the
- * filter. The Intent authority is determined by calling
- * {@link Intent#getData} and {@link android.net.Uri#getPath} on that URI.
- *
- * <p><strong>Categories</strong> match if <em>all</em> of the categories in
- * the Intent match categories given in the filter. Extra categories in the
- * filter that are not in the Intent will not cause the match to fail. Note
- * that unlike the action, an IntentFilter with no categories
- * will only match an Intent that does not have any categories.
- */
-public class IntentFilter implements Parcelable {
- private static final String SGLOB_STR = "sglob";
- private static final String PREFIX_STR = "prefix";
- private static final String LITERAL_STR = "literal";
- private static final String PATH_STR = "path";
- private static final String PORT_STR = "port";
- private static final String HOST_STR = "host";
- private static final String AUTH_STR = "auth";
- private static final String SCHEME_STR = "scheme";
- private static final String TYPE_STR = "type";
- private static final String CAT_STR = "cat";
- private static final String NAME_STR = "name";
- private static final String ACTION_STR = "action";
-
- /**
- * The filter {@link #setPriority} value at which system high-priority
- * receivers are placed; that is, receivers that should execute before
- * application code. Applications should never use filters with this or
- * higher priorities.
- *
- * @see #setPriority
- */
- public static final int SYSTEM_HIGH_PRIORITY = 1000;
-
- /**
- * The filter {@link #setPriority} value at which system low-priority
- * receivers are placed; that is, receivers that should execute after
- * application code. Applications should never use filters with this or
- * lower priorities.
- *
- * @see #setPriority
- */
- public static final int SYSTEM_LOW_PRIORITY = -1000;
-
- /**
- * The part of a match constant that describes the category of match
- * that occurred. May be either {@link #MATCH_CATEGORY_EMPTY},
- * {@link #MATCH_CATEGORY_SCHEME}, {@link #MATCH_CATEGORY_HOST},
- * {@link #MATCH_CATEGORY_PORT},
- * {@link #MATCH_CATEGORY_PATH}, or {@link #MATCH_CATEGORY_TYPE}. Higher
- * values indicate a better match.
- */
- public static final int MATCH_CATEGORY_MASK = 0xfff0000;
-
- /**
- * The part of a match constant that applies a quality adjustment to the
- * basic category of match. The value {@link #MATCH_ADJUSTMENT_NORMAL}
- * is no adjustment; higher numbers than that improve the quality, while
- * lower numbers reduce it.
- */
- public static final int MATCH_ADJUSTMENT_MASK = 0x000ffff;
-
- /**
- * Quality adjustment applied to the category of match that signifies
- * the default, base value; higher numbers improve the quality while
- * lower numbers reduce it.
- */
- public static final int MATCH_ADJUSTMENT_NORMAL = 0x8000;
-
- /**
- * The filter matched an intent that had no data specified.
- */
- public static final int MATCH_CATEGORY_EMPTY = 0x0100000;
- /**
- * The filter matched an intent with the same data URI scheme.
- */
- public static final int MATCH_CATEGORY_SCHEME = 0x0200000;
- /**
- * The filter matched an intent with the same data URI scheme and
- * authority host.
- */
- public static final int MATCH_CATEGORY_HOST = 0x0300000;
- /**
- * The filter matched an intent with the same data URI scheme and
- * authority host and port.
- */
- public static final int MATCH_CATEGORY_PORT = 0x0400000;
- /**
- * The filter matched an intent with the same data URI scheme,
- * authority, and path.
- */
- public static final int MATCH_CATEGORY_PATH = 0x0500000;
- /**
- * The filter matched an intent with the same data MIME type.
- */
- public static final int MATCH_CATEGORY_TYPE = 0x0600000;
-
- /**
- * The filter didn't match due to different MIME types.
- */
- public static final int NO_MATCH_TYPE = -1;
- /**
- * The filter didn't match due to different data URIs.
- */
- public static final int NO_MATCH_DATA = -2;
- /**
- * The filter didn't match due to different actions.
- */
- public static final int NO_MATCH_ACTION = -3;
- /**
- * The filter didn't match because it required one or more categories
- * that were not in the Intent.
- */
- public static final int NO_MATCH_CATEGORY = -4;
-
- private int mPriority;
- private final ArrayList<String> mActions;
- private ArrayList<String> mCategories = null;
- private ArrayList<String> mDataSchemes = null;
- private ArrayList<AuthorityEntry> mDataAuthorities = null;
- private ArrayList<PatternMatcher> mDataPaths = null;
- private ArrayList<String> mDataTypes = null;
- private boolean mHasPartialTypes = false;
-
- // These functions are the start of more optimized code for managing
- // the string sets... not yet implemented.
-
- private static int findStringInSet(String[] set, String string,
- int[] lengths, int lenPos) {
- if (set == null) return -1;
- final int N = lengths[lenPos];
- for (int i=0; i<N; i++) {
- if (set[i].equals(string)) return i;
- }
- return -1;
- }
-
- private static String[] addStringToSet(String[] set, String string,
- int[] lengths, int lenPos) {
- if (findStringInSet(set, string, lengths, lenPos) >= 0) return set;
- if (set == null) {
- set = new String[2];
- set[0] = string;
- lengths[lenPos] = 1;
- return set;
- }
- final int N = lengths[lenPos];
- if (N < set.length) {
- set[N] = string;
- lengths[lenPos] = N+1;
- return set;
- }
-
- String[] newSet = new String[(N*3)/2 + 2];
- System.arraycopy(set, 0, newSet, 0, N);
- set = newSet;
- set[N] = string;
- lengths[lenPos] = N+1;
- return set;
- }
-
- private static String[] removeStringFromSet(String[] set, String string,
- int[] lengths, int lenPos) {
- int pos = findStringInSet(set, string, lengths, lenPos);
- if (pos < 0) return set;
- final int N = lengths[lenPos];
- if (N > (set.length/4)) {
- int copyLen = N-(pos+1);
- if (copyLen > 0) {
- System.arraycopy(set, pos+1, set, pos, copyLen);
- }
- set[N-1] = null;
- lengths[lenPos] = N-1;
- return set;
- }
-
- String[] newSet = new String[set.length/3];
- if (pos > 0) System.arraycopy(set, 0, newSet, 0, pos);
- if ((pos+1) < N) System.arraycopy(set, pos+1, newSet, pos, N-(pos+1));
- return newSet;
- }
-
- /**
- * This exception is thrown when a given MIME type does not have a valid
- * syntax.
- */
- public static class MalformedMimeTypeException extends AndroidException {
- public MalformedMimeTypeException() {
- }
-
- public MalformedMimeTypeException(String name) {
- super(name);
- }
- };
-
- /**
- * Create a new IntentFilter instance with a specified action and MIME
- * type, where you know the MIME type is correctly formatted. This catches
- * the {@link MalformedMimeTypeException} exception that the constructor
- * can call and turns it into a runtime exception.
- *
- * @param action The action to match, i.e. Intent.ACTION_VIEW.
- * @param dataType The type to match, i.e. "vnd.android.cursor.dir/person".
- *
- * @return A new IntentFilter for the given action and type.
- *
- * @see #IntentFilter(String, String)
- */
- public static IntentFilter create(String action, String dataType) {
- try {
- return new IntentFilter(action, dataType);
- } catch (MalformedMimeTypeException e) {
- throw new RuntimeException("Bad MIME type", e);
- }
- }
-
- /**
- * New empty IntentFilter.
- */
- public IntentFilter() {
- mPriority = 0;
- mActions = new ArrayList<String>();
- }
-
- /**
- * New IntentFilter that matches a single action with no data. If
- * no data characteristics are subsequently specified, then the
- * filter will only match intents that contain no data.
- *
- * @param action The action to match, i.e. Intent.ACTION_MAIN.
- */
- public IntentFilter(String action) {
- mPriority = 0;
- mActions = new ArrayList<String>();
- addAction(action);
- }
-
- /**
- * New IntentFilter that matches a single action and data type.
- *
- * <p>Throws {@link MalformedMimeTypeException} if the given MIME type is
- * not syntactically correct.
- *
- * @param action The action to match, i.e. Intent.ACTION_VIEW.
- * @param dataType The type to match, i.e. "vnd.android.cursor.dir/person".
- *
- */
- public IntentFilter(String action, String dataType)
- throws MalformedMimeTypeException {
- mPriority = 0;
- mActions = new ArrayList<String>();
- addDataType(dataType);
- }
-
- /**
- * New IntentFilter containing a copy of an existing filter.
- *
- * @param o The original filter to copy.
- */
- public IntentFilter(IntentFilter o) {
- mPriority = o.mPriority;
- mActions = new ArrayList<String>(o.mActions);
- if (o.mCategories != null) {
- mCategories = new ArrayList<String>(o.mCategories);
- }
- if (o.mDataTypes != null) {
- mDataTypes = new ArrayList<String>(o.mDataTypes);
- }
- if (o.mDataSchemes != null) {
- mDataSchemes = new ArrayList<String>(o.mDataSchemes);
- }
- if (o.mDataAuthorities != null) {
- mDataAuthorities = new ArrayList<AuthorityEntry>(o.mDataAuthorities);
- }
- if (o.mDataPaths != null) {
- mDataPaths = new ArrayList<PatternMatcher>(o.mDataPaths);
- }
- mHasPartialTypes = o.mHasPartialTypes;
- }
-
- /**
- * Modify priority of this filter. The default priority is 0. Positive
- * values will be before the default, lower values will be after it.
- * Applications must use a value that is larger than
- * {@link #SYSTEM_LOW_PRIORITY} and smaller than
- * {@link #SYSTEM_HIGH_PRIORITY} .
- *
- * @param priority The new priority value.
- *
- * @see #getPriority
- * @see #SYSTEM_LOW_PRIORITY
- * @see #SYSTEM_HIGH_PRIORITY
- */
- public final void setPriority(int priority) {
- mPriority = priority;
- }
-
- /**
- * Return the priority of this filter.
- *
- * @return The priority of the filter.
- *
- * @see #setPriority
- */
- public final int getPriority() {
- return mPriority;
- }
-
- /**
- * Add a new Intent action to match against. If any actions are included
- * in the filter, then an Intent's action must be one of those values for
- * it to match. If no actions are included, the Intent action is ignored.
- *
- * @param action Name of the action to match, i.e. Intent.ACTION_VIEW.
- */
- public final void addAction(String action) {
- if (!mActions.contains(action)) {
- mActions.add(action.intern());
- }
- }
-
- /**
- * Return the number of actions in the filter.
- */
- public final int countActions() {
- return mActions.size();
- }
-
- /**
- * Return an action in the filter.
- */
- public final String getAction(int index) {
- return mActions.get(index);
- }
-
- /**
- * Is the given action included in the filter? Note that if the filter
- * does not include any actions, false will <em>always</em> be returned.
- *
- * @param action The action to look for.
- *
- * @return True if the action is explicitly mentioned in the filter.
- */
- public final boolean hasAction(String action) {
- return mActions.contains(action);
- }
-
- /**
- * Match this filter against an Intent's action. If the filter does not
- * specify any actions, the match will always fail.
- *
- * @param action The desired action to look for.
- *
- * @return True if the action is listed in the filter or the filter does
- * not specify any actions.
- */
- public final boolean matchAction(String action) {
- if (action == null || mActions == null || mActions.size() == 0) {
- return false;
- }
- return mActions.contains(action);
- }
-
- /**
- * Return an iterator over the filter's actions. If there are no actions,
- * returns null.
- */
- public final Iterator<String> actionsIterator() {
- return mActions != null ? mActions.iterator() : null;
- }
-
- /**
- * Add a new Intent data type to match against. If any types are
- * included in the filter, then an Intent's data must be <em>either</em>
- * one of these types <em>or</em> a matching scheme. If no data types
- * are included, then an Intent will only match if it specifies no data.
- *
- * <p>Throws {@link MalformedMimeTypeException} if the given MIME type is
- * not syntactically correct.
- *
- * @param type Name of the data type to match, i.e. "vnd.android.cursor.dir/person".
- *
- * @see #matchData
- */
- public final void addDataType(String type)
- throws MalformedMimeTypeException {
- final int slashpos = type.indexOf('/');
- final int typelen = type.length();
- if (slashpos > 0 && typelen >= slashpos+2) {
- if (mDataTypes == null) mDataTypes = new ArrayList<String>();
- if (typelen == slashpos+2 && type.charAt(slashpos+1) == '*') {
- String str = type.substring(0, slashpos);
- if (!mDataTypes.contains(str)) {
- mDataTypes.add(str.intern());
- }
- mHasPartialTypes = true;
- } else {
- if (!mDataTypes.contains(type)) {
- mDataTypes.add(type.intern());
- }
- }
- return;
- }
-
- throw new MalformedMimeTypeException(type);
- }
-
- /**
- * Is the given data type included in the filter? Note that if the filter
- * does not include any type, false will <em>always</em> be returned.
- *
- * @param type The data type to look for.
- *
- * @return True if the type is explicitly mentioned in the filter.
- */
- public final boolean hasDataType(String type) {
- return mDataTypes != null && findMimeType(type);
- }
-
- /**
- * Return the number of data types in the filter.
- */
- public final int countDataTypes() {
- return mDataTypes != null ? mDataTypes.size() : 0;
- }
-
- /**
- * Return a data type in the filter.
- */
- public final String getDataType(int index) {
- return mDataTypes.get(index);
- }
-
- /**
- * Return an iterator over the filter's data types.
- */
- public final Iterator<String> typesIterator() {
- return mDataTypes != null ? mDataTypes.iterator() : null;
- }
-
- /**
- * Add a new Intent data scheme to match against. If any schemes are
- * included in the filter, then an Intent's data must be <em>either</em>
- * one of these schemes <em>or</em> a matching data type. If no schemes
- * are included, then an Intent will match only if it includes no data.
- *
- * @param scheme Name of the scheme to match, i.e. "http".
- *
- * @see #matchData
- */
- public final void addDataScheme(String scheme) {
- if (mDataSchemes == null) mDataSchemes = new ArrayList<String>();
- if (!mDataSchemes.contains(scheme)) {
- mDataSchemes.add(scheme.intern());
- }
- }
-
- /**
- * Return the number of data schemes in the filter.
- */
- public final int countDataSchemes() {
- return mDataSchemes != null ? mDataSchemes.size() : 0;
- }
-
- /**
- * Return a data scheme in the filter.
- */
- public final String getDataScheme(int index) {
- return mDataSchemes.get(index);
- }
-
- /**
- * Is the given data scheme included in the filter? Note that if the
- * filter does not include any scheme, false will <em>always</em> be
- * returned.
- *
- * @param scheme The data scheme to look for.
- *
- * @return True if the scheme is explicitly mentioned in the filter.
- */
- public final boolean hasDataScheme(String scheme) {
- return mDataSchemes != null && mDataSchemes.contains(scheme);
- }
-
- /**
- * Return an iterator over the filter's data schemes.
- */
- public final Iterator<String> schemesIterator() {
- return mDataSchemes != null ? mDataSchemes.iterator() : null;
- }
-
- /**
- * This is an entry for a single authority in the Iterator returned by
- * {@link #authoritiesIterator()}.
- */
- public final static class AuthorityEntry {
- private final String mOrigHost;
- private final String mHost;
- private final boolean mWild;
- private final int mPort;
-
- public AuthorityEntry(String host, String port) {
- mOrigHost = host;
- mWild = host.length() > 0 && host.charAt(0) == '*';
- mHost = mWild ? host.substring(1).intern() : host;
- mPort = port != null ? Integer.parseInt(port) : -1;
- }
-
- AuthorityEntry(Parcel src) {
- mOrigHost = src.readString();
- mHost = src.readString();
- mWild = src.readInt() != 0;
- mPort = src.readInt();
- }
-
- void writeToParcel(Parcel dest) {
- dest.writeString(mOrigHost);
- dest.writeString(mHost);
- dest.writeInt(mWild ? 1 : 0);
- dest.writeInt(mPort);
- }
-
- public String getHost() {
- return mOrigHost;
- }
-
- public int getPort() {
- return mPort;
- }
-
- public int match(Uri data) {
- String host = data.getHost();
- if (host == null) {
- return NO_MATCH_DATA;
- }
- if (Config.LOGV) Log.v("IntentFilter",
- "Match host " + host + ": " + mHost);
- if (mWild) {
- if (host.length() < mHost.length()) {
- return NO_MATCH_DATA;
- }
- host = host.substring(host.length()-mHost.length());
- }
- if (host.compareToIgnoreCase(mHost) != 0) {
- return NO_MATCH_DATA;
- }
- if (mPort >= 0) {
- if (mPort != data.getPort()) {
- return NO_MATCH_DATA;
- }
- return MATCH_CATEGORY_PORT;
- }
- return MATCH_CATEGORY_HOST;
- }
- };
-
- /**
- * Add a new Intent data authority to match against. The filter must
- * include one or more schemes (via {@link #addDataScheme}) for the
- * authority to be considered. If any authorities are
- * included in the filter, then an Intent's data must match one of
- * them. If no authorities are included, then only the scheme must match.
- *
- * @param host The host part of the authority to match. May start with a
- * single '*' to wildcard the front of the host name.
- * @param port Optional port part of the authority to match. If null, any
- * port is allowed.
- *
- * @see #matchData
- * @see #addDataScheme
- */
- public final void addDataAuthority(String host, String port) {
- if (mDataAuthorities == null) mDataAuthorities =
- new ArrayList<AuthorityEntry>();
- if (port != null) port = port.intern();
- mDataAuthorities.add(new AuthorityEntry(host.intern(), port));
- }
-
- /**
- * Return the number of data authorities in the filter.
- */
- public final int countDataAuthorities() {
- return mDataAuthorities != null ? mDataAuthorities.size() : 0;
- }
-
- /**
- * Return a data authority in the filter.
- */
- public final AuthorityEntry getDataAuthority(int index) {
- return mDataAuthorities.get(index);
- }
-
- /**
- * Is the given data authority included in the filter? Note that if the
- * filter does not include any authorities, false will <em>always</em> be
- * returned.
- *
- * @param data The data whose authority is being looked for.
- *
- * @return Returns true if the data string matches an authority listed in the
- * filter.
- */
- public final boolean hasDataAuthority(Uri data) {
- return matchDataAuthority(data) >= 0;
- }
-
- /**
- * Return an iterator over the filter's data authorities.
- */
- public final Iterator<AuthorityEntry> authoritiesIterator() {
- return mDataAuthorities != null ? mDataAuthorities.iterator() : null;
- }
-
- /**
- * Add a new Intent data oath to match against. The filter must
- * include one or more schemes (via {@link #addDataScheme}) <em>and</em>
- * one or more authorities (via {@link #addDataAuthority}) for the
- * path to be considered. If any paths are
- * included in the filter, then an Intent's data must match one of
- * them. If no paths are included, then only the scheme/authority must
- * match.
- *
- * <p>The path given here can either be a literal that must directly
- * match or match against a prefix, or it can be a simple globbing pattern.
- * If the latter, you can use '*' anywhere in the pattern to match zero
- * or more instances of the previous character, '.' as a wildcard to match
- * any character, and '\' to escape the next character.
- *
- * @param path Either a raw string that must exactly match the file
- * path, or a simple pattern, depending on <var>type</var>.
- * @param type Determines how <var>path</var> will be compared to
- * determine a match: either {@link PatternMatcher#PATTERN_LITERAL},
- * {@link PatternMatcher#PATTERN_PREFIX}, or
- * {@link PatternMatcher#PATTERN_SIMPLE_GLOB}.
- *
- * @see #matchData
- * @see #addDataScheme
- * @see #addDataAuthority
- */
- public final void addDataPath(String path, int type) {
- if (mDataPaths == null) mDataPaths = new ArrayList<PatternMatcher>();
- mDataPaths.add(new PatternMatcher(path.intern(), type));
- }
-
- /**
- * Return the number of data paths in the filter.
- */
- public final int countDataPaths() {
- return mDataPaths != null ? mDataPaths.size() : 0;
- }
-
- /**
- * Return a data path in the filter.
- */
- public final PatternMatcher getDataPath(int index) {
- return mDataPaths.get(index);
- }
-
- /**
- * Is the given data path included in the filter? Note that if the
- * filter does not include any paths, false will <em>always</em> be
- * returned.
- *
- * @param data The data path to look for. This is without the scheme
- * prefix.
- *
- * @return True if the data string matches a path listed in the
- * filter.
- */
- public final boolean hasDataPath(String data) {
- if (mDataPaths == null) {
- return false;
- }
- Iterator<PatternMatcher> i = mDataPaths.iterator();
- while (i.hasNext()) {
- final PatternMatcher pe = i.next();
- if (pe.match(data)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Return an iterator over the filter's data paths.
- */
- public final Iterator<PatternMatcher> pathsIterator() {
- return mDataPaths != null ? mDataPaths.iterator() : null;
- }
-
- /**
- * Match this intent filter against the given Intent data. This ignores
- * the data scheme -- unlike {@link #matchData}, the authority will match
- * regardless of whether there is a matching scheme.
- *
- * @param data The data whose authority is being looked for.
- *
- * @return Returns either {@link #MATCH_CATEGORY_HOST},
- * {@link #MATCH_CATEGORY_PORT}, {@link #NO_MATCH_DATA}.
- */
- public final int matchDataAuthority(Uri data) {
- if (mDataAuthorities == null) {
- return NO_MATCH_DATA;
- }
- Iterator<AuthorityEntry> i = mDataAuthorities.iterator();
- while (i.hasNext()) {
- final AuthorityEntry ae = i.next();
- int match = ae.match(data);
- if (match >= 0) {
- return match;
- }
- }
- return NO_MATCH_DATA;
- }
-
- /**
- * Match this filter against an Intent's data (type, scheme and path). If
- * the filter does not specify any types and does not specify any
- * schemes/paths, the match will only succeed if the intent does not
- * also specify a type or data.
- *
- * <p>Note that to match against an authority, you must also specify a base
- * scheme the authority is in. To match against a data path, both a scheme
- * and authority must be specified. If the filter does not specify any
- * types or schemes that it matches against, it is considered to be empty
- * (any authority or data path given is ignored, as if it were empty as
- * well).
- *
- * @param type The desired data type to look for, as returned by
- * Intent.resolveType().
- * @param scheme The desired data scheme to look for, as returned by
- * Intent.getScheme().
- * @param data The full data string to match against, as supplied in
- * Intent.data.
- *
- * @return Returns either a valid match constant (a combination of
- * {@link #MATCH_CATEGORY_MASK} and {@link #MATCH_ADJUSTMENT_MASK}),
- * or one of the error codes {@link #NO_MATCH_TYPE} if the type didn't match
- * or {@link #NO_MATCH_DATA} if the scheme/path didn't match.
- *
- * @see #match
- */
- public final int matchData(String type, String scheme, Uri data) {
- final ArrayList<String> types = mDataTypes;
- final ArrayList<String> schemes = mDataSchemes;
- final ArrayList<AuthorityEntry> authorities = mDataAuthorities;
- final ArrayList<PatternMatcher> paths = mDataPaths;
-
- int match = MATCH_CATEGORY_EMPTY;
-
- if (types == null && schemes == null) {
- return ((type == null && data == null)
- ? (MATCH_CATEGORY_EMPTY+MATCH_ADJUSTMENT_NORMAL) : NO_MATCH_DATA);
- }
-
- if (schemes != null) {
- if (schemes.contains(scheme != null ? scheme : "")) {
- match = MATCH_CATEGORY_SCHEME;
- } else {
- return NO_MATCH_DATA;
- }
-
- if (authorities != null) {
- int authMatch = matchDataAuthority(data);
- if (authMatch >= 0) {
- if (paths == null) {
- match = authMatch;
- } else if (hasDataPath(data.getPath())) {
- match = MATCH_CATEGORY_PATH;
- } else {
- return NO_MATCH_DATA;
- }
- } else {
- return NO_MATCH_DATA;
- }
- }
- } else {
- // Special case: match either an Intent with no data URI,
- // or with a scheme: URI. This is to give a convenience for
- // the common case where you want to deal with data in a
- // content provider, which is done by type, and we don't want
- // to force everyone to say they handle content: or file: URIs.
- if (scheme != null && !"".equals(scheme)
- && !"content".equals(scheme)
- && !"file".equals(scheme)) {
- return NO_MATCH_DATA;
- }
- }
-
- if (types != null) {
- if (findMimeType(type)) {
- match = MATCH_CATEGORY_TYPE;
- } else {
- return NO_MATCH_TYPE;
- }
- } else {
- // If no MIME types are specified, then we will only match against
- // an Intent that does not have a MIME type.
- if (type != null) {
- return NO_MATCH_TYPE;
- }
- }
-
- return match + MATCH_ADJUSTMENT_NORMAL;
- }
-
- /**
- * Add a new Intent category to match against. The semantics of
- * categories is the opposite of actions -- an Intent includes the
- * categories that it requires, all of which must be included in the
- * filter in order to match. In other words, adding a category to the
- * filter has no impact on matching unless that category is specified in
- * the intent.
- *
- * @param category Name of category to match, i.e. Intent.CATEGORY_EMBED.
- */
- public final void addCategory(String category) {
- if (mCategories == null) mCategories = new ArrayList<String>();
- if (!mCategories.contains(category)) {
- mCategories.add(category.intern());
- }
- }
-
- /**
- * Return the number of categories in the filter.
- */
- public final int countCategories() {
- return mCategories != null ? mCategories.size() : 0;
- }
-
- /**
- * Return a category in the filter.
- */
- public final String getCategory(int index) {
- return mCategories.get(index);
- }
-
- /**
- * Is the given category included in the filter?
- *
- * @param category The category that the filter supports.
- *
- * @return True if the category is explicitly mentioned in the filter.
- */
- public final boolean hasCategory(String category) {
- return mCategories != null && mCategories.contains(category);
- }
-
- /**
- * Return an iterator over the filter's categories.
- */
- public final Iterator<String> categoriesIterator() {
- return mCategories != null ? mCategories.iterator() : null;
- }
-
- /**
- * Match this filter against an Intent's categories. Each category in
- * the Intent must be specified by the filter; if any are not in the
- * filter, the match fails.
- *
- * @param categories The categories included in the intent, as returned by
- * Intent.getCategories().
- *
- * @return If all categories match (success), null; else the name of the
- * first category that didn't match.
- */
- public final String matchCategories(Set<String> categories) {
- if (categories == null) {
- return null;
- }
-
- Iterator<String> it = categories.iterator();
-
- if (mCategories == null) {
- return it.hasNext() ? it.next() : null;
- }
-
- while (it.hasNext()) {
- final String category = it.next();
- if (!mCategories.contains(category)) {
- return category;
- }
- }
-
- return null;
- }
-
- /**
- * Test whether this filter matches the given <var>intent</var>.
- *
- * @param intent The Intent to compare against.
- * @param resolve If true, the intent's type will be resolved by calling
- * Intent.resolveType(); otherwise a simple match against
- * Intent.type will be performed.
- * @param logTag Tag to use in debugging messages.
- *
- * @return Returns either a valid match constant (a combination of
- * {@link #MATCH_CATEGORY_MASK} and {@link #MATCH_ADJUSTMENT_MASK}),
- * or one of the error codes {@link #NO_MATCH_TYPE} if the type didn't match,
- * {@link #NO_MATCH_DATA} if the scheme/path didn't match,
- * {@link #NO_MATCH_ACTION if the action didn't match, or
- * {@link #NO_MATCH_CATEGORY} if one or more categories didn't match.
- *
- * @return How well the filter matches. Negative if it doesn't match,
- * zero or positive positive value if it does with a higher
- * value representing a better match.
- *
- * @see #match(String, String, String, android.net.Uri , Set, String)
- */
- public final int match(ContentResolver resolver, Intent intent,
- boolean resolve, String logTag) {
- String type = resolve ? intent.resolveType(resolver) : intent.getType();
- return match(intent.getAction(), type, intent.getScheme(),
- intent.getData(), intent.getCategories(), logTag);
- }
-
- /**
- * Test whether this filter matches the given intent data. A match is
- * only successful if the actions and categories in the Intent match
- * against the filter, as described in {@link IntentFilter}; in that case,
- * the match result returned will be as per {@link #matchData}.
- *
- * @param action The intent action to match against (Intent.getAction).
- * @param type The intent type to match against (Intent.resolveType()).
- * @param scheme The data scheme to match against (Intent.getScheme()).
- * @param data The data URI to match against (Intent.getData()).
- * @param categories The categories to match against
- * (Intent.getCategories()).
- * @param logTag Tag to use in debugging messages.
- *
- * @return Returns either a valid match constant (a combination of
- * {@link #MATCH_CATEGORY_MASK} and {@link #MATCH_ADJUSTMENT_MASK}),
- * or one of the error codes {@link #NO_MATCH_TYPE} if the type didn't match,
- * {@link #NO_MATCH_DATA} if the scheme/path didn't match,
- * {@link #NO_MATCH_ACTION if the action didn't match, or
- * {@link #NO_MATCH_CATEGORY} if one or more categories didn't match.
- *
- * @see #matchData
- * @see Intent#getAction
- * @see Intent#resolveType
- * @see Intent#getScheme
- * @see Intent#getData
- * @see Intent#getCategories
- */
- public final int match(String action, String type, String scheme,
- Uri data, Set<String> categories, String logTag) {
- if (action != null && !matchAction(action)) {
- if (Config.LOGV) Log.v(
- logTag, "No matching action " + action + " for " + this);
- return NO_MATCH_ACTION;
- }
-
- int dataMatch = matchData(type, scheme, data);
- if (dataMatch < 0) {
- if (Config.LOGV) {
- if (dataMatch == NO_MATCH_TYPE) {
- Log.v(logTag, "No matching type " + type
- + " for " + this);
- }
- if (dataMatch == NO_MATCH_DATA) {
- Log.v(logTag, "No matching scheme/path " + data
- + " for " + this);
- }
- }
- return dataMatch;
- }
-
- String categoryMatch = matchCategories(categories);
- if (categoryMatch != null) {
- if (Config.LOGV) Log.v(
- logTag, "No matching category "
- + categoryMatch + " for " + this);
- return NO_MATCH_CATEGORY;
- }
-
- // It would be nice to treat container activities as more
- // important than ones that can be embedded, but this is not the way...
- if (false) {
- if (categories != null) {
- dataMatch -= mCategories.size() - categories.size();
- }
- }
-
- return dataMatch;
- }
-
- /**
- * Write the contents of the IntentFilter as an XML stream.
- */
- public void writeToXml(XmlSerializer serializer) throws IOException {
- int N = countActions();
- for (int i=0; i<N; i++) {
- serializer.startTag(null, ACTION_STR);
- serializer.attribute(null, NAME_STR, mActions.get(i));
- serializer.endTag(null, ACTION_STR);
- }
- N = countCategories();
- for (int i=0; i<N; i++) {
- serializer.startTag(null, CAT_STR);
- serializer.attribute(null, NAME_STR, mCategories.get(i));
- serializer.endTag(null, CAT_STR);
- }
- N = countDataTypes();
- for (int i=0; i<N; i++) {
- serializer.startTag(null, TYPE_STR);
- String type = mDataTypes.get(i);
- if (type.indexOf('/') < 0) type = type + "/*";
- serializer.attribute(null, NAME_STR, type);
- serializer.endTag(null, TYPE_STR);
- }
- N = countDataSchemes();
- for (int i=0; i<N; i++) {
- serializer.startTag(null, SCHEME_STR);
- serializer.attribute(null, NAME_STR, mDataSchemes.get(i));
- serializer.endTag(null, SCHEME_STR);
- }
- N = countDataAuthorities();
- for (int i=0; i<N; i++) {
- serializer.startTag(null, AUTH_STR);
- AuthorityEntry ae = mDataAuthorities.get(i);
- serializer.attribute(null, HOST_STR, ae.getHost());
- if (ae.getPort() >= 0) {
- serializer.attribute(null, PORT_STR, Integer.toString(ae.getPort()));
- }
- serializer.endTag(null, AUTH_STR);
- }
- N = countDataPaths();
- for (int i=0; i<N; i++) {
- serializer.startTag(null, PATH_STR);
- PatternMatcher pe = mDataPaths.get(i);
- switch (pe.getType()) {
- case PatternMatcher.PATTERN_LITERAL:
- serializer.attribute(null, LITERAL_STR, pe.getPath());
- break;
- case PatternMatcher.PATTERN_PREFIX:
- serializer.attribute(null, PREFIX_STR, pe.getPath());
- break;
- case PatternMatcher.PATTERN_SIMPLE_GLOB:
- serializer.attribute(null, SGLOB_STR, pe.getPath());
- break;
- }
- serializer.endTag(null, PATH_STR);
- }
- }
-
- public void readFromXml(XmlPullParser parser) throws XmlPullParserException,
- IOException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG
- || type == XmlPullParser.TEXT) {
- continue;
- }
-
- String tagName = parser.getName();
- if (tagName.equals(ACTION_STR)) {
- String name = parser.getAttributeValue(null, NAME_STR);
- if (name != null) {
- addAction(name);
- }
- } else if (tagName.equals(CAT_STR)) {
- String name = parser.getAttributeValue(null, NAME_STR);
- if (name != null) {
- addCategory(name);
- }
- } else if (tagName.equals(TYPE_STR)) {
- String name = parser.getAttributeValue(null, NAME_STR);
- if (name != null) {
- try {
- addDataType(name);
- } catch (MalformedMimeTypeException e) {
- }
- }
- } else if (tagName.equals(SCHEME_STR)) {
- String name = parser.getAttributeValue(null, NAME_STR);
- if (name != null) {
- addDataScheme(name);
- }
- } else if (tagName.equals(AUTH_STR)) {
- String host = parser.getAttributeValue(null, HOST_STR);
- String port = parser.getAttributeValue(null, PORT_STR);
- if (host != null) {
- addDataAuthority(host, port);
- }
- } else if (tagName.equals(PATH_STR)) {
- String path = parser.getAttributeValue(null, LITERAL_STR);
- if (path != null) {
- addDataPath(path, PatternMatcher.PATTERN_LITERAL);
- } else if ((path=parser.getAttributeValue(null, PREFIX_STR)) != null) {
- addDataPath(path, PatternMatcher.PATTERN_PREFIX);
- } else if ((path=parser.getAttributeValue(null, SGLOB_STR)) != null) {
- addDataPath(path, PatternMatcher.PATTERN_SIMPLE_GLOB);
- }
- } else {
- Log.w("IntentFilter", "Unknown tag parsing IntentFilter: " + tagName);
- }
- XmlUtils.skipCurrentTag(parser);
- }
- }
-
- public void dump(Printer du, String prefix) {
- if (mActions.size() > 0) {
- Iterator<String> it = mActions.iterator();
- while (it.hasNext()) {
- du.println(prefix + "Action: \"" + it.next() + "\"");
- }
- }
- if (mCategories != null) {
- Iterator<String> it = mCategories.iterator();
- while (it.hasNext()) {
- du.println(prefix + "Category: \"" + it.next() + "\"");
- }
- }
- if (mDataSchemes != null) {
- Iterator<String> it = mDataSchemes.iterator();
- while (it.hasNext()) {
- du.println(prefix + "Data Scheme: \"" + it.next() + "\"");
- }
- }
- if (mDataAuthorities != null) {
- Iterator<AuthorityEntry> it = mDataAuthorities.iterator();
- while (it.hasNext()) {
- AuthorityEntry ae = it.next();
- du.println(prefix + "Data Authority: \"" + ae.mHost + "\":"
- + ae.mPort + (ae.mWild ? " WILD" : ""));
- }
- }
- if (mDataPaths != null) {
- Iterator<PatternMatcher> it = mDataPaths.iterator();
- while (it.hasNext()) {
- PatternMatcher pe = it.next();
- du.println(prefix + "Data Path: \"" + pe + "\"");
- }
- }
- if (mDataTypes != null) {
- Iterator<String> it = mDataTypes.iterator();
- while (it.hasNext()) {
- du.println(prefix + "Data Type: \"" + it.next() + "\"");
- }
- }
- du.println(prefix + "mPriority=" + mPriority
- + ", mHasPartialTypes=" + mHasPartialTypes);
- }
-
- public static final Parcelable.Creator<IntentFilter> CREATOR
- = new Parcelable.Creator<IntentFilter>() {
- public IntentFilter createFromParcel(Parcel source) {
- return new IntentFilter(source);
- }
-
- public IntentFilter[] newArray(int size) {
- return new IntentFilter[size];
- }
- };
-
- public final int describeContents() {
- return 0;
- }
-
- public final void writeToParcel(Parcel dest, int flags) {
- dest.writeStringList(mActions);
- if (mCategories != null) {
- dest.writeInt(1);
- dest.writeStringList(mCategories);
- } else {
- dest.writeInt(0);
- }
- if (mDataSchemes != null) {
- dest.writeInt(1);
- dest.writeStringList(mDataSchemes);
- } else {
- dest.writeInt(0);
- }
- if (mDataTypes != null) {
- dest.writeInt(1);
- dest.writeStringList(mDataTypes);
- } else {
- dest.writeInt(0);
- }
- if (mDataAuthorities != null) {
- final int N = mDataAuthorities.size();
- dest.writeInt(N);
- for (int i=0; i<N; i++) {
- mDataAuthorities.get(i).writeToParcel(dest);
- }
- } else {
- dest.writeInt(0);
- }
- if (mDataPaths != null) {
- final int N = mDataPaths.size();
- dest.writeInt(N);
- for (int i=0; i<N; i++) {
- mDataPaths.get(i).writeToParcel(dest, 0);
- }
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(mPriority);
- dest.writeInt(mHasPartialTypes ? 1 : 0);
- }
-
- /**
- * For debugging -- perform a check on the filter, return true if it passed
- * or false if it failed.
- *
- * {@hide}
- */
- public boolean debugCheck() {
- return true;
-
- // This code looks for intent filters that do not specify data.
- /*
- if (mActions != null && mActions.size() == 1
- && mActions.contains(Intent.ACTION_MAIN)) {
- return true;
- }
-
- if (mDataTypes == null && mDataSchemes == null) {
- Log.w("IntentFilter", "QUESTIONABLE INTENT FILTER:");
- dump(Log.WARN, "IntentFilter", " ");
- return false;
- }
-
- return true;
- */
- }
-
- private IntentFilter(Parcel source) {
- mActions = new ArrayList<String>();
- source.readStringList(mActions);
- if (source.readInt() != 0) {
- mCategories = new ArrayList<String>();
- source.readStringList(mCategories);
- }
- if (source.readInt() != 0) {
- mDataSchemes = new ArrayList<String>();
- source.readStringList(mDataSchemes);
- }
- if (source.readInt() != 0) {
- mDataTypes = new ArrayList<String>();
- source.readStringList(mDataTypes);
- }
- int N = source.readInt();
- if (N > 0) {
- mDataAuthorities = new ArrayList<AuthorityEntry>();
- for (int i=0; i<N; i++) {
- mDataAuthorities.add(new AuthorityEntry(source));
- }
- }
- N = source.readInt();
- if (N > 0) {
- mDataPaths = new ArrayList<PatternMatcher>();
- for (int i=0; i<N; i++) {
- mDataPaths.add(new PatternMatcher(source));
- }
- }
- mPriority = source.readInt();
- mHasPartialTypes = source.readInt() > 0;
- }
-
- private final boolean findMimeType(String type) {
- final ArrayList<String> t = mDataTypes;
-
- if (type == null) {
- return false;
- }
-
- if (t.contains(type)) {
- return true;
- }
-
- // Deal with an Intent wanting to match every type in the IntentFilter.
- final int typeLength = type.length();
- if (typeLength == 3 && type.equals("*/*")) {
- return !t.isEmpty();
- }
-
- // Deal with this IntentFilter wanting to match every Intent type.
- if (mHasPartialTypes && t.contains("*")) {
- return true;
- }
-
- final int slashpos = type.indexOf('/');
- if (slashpos > 0) {
- if (mHasPartialTypes && t.contains(type.substring(0, slashpos))) {
- return true;
- }
- if (typeLength == slashpos+2 && type.charAt(slashpos+1) == '*') {
- // Need to look through all types for one that matches
- // our base...
- final Iterator<String> it = t.iterator();
- while (it.hasNext()) {
- String v = it.next();
- if (type.regionMatches(0, v, 0, slashpos+1)) {
- return true;
- }
- }
- }
- }
-
- return false;
- }
-}
diff --git a/core/java/android/content/MutableContextWrapper.java b/core/java/android/content/MutableContextWrapper.java
deleted file mode 100644
index 820479c..0000000
--- a/core/java/android/content/MutableContextWrapper.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-/**
- * Special version of {@link ContextWrapper} that allows the base context to
- * be modified after it is initially set.
- */
-public class MutableContextWrapper extends ContextWrapper {
- public MutableContextWrapper(Context base) {
- super(base);
- }
-
- /**
- * Change the base context for this ContextWrapper. All calls will then be
- * delegated to the base context. Unlike ContextWrapper, the base context
- * can be changed even after one is already set.
- *
- * @param base The new base context for this wrapper.
- */
- public void setBaseContext(Context base) {
- mBase = base;
- }
-}
diff --git a/core/java/android/content/ReceiverCallNotAllowedException.java b/core/java/android/content/ReceiverCallNotAllowedException.java
deleted file mode 100644
index 96b269c..0000000
--- a/core/java/android/content/ReceiverCallNotAllowedException.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.util.AndroidRuntimeException;
-
-/**
- * This exception is thrown from {@link Context#registerReceiver} and
- * {@link Context#bindService} when these methods are being used from
- * an {@link BroadcastReceiver} component. In this case, the component will no
- * longer be active upon returning from receiving the Intent, so it is
- * not valid to use asynchronous APIs.
- */
-public class ReceiverCallNotAllowedException extends AndroidRuntimeException {
- public ReceiverCallNotAllowedException(String msg) {
- super(msg);
- }
-}
diff --git a/core/java/android/content/SearchRecentSuggestionsProvider.java b/core/java/android/content/SearchRecentSuggestionsProvider.java
deleted file mode 100644
index 3d89e92..0000000
--- a/core/java/android/content/SearchRecentSuggestionsProvider.java
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.app.SearchManager;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-import android.text.TextUtils;
-import android.util.Log;
-
-/**
- * This superclass can be used to create a simple search suggestions provider for your application.
- * It creates suggestions (as the user types) based on recent queries and/or recent views.
- *
- * <p>In order to use this class, you must do the following.
- *
- * <ul>
- * <li>Implement and test query search, as described in {@link android.app.SearchManager}. (This
- * provider will send any suggested queries via the standard
- * {@link android.content.Intent#ACTION_SEARCH ACTION_SEARCH} Intent, which you'll already
- * support once you have implemented and tested basic searchability.)</li>
- * <li>Create a Content Provider within your application by extending
- * {@link android.content.SearchRecentSuggestionsProvider}. The class you create will be
- * very simple - typically, it will have only a constructor. But the constructor has a very
- * important responsibility: When it calls {@link #setupSuggestions(String, int)}, it
- * <i>configures</i> the provider to match the requirements of your searchable activity.</li>
- * <li>Create a manifest entry describing your provider. Typically this would be as simple
- * as adding the following lines:
- * <pre class="prettyprint">
- * &lt;!-- Content provider for search suggestions --&gt;
- * &lt;provider android:name="YourSuggestionProviderClass"
- * android:authorities="your.suggestion.authority" /&gt;</pre>
- * </li>
- * <li>Please note that you <i>do not</i> instantiate this content provider directly from within
- * your code. This is done automatically by the system Content Resolver, when the search dialog
- * looks for suggestions.</li>
- * <li>In order for the Content Resolver to do this, you must update your searchable activity's
- * XML configuration file with information about your content provider. The following additions
- * are usually sufficient:
- * <pre class="prettyprint">
- * android:searchSuggestAuthority="your.suggestion.authority"
- * android:searchSuggestSelection=" ? "</pre>
- * </li>
- * <li>In your searchable activities, capture any user-generated queries and record them
- * for future searches by calling {@link android.provider.SearchRecentSuggestions#saveRecentQuery
- * SearchRecentSuggestions.saveRecentQuery()}.</li>
- * </ul>
- *
- * @see android.provider.SearchRecentSuggestions
- */
-public class SearchRecentSuggestionsProvider extends ContentProvider {
- // debugging support
- private static final String TAG = "SuggestionsProvider";
-
- // client-provided configuration values
- private String mAuthority;
- private int mMode;
- private boolean mTwoLineDisplay;
-
- // general database configuration and tables
- private SQLiteOpenHelper mOpenHelper;
- private static final String sDatabaseName = "suggestions.db";
- private static final String sSuggestions = "suggestions";
- private static final String ORDER_BY = "date DESC";
- private static final String NULL_COLUMN = "query";
-
- // Table of database versions. Don't forget to update!
- // NOTE: These version values are shifted left 8 bits (x 256) in order to create space for
- // a small set of mode bitflags in the version int.
- //
- // 1 original implementation with queries, and 1 or 2 display columns
- // 1->2 added UNIQUE constraint to display1 column
- private static final int DATABASE_VERSION = 2 * 256;
-
- /**
- * This mode bit configures the database to record recent queries. <i>required</i>
- *
- * @see #setupSuggestions(String, int)
- */
- public static final int DATABASE_MODE_QUERIES = 1;
- /**
- * This mode bit configures the database to include a 2nd annotation line with each entry.
- * <i>optional</i>
- *
- * @see #setupSuggestions(String, int)
- */
- public static final int DATABASE_MODE_2LINES = 2;
-
- // Uri and query support
- private static final int URI_MATCH_SUGGEST = 1;
-
- private Uri mSuggestionsUri;
- private UriMatcher mUriMatcher;
-
- private String mSuggestSuggestionClause;
- private String[] mSuggestionProjection;
-
- /**
- * Builds the database. This version has extra support for using the version field
- * as a mode flags field, and configures the database columns depending on the mode bits
- * (features) requested by the extending class.
- *
- * @hide
- */
- private static class DatabaseHelper extends SQLiteOpenHelper {
-
- private int mNewVersion;
-
- public DatabaseHelper(Context context, int newVersion) {
- super(context, sDatabaseName, null, newVersion);
- mNewVersion = newVersion;
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- StringBuilder builder = new StringBuilder();
- builder.append("CREATE TABLE suggestions (" +
- "_id INTEGER PRIMARY KEY" +
- ",display1 TEXT UNIQUE ON CONFLICT REPLACE");
- if (0 != (mNewVersion & DATABASE_MODE_2LINES)) {
- builder.append(",display2 TEXT");
- }
- builder.append(",query TEXT" +
- ",date LONG" +
- ");");
- db.execSQL(builder.toString());
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
- + newVersion + ", which will destroy all old data");
- db.execSQL("DROP TABLE IF EXISTS suggestions");
- onCreate(db);
- }
- }
-
- /**
- * In order to use this class, you must extend it, and call this setup function from your
- * constructor. In your application or activities, you must provide the same values when
- * you create the {@link android.provider.SearchRecentSuggestions} helper.
- *
- * @param authority This must match the authority that you've declared in your manifest.
- * @param mode You can use mode flags here to determine certain functional aspects of your
- * database. Note, this value should not change from run to run, because when it does change,
- * your suggestions database may be wiped.
- *
- * @see #DATABASE_MODE_QUERIES
- * @see #DATABASE_MODE_2LINES
- */
- protected void setupSuggestions(String authority, int mode) {
- if (TextUtils.isEmpty(authority) ||
- ((mode & DATABASE_MODE_QUERIES) == 0)) {
- throw new IllegalArgumentException();
- }
- // unpack mode flags
- mTwoLineDisplay = (0 != (mode & DATABASE_MODE_2LINES));
-
- // saved values
- mAuthority = new String(authority);
- mMode = mode;
-
- // derived values
- mSuggestionsUri = Uri.parse("content://" + mAuthority + "/suggestions");
- mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
- mUriMatcher.addURI(mAuthority, SearchManager.SUGGEST_URI_PATH_QUERY, URI_MATCH_SUGGEST);
-
- if (mTwoLineDisplay) {
- mSuggestSuggestionClause = "display1 LIKE ? OR display2 LIKE ?";
-
- mSuggestionProjection = new String [] {
- "0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT,
- "display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
- "display2 AS " + SearchManager.SUGGEST_COLUMN_TEXT_2,
- "query AS " + SearchManager.SUGGEST_COLUMN_QUERY,
- "_id"
- };
- } else {
- mSuggestSuggestionClause = "display1 LIKE ?";
-
- mSuggestionProjection = new String [] {
- "0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT,
- "display1 AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
- "query AS " + SearchManager.SUGGEST_COLUMN_QUERY,
- "_id"
- };
- }
-
-
- }
-
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
- final int length = uri.getPathSegments().size();
- if (length != 1) {
- throw new IllegalArgumentException("Unknown Uri");
- }
-
- final String base = uri.getPathSegments().get(0);
- int count = 0;
- if (base.equals(sSuggestions)) {
- count = db.delete(sSuggestions, selection, selectionArgs);
- } else {
- throw new IllegalArgumentException("Unknown Uri");
- }
- getContext().getContentResolver().notifyChange(uri, null);
- return count;
- }
-
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- @Override
- public String getType(Uri uri) {
- if (mUriMatcher.match(uri) == URI_MATCH_SUGGEST) {
- return SearchManager.SUGGEST_MIME_TYPE;
- }
- int length = uri.getPathSegments().size();
- if (length >= 1) {
- String base = uri.getPathSegments().get(0);
- if (base.equals(sSuggestions)) {
- if (length == 1) {
- return "vnd.android.cursor.dir/suggestion";
- } else if (length == 2) {
- return "vnd.android.cursor.item/suggestion";
- }
- }
- }
- throw new IllegalArgumentException("Unknown Uri");
- }
-
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
- int length = uri.getPathSegments().size();
- if (length < 1) {
- throw new IllegalArgumentException("Unknown Uri");
- }
- // Note: This table has on-conflict-replace semantics, so insert() may actually replace()
- long rowID = -1;
- String base = uri.getPathSegments().get(0);
- Uri newUri = null;
- if (base.equals(sSuggestions)) {
- if (length == 1) {
- rowID = db.insert(sSuggestions, NULL_COLUMN, values);
- if (rowID > 0) {
- newUri = Uri.withAppendedPath(mSuggestionsUri, String.valueOf(rowID));
- }
- }
- }
- if (rowID < 0) {
- throw new IllegalArgumentException("Unknown Uri");
- }
- getContext().getContentResolver().notifyChange(newUri, null);
- return newUri;
- }
-
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- @Override
- public boolean onCreate() {
- if (mAuthority == null || mMode == 0) {
- throw new IllegalArgumentException("Provider not configured");
- }
- int mWorkingDbVersion = DATABASE_VERSION + mMode;
- mOpenHelper = new DatabaseHelper(getContext(), mWorkingDbVersion);
-
- return true;
- }
-
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- // TODO: Confirm no injection attacks here, or rewrite.
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-
- // special case for actual suggestions (from search manager)
- if (mUriMatcher.match(uri) == URI_MATCH_SUGGEST) {
- String suggestSelection;
- String[] myArgs;
- if (TextUtils.isEmpty(selectionArgs[0])) {
- suggestSelection = null;
- myArgs = null;
- } else {
- String like = "%" + selectionArgs[0] + "%";
- if (mTwoLineDisplay) {
- myArgs = new String [] { like, like };
- } else {
- myArgs = new String [] { like };
- }
- suggestSelection = mSuggestSuggestionClause;
- }
- // Suggestions are always performed with the default sort order
- Cursor c = db.query(sSuggestions, mSuggestionProjection,
- suggestSelection, myArgs, null, null, ORDER_BY, null);
- c.setNotificationUri(getContext().getContentResolver(), uri);
- return c;
- }
-
- // otherwise process arguments and perform a standard query
- int length = uri.getPathSegments().size();
- if (length != 1 && length != 2) {
- throw new IllegalArgumentException("Unknown Uri");
- }
-
- String base = uri.getPathSegments().get(0);
- if (!base.equals(sSuggestions)) {
- throw new IllegalArgumentException("Unknown Uri");
- }
-
- String[] useProjection = null;
- if (projection != null && projection.length > 0) {
- useProjection = new String[projection.length + 1];
- System.arraycopy(projection, 0, useProjection, 0, projection.length);
- useProjection[projection.length] = "_id AS _id";
- }
-
- StringBuilder whereClause = new StringBuilder(256);
- if (length == 2) {
- whereClause.append("(_id = ").append(uri.getPathSegments().get(1)).append(")");
- }
-
- // Tack on the user's selection, if present
- if (selection != null && selection.length() > 0) {
- if (whereClause.length() > 0) {
- whereClause.append(" AND ");
- }
-
- whereClause.append('(');
- whereClause.append(selection);
- whereClause.append(')');
- }
-
- // And perform the generic query as requested
- Cursor c = db.query(base, useProjection, whereClause.toString(),
- selectionArgs, null, null, sortOrder,
- null);
- c.setNotificationUri(getContext().getContentResolver(), uri);
- return c;
- }
-
- /**
- * This method is provided for use by the ContentResolver. Do not override, or directly
- * call from your own code.
- */
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- throw new UnsupportedOperationException("Not implemented");
- }
-
-}
diff --git a/core/java/android/content/ServiceConnection.java b/core/java/android/content/ServiceConnection.java
deleted file mode 100644
index d115ce4..0000000
--- a/core/java/android/content/ServiceConnection.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.os.IBinder;
-
-/**
- * Interface for monitoring the state of an application service. See
- * {@link android.app.Service} and
- * {@link Context#bindService Context.bindService()} for more information.
- * <p>Like many callbacks from the system, the methods on this class are called
- * from the main thread of your process.
- */
-public interface ServiceConnection {
- /**
- * Called when a connection to the Service has been established, with
- * the {@link android.os.IBinder} of the communication channel to the
- * Service.
- *
- * @param name The concrete component name of the service that has
- * been connected.
- *
- * @param service The IBinder of the Service's communication channel,
- * which you can now make calls on.
- */
- public void onServiceConnected(ComponentName name, IBinder service);
-
- /**
- * Called when a connection to the Service has been lost. This typically
- * happens when the process hosting the service has crashed or been killed.
- * This does <em>not</em> remove the ServiceConnection itself -- this
- * binding to the service will remain active, and you will receive a call
- * to {@link #onServiceConnected} when the Service is next running.
- *
- * @param name The concrete component name of the service whose
- * connection has been lost.
- */
- public void onServiceDisconnected(ComponentName name);
-}
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
deleted file mode 100644
index a15e29e..0000000
--- a/core/java/android/content/SharedPreferences.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import java.util.Map;
-
-/**
- * Interface for accessing and modifying preference data returned by {@link
- * Context#getSharedPreferences}. For any particular set of preferences,
- * there is a single instance of this class that all clients share.
- * Modifications to the preferences must go through an {@link Editor} object
- * to ensure the preference values remain in a consistent state and control
- * when they are committed to storage.
- *
- * <p><em>Note: currently this class does not support use across multiple
- * processes. This will be added later.</em>
- *
- * @see Context#getSharedPreferences
- */
-public interface SharedPreferences {
- /**
- * Interface definition for a callback to be invoked when a shared
- * preference is changed.
- */
- public interface OnSharedPreferenceChangeListener {
- /**
- * Called when a shared preference is changed, added, or removed. This
- * may be called even if a preference is set to its existing value.
- *
- * @param sharedPreferences The {@link SharedPreferences} that received
- * the change.
- * @param key The key of the preference that was changed, added, or
- * removed.
- */
- void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key);
- }
-
- /**
- * Interface used for modifying values in a {@link SharedPreferences}
- * object. All changes you make in an editor are batched, and not copied
- * back to the original {@link SharedPreferences} or persistent storage
- * until you call {@link #commit}.
- */
- public interface Editor {
- /**
- * Set a String value in the preferences editor, to be written back once
- * {@link #commit} is called.
- *
- * @param key The name of the preference to modify.
- * @param value The new value for the preference.
- *
- * @return Returns a reference to the same Editor object, so you can
- * chain put calls together.
- */
- Editor putString(String key, String value);
-
- /**
- * Set an int value in the preferences editor, to be written back once
- * {@link #commit} is called.
- *
- * @param key The name of the preference to modify.
- * @param value The new value for the preference.
- *
- * @return Returns a reference to the same Editor object, so you can
- * chain put calls together.
- */
- Editor putInt(String key, int value);
-
- /**
- * Set a long value in the preferences editor, to be written back once
- * {@link #commit} is called.
- *
- * @param key The name of the preference to modify.
- * @param value The new value for the preference.
- *
- * @return Returns a reference to the same Editor object, so you can
- * chain put calls together.
- */
- Editor putLong(String key, long value);
-
- /**
- * Set a float value in the preferences editor, to be written back once
- * {@link #commit} is called.
- *
- * @param key The name of the preference to modify.
- * @param value The new value for the preference.
- *
- * @return Returns a reference to the same Editor object, so you can
- * chain put calls together.
- */
- Editor putFloat(String key, float value);
-
- /**
- * Set a boolean value in the preferences editor, to be written back
- * once {@link #commit} is called.
- *
- * @param key The name of the preference to modify.
- * @param value The new value for the preference.
- *
- * @return Returns a reference to the same Editor object, so you can
- * chain put calls together.
- */
- Editor putBoolean(String key, boolean value);
-
- /**
- * Mark in the editor that a preference value should be removed, which
- * will be done in the actual preferences once {@link #commit} is
- * called.
- *
- * <p>Note that when committing back to the preferences, all removals
- * are done first, regardless of whether you called remove before
- * or after put methods on this editor.
- *
- * @param key The name of the preference to remove.
- *
- * @return Returns a reference to the same Editor object, so you can
- * chain put calls together.
- */
- Editor remove(String key);
-
- /**
- * Mark in the editor to remove <em>all</em> values from the
- * preferences. Once commit is called, the only remaining preferences
- * will be any that you have defined in this editor.
- *
- * <p>Note that when committing back to the preferences, the clear
- * is done first, regardless of whether you called clear before
- * or after put methods on this editor.
- *
- * @return Returns a reference to the same Editor object, so you can
- * chain put calls together.
- */
- Editor clear();
-
- /**
- * Commit your preferences changes back from this Editor to the
- * {@link SharedPreferences} object it is editing. This atomically
- * performs the requested modifications, replacing whatever is currently
- * in the SharedPreferences.
- *
- * <p>Note that when two editors are modifying preferences at the same
- * time, the last one to call commit wins.
- *
- * @return Returns true if the new values were successfully written
- * to persistent storage.
- */
- boolean commit();
- }
-
- /**
- * Retrieve all values from the preferences.
- *
- * @return Returns a map containing a list of pairs key/value representing
- * the preferences.
- *
- * @throws NullPointerException
- */
- Map<String, ?> getAll();
-
- /**
- * Retrieve a String value from the preferences.
- *
- * @param key The name of the preference to retrieve.
- * @param defValue Value to return if this preference does not exist.
- *
- * @return Returns the preference value if it exists, or defValue. Throws
- * ClassCastException if there is a preference with this name that is not
- * a String.
- *
- * @throws ClassCastException
- */
- String getString(String key, String defValue);
-
- /**
- * Retrieve an int value from the preferences.
- *
- * @param key The name of the preference to retrieve.
- * @param defValue Value to return if this preference does not exist.
- *
- * @return Returns the preference value if it exists, or defValue. Throws
- * ClassCastException if there is a preference with this name that is not
- * an int.
- *
- * @throws ClassCastException
- */
- int getInt(String key, int defValue);
-
- /**
- * Retrieve a long value from the preferences.
- *
- * @param key The name of the preference to retrieve.
- * @param defValue Value to return if this preference does not exist.
- *
- * @return Returns the preference value if it exists, or defValue. Throws
- * ClassCastException if there is a preference with this name that is not
- * a long.
- *
- * @throws ClassCastException
- */
- long getLong(String key, long defValue);
-
- /**
- * Retrieve a float value from the preferences.
- *
- * @param key The name of the preference to retrieve.
- * @param defValue Value to return if this preference does not exist.
- *
- * @return Returns the preference value if it exists, or defValue. Throws
- * ClassCastException if there is a preference with this name that is not
- * a float.
- *
- * @throws ClassCastException
- */
- float getFloat(String key, float defValue);
-
- /**
- * Retrieve a boolean value from the preferences.
- *
- * @param key The name of the preference to retrieve.
- * @param defValue Value to return if this preference does not exist.
- *
- * @return Returns the preference value if it exists, or defValue. Throws
- * ClassCastException if there is a preference with this name that is not
- * a boolean.
- *
- * @throws ClassCastException
- */
- boolean getBoolean(String key, boolean defValue);
-
- /**
- * Checks whether the preferences contains a preference.
- *
- * @param key The name of the preference to check.
- * @return Returns true if the preference exists in the preferences,
- * otherwise false.
- */
- boolean contains(String key);
-
- /**
- * Create a new Editor for these preferences, through which you can make
- * modifications to the data in the preferences and atomically commit those
- * changes back to the SharedPreferences object.
- *
- * <p>Note that you <em>must</em> call {@link Editor#commit} to have any
- * changes you perform in the Editor actually show up in the
- * SharedPreferences.
- *
- * @return Returns a new instance of the {@link Editor} interface, allowing
- * you to modify the values in this SharedPreferences object.
- */
- Editor edit();
-
- /**
- * Registers a callback to be invoked when a change happens to a preference.
- *
- * @param listener The callback that will run.
- * @see #unregisterOnSharedPreferenceChangeListener
- */
- void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener);
-
- /**
- * Unregisters a previous callback.
- *
- * @param listener The callback that should be unregistered.
- * @see #registerOnSharedPreferenceChangeListener
- */
- void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener listener);
-}
diff --git a/core/java/android/content/SyncAdapter.java b/core/java/android/content/SyncAdapter.java
deleted file mode 100644
index 7826e50..0000000
--- a/core/java/android/content/SyncAdapter.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.os.Bundle;
-import android.os.RemoteException;
-
-/**
- * @hide
- */
-public abstract class SyncAdapter {
- private static final String TAG = "SyncAdapter";
-
- /** Kernel event log tag. Also listed in data/etc/event-log-tags. */
- public static final int LOG_SYNC_DETAILS = 2743;
-
- class Transport extends ISyncAdapter.Stub {
- public void startSync(ISyncContext syncContext, String account,
- Bundle extras) throws RemoteException {
- SyncAdapter.this.startSync(new SyncContext(syncContext), account, extras);
- }
-
- public void cancelSync() throws RemoteException {
- SyncAdapter.this.cancelSync();
- }
- }
-
- Transport mTransport = new Transport();
-
- /**
- * Get the Transport object. (note this is package private).
- */
- final ISyncAdapter getISyncAdapter()
- {
- return mTransport;
- }
-
- /**
- * Initiate a sync for this account. SyncAdapter-specific parameters may
- * be specified in extras, which is guaranteed to not be null. IPC invocations
- * of this method and cancelSync() are guaranteed to be serialized.
- *
- * @param syncContext the ISyncContext used to indicate the progress of the sync. When
- * the sync is finished (successfully or not) ISyncContext.onFinished() must be called.
- * @param account the account that should be synced
- * @param extras SyncAdapter-specific parameters
- */
- public abstract void startSync(SyncContext syncContext, String account, Bundle extras);
-
- /**
- * Cancel the most recently initiated sync. Due to race conditions, this may arrive
- * after the ISyncContext.onFinished() for that sync was called. IPC invocations
- * of this method and startSync() are guaranteed to be serialized.
- */
- public abstract void cancelSync();
-}
diff --git a/core/java/android/content/SyncContext.java b/core/java/android/content/SyncContext.java
deleted file mode 100644
index f4faa04..0000000
--- a/core/java/android/content/SyncContext.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.os.RemoteException;
-import android.os.SystemClock;
-
-/**
- * @hide
- */
-public class SyncContext {
- private ISyncContext mSyncContext;
- private long mLastHeartbeatSendTime;
-
- private static final long HEARTBEAT_SEND_INTERVAL_IN_MS = 1000;
-
- public SyncContext(ISyncContext syncContextInterface) {
- mSyncContext = syncContextInterface;
- mLastHeartbeatSendTime = 0;
- }
-
- /**
- * Call to update the status text for this sync. This internally invokes
- * {@link #updateHeartbeat}, so it also takes the place of a call to that.
- *
- * @param message the current status message for this sync
- */
- public void setStatusText(String message) {
- updateHeartbeat();
- }
-
- /**
- * Call to indicate that the SyncAdapter is making progress. E.g., if this SyncAdapter
- * downloads or sends records to/from the server, this may be called after each record
- * is downloaded or uploaded.
- */
- public void updateHeartbeat() {
- final long now = SystemClock.elapsedRealtime();
- if (now < mLastHeartbeatSendTime + HEARTBEAT_SEND_INTERVAL_IN_MS) return;
- try {
- mLastHeartbeatSendTime = now;
- mSyncContext.sendHeartbeat();
- } catch (RemoteException e) {
- // this should never happen
- }
- }
-
- public void onFinished(SyncResult result) {
- try {
- mSyncContext.onFinished(result);
- } catch (RemoteException e) {
- // this should never happen
- }
- }
-
- public ISyncContext getISyncContext() {
- return mSyncContext;
- }
-}
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
deleted file mode 100644
index 96470c3..0000000
--- a/core/java/android/content/SyncManager.java
+++ /dev/null
@@ -1,2175 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import com.google.android.collect.Maps;
-
-import com.android.internal.R;
-import com.android.internal.util.ArrayUtils;
-
-import android.accounts.AccountMonitor;
-import android.accounts.AccountMonitorListener;
-import android.app.AlarmManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.HandlerThread;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Parcel;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.preference.Preference;
-import android.preference.PreferenceGroup;
-import android.provider.Sync;
-import android.provider.Settings;
-import android.provider.Sync.History;
-import android.text.TextUtils;
-import android.text.format.DateUtils;
-import android.text.format.Time;
-import android.util.Config;
-import android.util.EventLog;
-import android.util.Log;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.PriorityQueue;
-import java.util.Random;
-import java.util.Observer;
-import java.util.Observable;
-
-/**
- * @hide
- */
-class SyncManager {
- private static final String TAG = "SyncManager";
-
- // used during dumping of the Sync history
- private static final long MILLIS_IN_HOUR = 1000 * 60 * 60;
- private static final long MILLIS_IN_DAY = MILLIS_IN_HOUR * 24;
- private static final long MILLIS_IN_WEEK = MILLIS_IN_DAY * 7;
- private static final long MILLIS_IN_4WEEKS = MILLIS_IN_WEEK * 4;
-
- /** Delay a sync due to local changes this long. In milliseconds */
- private static final long LOCAL_SYNC_DELAY = 30 * 1000; // 30 seconds
-
- /**
- * If a sync takes longer than this and the sync queue is not empty then we will
- * cancel it and add it back to the end of the sync queue. In milliseconds.
- */
- private static final long MAX_TIME_PER_SYNC = 5 * 60 * 1000; // 5 minutes
-
- private static final long SYNC_NOTIFICATION_DELAY = 30 * 1000; // 30 seconds
-
- /**
- * When retrying a sync for the first time use this delay. After that
- * the retry time will double until it reached MAX_SYNC_RETRY_TIME.
- * In milliseconds.
- */
- private static final long INITIAL_SYNC_RETRY_TIME_IN_MS = 30 * 1000; // 30 seconds
-
- /**
- * Default the max sync retry time to this value.
- */
- private static final long DEFAULT_MAX_SYNC_RETRY_TIME_IN_SECONDS = 60 * 60; // one hour
-
- /**
- * An error notification is sent if sync of any of the providers has been failing for this long.
- */
- private static final long ERROR_NOTIFICATION_DELAY_MS = 1000 * 60 * 10; // 10 minutes
-
- private static final String SYNC_WAKE_LOCK = "SyncManagerSyncWakeLock";
- private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarmWakeLock";
-
- private Context mContext;
- private ContentResolver mContentResolver;
-
- private String mStatusText = "";
- private long mHeartbeatTime = 0;
-
- private AccountMonitor mAccountMonitor;
-
- private volatile String[] mAccounts = null;
-
- volatile private PowerManager.WakeLock mSyncWakeLock;
- volatile private PowerManager.WakeLock mHandleAlarmWakeLock;
- volatile private boolean mDataConnectionIsConnected = false;
- volatile private boolean mStorageIsLow = false;
- private Sync.Settings.QueryMap mSyncSettings;
-
- private final NotificationManager mNotificationMgr;
- private AlarmManager mAlarmService = null;
- private HandlerThread mSyncThread;
-
- private volatile IPackageManager mPackageManager;
-
- private final SyncStorageEngine mSyncStorageEngine;
- private final SyncQueue mSyncQueue;
-
- private ActiveSyncContext mActiveSyncContext = null;
-
- // set if the sync error indicator should be reported.
- private boolean mNeedSyncErrorNotification = false;
- // set if the sync active indicator should be reported
- private boolean mNeedSyncActiveNotification = false;
-
- private volatile boolean mSyncPollInitialized;
- private final PendingIntent mSyncAlarmIntent;
- private final PendingIntent mSyncPollAlarmIntent;
-
- private BroadcastReceiver mStorageIntentReceiver =
- new BroadcastReceiver() {
- public void onReceive(Context context, Intent intent) {
- ensureContentResolver();
- String action = intent.getAction();
- if (Intent.ACTION_DEVICE_STORAGE_LOW.equals(action)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Internal storage is low.");
- }
- mStorageIsLow = true;
- cancelActiveSync(null /* no url */);
- } else if (Intent.ACTION_DEVICE_STORAGE_OK.equals(action)) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Internal storage is ok.");
- }
- mStorageIsLow = false;
- sendCheckAlarmsMessage();
- }
- }
- };
-
- private BroadcastReceiver mConnectivityIntentReceiver =
- new BroadcastReceiver() {
- public void onReceive(Context context, Intent intent) {
- NetworkInfo networkInfo =
- intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
- NetworkInfo.State state = (networkInfo == null ? NetworkInfo.State.UNKNOWN :
- networkInfo.getState());
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "received connectivity action. network info: " + networkInfo);
- }
-
- // only pay attention to the CONNECTED and DISCONNECTED states.
- // if connected, we are connected.
- // if disconnected, we may not be connected. in some cases, we may be connected on
- // a different network.
- // e.g., if switching from GPRS to WiFi, we may receive the CONNECTED to WiFi and
- // DISCONNECTED for GPRS in any order. if we receive the CONNECTED first, and then
- // a DISCONNECTED, we want to make sure we set mDataConnectionIsConnected to true
- // since we still have a WiFi connection.
- switch (state) {
- case CONNECTED:
- mDataConnectionIsConnected = true;
- break;
- case DISCONNECTED:
- if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)) {
- mDataConnectionIsConnected = false;
- } else {
- mDataConnectionIsConnected = true;
- }
- break;
- default:
- // ignore the rest of the states -- leave our boolean alone.
- }
- if (mDataConnectionIsConnected) {
- initializeSyncPoll();
- sendCheckAlarmsMessage();
- }
- }
- };
-
- private static final String ACTION_SYNC_ALARM = "android.content.syncmanager.SYNC_ALARM";
- private static final String SYNC_POLL_ALARM = "android.content.syncmanager.SYNC_POLL_ALARM";
- private final SyncHandler mSyncHandler;
-
- private static final String[] SYNC_ACTIVE_PROJECTION = new String[]{
- Sync.Active.ACCOUNT,
- Sync.Active.AUTHORITY,
- Sync.Active.START_TIME,
- };
-
- private static final String[] SYNC_PENDING_PROJECTION = new String[]{
- Sync.Pending.ACCOUNT,
- Sync.Pending.AUTHORITY
- };
-
- private static final int MAX_SYNC_POLL_DELAY_SECONDS = 36 * 60 * 60; // 36 hours
- private static final int MIN_SYNC_POLL_DELAY_SECONDS = 24 * 60 * 60; // 24 hours
-
- private static final String SYNCMANAGER_PREFS_FILENAME = "/data/system/syncmanager.prefs";
-
- public SyncManager(Context context, boolean factoryTest) {
- // Initialize the SyncStorageEngine first, before registering observers
- // and creating threads and so on; it may fail if the disk is full.
- SyncStorageEngine.init(context);
- mSyncStorageEngine = SyncStorageEngine.getSingleton();
- mSyncQueue = new SyncQueue(mSyncStorageEngine);
-
- mContext = context;
-
- mSyncThread = new HandlerThread("SyncHandlerThread", Process.THREAD_PRIORITY_BACKGROUND);
- mSyncThread.start();
- mSyncHandler = new SyncHandler(mSyncThread.getLooper());
-
- mPackageManager = null;
-
- mSyncAlarmIntent = PendingIntent.getBroadcast(
- mContext, 0 /* ignored */, new Intent(ACTION_SYNC_ALARM), 0);
-
- mSyncPollAlarmIntent = PendingIntent.getBroadcast(
- mContext, 0 /* ignored */, new Intent(SYNC_POLL_ALARM), 0);
-
- IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
- context.registerReceiver(mConnectivityIntentReceiver, intentFilter);
-
- intentFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
- intentFilter.addAction(Intent.ACTION_DEVICE_STORAGE_OK);
- context.registerReceiver(mStorageIntentReceiver, intentFilter);
-
- if (!factoryTest) {
- mNotificationMgr = (NotificationManager)
- context.getSystemService(Context.NOTIFICATION_SERVICE);
- context.registerReceiver(new SyncAlarmIntentReceiver(),
- new IntentFilter(ACTION_SYNC_ALARM));
- } else {
- mNotificationMgr = null;
- }
- PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
- mSyncWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, SYNC_WAKE_LOCK);
- mSyncWakeLock.setReferenceCounted(false);
-
- // This WakeLock is used to ensure that we stay awake between the time that we receive
- // a sync alarm notification and when we finish processing it. We need to do this
- // because we don't do the work in the alarm handler, rather we do it in a message
- // handler.
- mHandleAlarmWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
- HANDLE_SYNC_ALARM_WAKE_LOCK);
- mHandleAlarmWakeLock.setReferenceCounted(false);
-
- if (!factoryTest) {
- AccountMonitorListener listener = new AccountMonitorListener() {
- public void onAccountsUpdated(String[] accounts) {
- final boolean hadAccountsAlready = mAccounts != null;
- // copy the accounts into a new array and change mAccounts to point to it
- String[] newAccounts = new String[accounts.length];
- System.arraycopy(accounts, 0, newAccounts, 0, accounts.length);
- mAccounts = newAccounts;
-
- // if a sync is in progress yet it is no longer in the accounts list, cancel it
- ActiveSyncContext activeSyncContext = mActiveSyncContext;
- if (activeSyncContext != null) {
- if (!ArrayUtils.contains(newAccounts,
- activeSyncContext.mSyncOperation.account)) {
- Log.d(TAG, "canceling sync since the account has been removed");
- sendSyncFinishedOrCanceledMessage(activeSyncContext,
- null /* no result since this is a cancel */);
- }
- }
-
- // we must do this since we don't bother scheduling alarms when
- // the accounts are not set yet
- sendCheckAlarmsMessage();
-
- mSyncStorageEngine.doDatabaseCleanup(accounts);
-
- if (hadAccountsAlready && mAccounts.length > 0) {
- // request a sync so that if the password was changed we will retry any sync
- // that failed when it was wrong
- startSync(null /* all providers */, null /* no extras */);
- }
- }
- };
- mAccountMonitor = new AccountMonitor(context, listener);
- }
- }
-
- private synchronized void initializeSyncPoll() {
- if (mSyncPollInitialized) return;
- mSyncPollInitialized = true;
-
- mContext.registerReceiver(new SyncPollAlarmReceiver(), new IntentFilter(SYNC_POLL_ALARM));
-
- // load the next poll time from shared preferences
- long absoluteAlarmTime = readSyncPollTime();
-
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "initializeSyncPoll: absoluteAlarmTime is " + absoluteAlarmTime);
- }
-
- // Convert absoluteAlarmTime to elapsed realtime. If this time was in the past then
- // schedule the poll immediately, if it is too far in the future then cap it at
- // MAX_SYNC_POLL_DELAY_SECONDS.
- long absoluteNow = System.currentTimeMillis();
- long relativeNow = SystemClock.elapsedRealtime();
- long relativeAlarmTime = relativeNow;
- if (absoluteAlarmTime > absoluteNow) {
- long delayInMs = absoluteAlarmTime - absoluteNow;
- final int maxDelayInMs = MAX_SYNC_POLL_DELAY_SECONDS * 1000;
- if (delayInMs > maxDelayInMs) {
- delayInMs = MAX_SYNC_POLL_DELAY_SECONDS * 1000;
- }
- relativeAlarmTime += delayInMs;
- }
-
- // schedule an alarm for the next poll time
- scheduleSyncPollAlarm(relativeAlarmTime);
- }
-
- private void scheduleSyncPollAlarm(long relativeAlarmTime) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "scheduleSyncPollAlarm: relativeAlarmTime is " + relativeAlarmTime
- + ", now is " + SystemClock.elapsedRealtime()
- + ", delay is " + (relativeAlarmTime - SystemClock.elapsedRealtime()));
- }
- ensureAlarmService();
- mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, relativeAlarmTime,
- mSyncPollAlarmIntent);
- }
-
- /**
- * Return a random value v that satisfies minValue <= v < maxValue. The difference between
- * maxValue and minValue must be less than Integer.MAX_VALUE.
- */
- private long jitterize(long minValue, long maxValue) {
- Random random = new Random(SystemClock.elapsedRealtime());
- long spread = maxValue - minValue;
- if (spread > Integer.MAX_VALUE) {
- throw new IllegalArgumentException("the difference between the maxValue and the "
- + "minValue must be less than " + Integer.MAX_VALUE);
- }
- return minValue + random.nextInt((int)spread);
- }
-
- private void handleSyncPollAlarm() {
- // determine the next poll time
- long delayMs = jitterize(MIN_SYNC_POLL_DELAY_SECONDS, MAX_SYNC_POLL_DELAY_SECONDS) * 1000;
- long nextRelativePollTimeMs = SystemClock.elapsedRealtime() + delayMs;
-
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "handleSyncPollAlarm: delay " + delayMs);
-
- // write the absolute time to shared preferences
- writeSyncPollTime(System.currentTimeMillis() + delayMs);
-
- // schedule an alarm for the next poll time
- scheduleSyncPollAlarm(nextRelativePollTimeMs);
-
- // perform a poll
- scheduleSync(null /* sync all syncable providers */, new Bundle(), 0 /* no delay */);
- }
-
- private void writeSyncPollTime(long when) {
- File f = new File(SYNCMANAGER_PREFS_FILENAME);
- DataOutputStream str = null;
- try {
- str = new DataOutputStream(new FileOutputStream(f));
- str.writeLong(when);
- } catch (FileNotFoundException e) {
- Log.w(TAG, "error writing to file " + f, e);
- } catch (IOException e) {
- Log.w(TAG, "error writing to file " + f, e);
- } finally {
- if (str != null) {
- try {
- str.close();
- } catch (IOException e) {
- Log.w(TAG, "error closing file " + f, e);
- }
- }
- }
- }
-
- private long readSyncPollTime() {
- File f = new File(SYNCMANAGER_PREFS_FILENAME);
-
- DataInputStream str = null;
- try {
- str = new DataInputStream(new FileInputStream(f));
- return str.readLong();
- } catch (FileNotFoundException e) {
- writeSyncPollTime(0);
- } catch (IOException e) {
- Log.w(TAG, "error reading file " + f, e);
- } finally {
- if (str != null) {
- try {
- str.close();
- } catch (IOException e) {
- Log.w(TAG, "error closing file " + f, e);
- }
- }
- }
- return 0;
- }
-
- public ActiveSyncContext getActiveSyncContext() {
- return mActiveSyncContext;
- }
-
- private Sync.Settings.QueryMap getSyncSettings() {
- if (mSyncSettings == null) {
- mSyncSettings = new Sync.Settings.QueryMap(mContext.getContentResolver(), true,
- new Handler());
- mSyncSettings.addObserver(new Observer(){
- public void update(Observable o, Object arg) {
- // force the sync loop to run if the settings change
- sendCheckAlarmsMessage();
- }
- });
- }
- return mSyncSettings;
- }
-
- private void ensureContentResolver() {
- if (mContentResolver == null) {
- mContentResolver = mContext.getContentResolver();
- }
- }
-
- private void ensureAlarmService() {
- if (mAlarmService == null) {
- mAlarmService = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
- }
- }
-
- public String getSyncingAccount() {
- ActiveSyncContext activeSyncContext = mActiveSyncContext;
- return (activeSyncContext != null) ? activeSyncContext.mSyncOperation.account : null;
- }
-
- /**
- * Returns whether or not sync is enabled. Sync can be enabled by
- * setting the system property "ro.config.sync" to the value "yes".
- * This is normally done at boot time on builds that support sync.
- * @return true if sync is enabled
- */
- private boolean isSyncEnabled() {
- // Require the precise value "yes" to discourage accidental activation.
- return "yes".equals(SystemProperties.get("ro.config.sync"));
- }
-
- /**
- * Initiate a sync. This can start a sync for all providers
- * (pass null to url, set onlyTicklable to false), only those
- * providers that are marked as ticklable (pass null to url,
- * set onlyTicklable to true), or a specific provider (set url
- * to the content url of the provider).
- *
- * <p>If the ContentResolver.SYNC_EXTRAS_UPLOAD boolean in extras is
- * true then initiate a sync that just checks for local changes to send
- * to the server, otherwise initiate a sync that first gets any
- * changes from the server before sending local changes back to
- * the server.
- *
- * <p>If a specific provider is being synced (the url is non-null)
- * then the extras can contain SyncAdapter-specific information
- * to control what gets synced (e.g. which specific feed to sync).
- *
- * <p>You'll start getting callbacks after this.
- *
- * @param url The Uri of a specific provider to be synced, or
- * null to sync all providers.
- * @param extras a Map of SyncAdapter-specific information to control
-* syncs of a specific provider. Can be null. Is ignored
-* if the url is null.
- * @param delay how many milliseconds in the future to wait before performing this
- * sync. -1 means to make this the next sync to perform.
- */
- public void scheduleSync(Uri url, Bundle extras, long delay) {
- boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
- if (isLoggable) {
- Log.v(TAG, "scheduleSync:"
- + " delay " + delay
- + ", url " + ((url == null) ? "(null)" : url)
- + ", extras " + ((extras == null) ? "(null)" : extras));
- }
-
- if (!isSyncEnabled()) {
- if (isLoggable) {
- Log.v(TAG, "not syncing because sync is disabled");
- }
- setStatusText("Sync is disabled.");
- return;
- }
-
- if (mAccounts == null) setStatusText("The accounts aren't known yet.");
- if (!mDataConnectionIsConnected) setStatusText("No data connection");
- if (mStorageIsLow) setStatusText("Memory low");
-
- if (extras == null) extras = new Bundle();
-
- Boolean expedited = extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, false);
- if (expedited) {
- delay = -1; // this means schedule at the front of the queue
- }
-
- String[] accounts;
- String accountFromExtras = extras.getString(ContentResolver.SYNC_EXTRAS_ACCOUNT);
- if (!TextUtils.isEmpty(accountFromExtras)) {
- accounts = new String[]{accountFromExtras};
- } else {
- // if the accounts aren't configured yet then we can't support an account-less
- // sync request
- accounts = mAccounts;
- if (accounts == null) {
- // not ready yet
- if (isLoggable) {
- Log.v(TAG, "scheduleSync: no accounts yet, dropping");
- }
- return;
- }
- if (accounts.length == 0) {
- if (isLoggable) {
- Log.v(TAG, "scheduleSync: no accounts configured, dropping");
- }
- setStatusText("No accounts are configured.");
- return;
- }
- }
-
- final boolean uploadOnly = extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false);
- final boolean force = extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false);
-
- int source;
- if (uploadOnly) {
- source = Sync.History.SOURCE_LOCAL;
- } else if (force) {
- source = Sync.History.SOURCE_USER;
- } else if (url == null) {
- source = Sync.History.SOURCE_POLL;
- } else {
- // this isn't strictly server, since arbitrary callers can (and do) request
- // a non-forced two-way sync on a specific url
- source = Sync.History.SOURCE_SERVER;
- }
-
- List<String> names = new ArrayList<String>();
- List<ProviderInfo> providers = new ArrayList<ProviderInfo>();
- populateProvidersList(url, names, providers);
-
- final int numProviders = providers.size();
- for (int i = 0; i < numProviders; i++) {
- if (!providers.get(i).isSyncable) continue;
- final String name = names.get(i);
- for (String account : accounts) {
- scheduleSyncOperation(new SyncOperation(account, source, name, extras, delay));
- // TODO: remove this when Calendar supports multiple accounts. Until then
- // pretend that only the first account exists when syncing calendar.
- if ("calendar".equals(name)) {
- break;
- }
- }
- }
- }
-
- private void setStatusText(String message) {
- mStatusText = message;
- }
-
- private void populateProvidersList(Uri url, List<String> names, List<ProviderInfo> providers) {
- try {
- final IPackageManager packageManager = getPackageManager();
- if (url == null) {
- packageManager.querySyncProviders(names, providers);
- } else {
- final String authority = url.getAuthority();
- ProviderInfo info = packageManager.resolveContentProvider(url.getAuthority(), 0);
- if (info != null) {
- // only set this provider if the requested authority is the primary authority
- String[] providerNames = info.authority.split(";");
- if (url.getAuthority().equals(providerNames[0])) {
- names.add(authority);
- providers.add(info);
- }
- }
- }
- } catch (RemoteException ex) {
- // we should really never get this, but if we do then clear the lists, which
- // will result in the dropping of the sync request
- Log.e(TAG, "error trying to get the ProviderInfo for " + url, ex);
- names.clear();
- providers.clear();
- }
- }
-
- public void scheduleLocalSync(Uri url) {
- final Bundle extras = new Bundle();
- extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, true);
- scheduleSync(url, extras, LOCAL_SYNC_DELAY);
- }
-
- private IPackageManager getPackageManager() {
- // Don't bother synchronizing on this. The worst that can happen is that two threads
- // can try to get the package manager at the same time but only one result gets
- // used. Since there is only one package manager in the system this doesn't matter.
- if (mPackageManager == null) {
- IBinder b = ServiceManager.getService("package");
- mPackageManager = IPackageManager.Stub.asInterface(b);
- }
- return mPackageManager;
- }
-
- /**
- * Initiate a sync for this given URL, or pass null for a full sync.
- *
- * <p>You'll start getting callbacks after this.
- *
- * @param url The Uri of a specific provider to be synced, or
- * null to sync all providers.
- * @param extras a Map of SyncAdapter specific information to control
- * syncs of a specific provider. Can be null. Is ignored
- */
- public void startSync(Uri url, Bundle extras) {
- scheduleSync(url, extras, 0 /* no delay */);
- }
-
- public void updateHeartbeatTime() {
- mHeartbeatTime = SystemClock.elapsedRealtime();
- ensureContentResolver();
- mContentResolver.notifyChange(Sync.Active.CONTENT_URI,
- null /* this change wasn't made through an observer */);
- }
-
- private void sendSyncAlarmMessage() {
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_SYNC_ALARM");
- mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_SYNC_ALARM);
- }
-
- private void sendCheckAlarmsMessage() {
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_CHECK_ALARMS");
- mSyncHandler.sendEmptyMessage(SyncHandler.MESSAGE_CHECK_ALARMS);
- }
-
- private void sendSyncFinishedOrCanceledMessage(ActiveSyncContext syncContext,
- SyncResult syncResult) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "sending MESSAGE_SYNC_FINISHED");
- Message msg = mSyncHandler.obtainMessage();
- msg.what = SyncHandler.MESSAGE_SYNC_FINISHED;
- msg.obj = new SyncHandlerMessagePayload(syncContext, syncResult);
- mSyncHandler.sendMessage(msg);
- }
-
- class SyncHandlerMessagePayload {
- public final ActiveSyncContext activeSyncContext;
- public final SyncResult syncResult;
-
- SyncHandlerMessagePayload(ActiveSyncContext syncContext, SyncResult syncResult) {
- this.activeSyncContext = syncContext;
- this.syncResult = syncResult;
- }
- }
-
- class SyncAlarmIntentReceiver extends BroadcastReceiver {
- public void onReceive(Context context, Intent intent) {
- mHandleAlarmWakeLock.acquire();
- sendSyncAlarmMessage();
- }
- }
-
- class SyncPollAlarmReceiver extends BroadcastReceiver {
- public void onReceive(Context context, Intent intent) {
- handleSyncPollAlarm();
- }
- }
-
- private void rescheduleImmediately(SyncOperation syncOperation) {
- SyncOperation rescheduledSyncOperation = new SyncOperation(syncOperation);
- rescheduledSyncOperation.setDelay(0);
- scheduleSyncOperation(rescheduledSyncOperation);
- }
-
- private long rescheduleWithDelay(SyncOperation syncOperation) {
- long newDelayInMs;
-
- if (syncOperation.delay == 0) {
- // The initial delay is the jitterized INITIAL_SYNC_RETRY_TIME_IN_MS
- newDelayInMs = jitterize(INITIAL_SYNC_RETRY_TIME_IN_MS,
- (long)(INITIAL_SYNC_RETRY_TIME_IN_MS * 1.1));
- } else {
- // Subsequent delays are the double of the previous delay
- newDelayInMs = syncOperation.delay * 2;
- }
-
- // Cap the delay
- ensureContentResolver();
- long maxSyncRetryTimeInSeconds = Settings.Gservices.getLong(mContentResolver,
- Settings.Gservices.SYNC_MAX_RETRY_DELAY_IN_SECONDS,
- DEFAULT_MAX_SYNC_RETRY_TIME_IN_SECONDS);
- if (newDelayInMs > maxSyncRetryTimeInSeconds * 1000) {
- newDelayInMs = maxSyncRetryTimeInSeconds * 1000;
- }
-
- SyncOperation rescheduledSyncOperation = new SyncOperation(syncOperation);
- rescheduledSyncOperation.setDelay(newDelayInMs);
- scheduleSyncOperation(rescheduledSyncOperation);
- return newDelayInMs;
- }
-
- /**
- * Cancel the active sync if it matches the uri. The uri corresponds to the one passed
- * in to startSync().
- * @param uri If non-null, the active sync is only canceled if it matches the uri.
- * If null, any active sync is canceled.
- */
- public void cancelActiveSync(Uri uri) {
- ActiveSyncContext activeSyncContext = mActiveSyncContext;
- if (activeSyncContext != null) {
- // if a Uri was specified then only cancel the sync if it matches the the uri
- if (uri != null) {
- if (!uri.getAuthority().equals(activeSyncContext.mSyncOperation.authority)) {
- return;
- }
- }
- sendSyncFinishedOrCanceledMessage(activeSyncContext,
- null /* no result since this is a cancel */);
- }
- }
-
- /**
- * Create and schedule a SyncOperation.
- *
- * @param syncOperation the SyncOperation to schedule
- */
- public void scheduleSyncOperation(SyncOperation syncOperation) {
- // If this operation is expedited and there is a sync in progress then
- // reschedule the current operation and send a cancel for it.
- final boolean expedited = syncOperation.delay < 0;
- final ActiveSyncContext activeSyncContext = mActiveSyncContext;
- if (expedited && activeSyncContext != null) {
- final boolean activeIsExpedited = activeSyncContext.mSyncOperation.delay < 0;
- final boolean hasSameKey =
- activeSyncContext.mSyncOperation.key.equals(syncOperation.key);
- // This request is expedited and there is a sync in progress.
- // Interrupt the current sync only if it is not expedited and if it has a different
- // key than the one we are scheduling.
- if (!activeIsExpedited && !hasSameKey) {
- rescheduleImmediately(activeSyncContext.mSyncOperation);
- sendSyncFinishedOrCanceledMessage(activeSyncContext,
- null /* no result since this is a cancel */);
- }
- }
-
- boolean operationEnqueued;
- synchronized (mSyncQueue) {
- operationEnqueued = mSyncQueue.add(syncOperation);
- }
-
- if (operationEnqueued) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "scheduleSyncOperation: enqueued " + syncOperation);
- }
- sendCheckAlarmsMessage();
- } else {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "scheduleSyncOperation: dropping duplicate sync operation "
- + syncOperation);
- }
- }
- }
-
- /**
- * Remove any scheduled sync operations that match uri. The uri corresponds to the one passed
- * in to startSync().
- * @param uri If non-null, only operations that match the uri are cleared.
- * If null, all operations are cleared.
- */
- public void clearScheduledSyncOperations(Uri uri) {
- synchronized (mSyncQueue) {
- mSyncQueue.clear(null, uri != null ? uri.getAuthority() : null);
- }
- }
-
- void maybeRescheduleSync(SyncResult syncResult, SyncOperation previousSyncOperation) {
- boolean isLoggable = Log.isLoggable(TAG, Log.DEBUG);
- if (isLoggable) {
- Log.d(TAG, "encountered error(s) during the sync: " + syncResult + ", "
- + previousSyncOperation);
- }
-
- // If the operation succeeded to some extent then retry immediately.
- // If this was a two-way sync then retry soft errors with an exponential backoff.
- // If this was an upward sync then schedule a two-way sync immediately.
- // Otherwise do not reschedule.
-
- if (syncResult.madeSomeProgress()) {
- if (isLoggable) {
- Log.d(TAG, "retrying sync operation immediately because "
- + "even though it had an error it achieved some success");
- }
- rescheduleImmediately(previousSyncOperation);
- } else if (previousSyncOperation.extras.getBoolean(
- ContentResolver.SYNC_EXTRAS_UPLOAD, false)) {
- final SyncOperation newSyncOperation = new SyncOperation(previousSyncOperation);
- newSyncOperation.extras.putBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD, false);
- newSyncOperation.setDelay(0);
- if (Config.LOGD) {
- Log.d(TAG, "retrying sync operation as a two-way sync because an upload-only sync "
- + "encountered an error: " + previousSyncOperation);
- }
- scheduleSyncOperation(newSyncOperation);
- } else if (syncResult.hasSoftError()) {
- long delay = rescheduleWithDelay(previousSyncOperation);
- if (delay >= 0) {
- if (isLoggable) {
- Log.d(TAG, "retrying sync operation in " + delay + " ms because "
- + "it encountered a soft error: " + previousSyncOperation);
- }
- }
- } else {
- if (Config.LOGD) {
- Log.d(TAG, "not retrying sync operation because the error is a hard error: "
- + previousSyncOperation);
- }
- }
- }
-
- /**
- * Value type that represents a sync operation.
- */
- static class SyncOperation implements Comparable {
- final String account;
- int syncSource;
- String authority;
- Bundle extras;
- final String key;
- long earliestRunTime;
- long delay;
- Long rowId = null;
-
- SyncOperation(String account, int source, String authority, Bundle extras, long delay) {
- this.account = account;
- this.syncSource = source;
- this.authority = authority;
- this.extras = new Bundle(extras);
- this.setDelay(delay);
- this.key = toKey();
- }
-
- SyncOperation(SyncOperation other) {
- this.account = other.account;
- this.syncSource = other.syncSource;
- this.authority = other.authority;
- this.extras = new Bundle(other.extras);
- this.delay = other.delay;
- this.earliestRunTime = other.earliestRunTime;
- this.key = toKey();
- }
-
- public void setDelay(long delay) {
- this.delay = delay;
- if (delay >= 0) {
- this.earliestRunTime = SystemClock.elapsedRealtime() + delay;
- } else {
- this.earliestRunTime = 0;
- }
- }
-
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("authority: ").append(authority);
- sb.append(" account: ").append(account);
- sb.append(" extras: ");
- extrasToStringBuilder(extras, sb);
- sb.append(" syncSource: ").append(syncSource);
- sb.append(" when: ").append(earliestRunTime);
- sb.append(" delay: ").append(delay);
- sb.append(" key: {").append(key).append("}");
- if (rowId != null) sb.append(" rowId: ").append(rowId);
- return sb.toString();
- }
-
- private String toKey() {
- StringBuilder sb = new StringBuilder();
- sb.append("authority: ").append(authority);
- sb.append(" account: ").append(account);
- sb.append(" extras: ");
- extrasToStringBuilder(extras, sb);
- return sb.toString();
- }
-
- private static void extrasToStringBuilder(Bundle bundle, StringBuilder sb) {
- sb.append("[");
- for (String key : bundle.keySet()) {
- sb.append(key).append("=").append(bundle.get(key)).append(" ");
- }
- sb.append("]");
- }
-
- public int compareTo(Object o) {
- SyncOperation other = (SyncOperation)o;
- if (earliestRunTime == other.earliestRunTime) {
- return 0;
- }
- return (earliestRunTime < other.earliestRunTime) ? -1 : 1;
- }
- }
-
- /**
- * @hide
- */
- class ActiveSyncContext extends ISyncContext.Stub {
- final SyncOperation mSyncOperation;
- final long mHistoryRowId;
- final IContentProvider mContentProvider;
- final ISyncAdapter mSyncAdapter;
- final long mStartTime;
- long mTimeoutStartTime;
-
- public ActiveSyncContext(SyncOperation syncOperation, IContentProvider contentProvider,
- ISyncAdapter syncAdapter, long historyRowId) {
- super();
- mSyncOperation = syncOperation;
- mHistoryRowId = historyRowId;
- mContentProvider = contentProvider;
- mSyncAdapter = syncAdapter;
- mStartTime = SystemClock.elapsedRealtime();
- mTimeoutStartTime = mStartTime;
- }
-
- public void sendHeartbeat() {
- // ignore this call if it corresponds to an old sync session
- if (mActiveSyncContext == this) {
- SyncManager.this.updateHeartbeatTime();
- }
- }
-
- public void onFinished(SyncResult result) {
- // include "this" in the message so that the handler can ignore it if this
- // ActiveSyncContext is no longer the mActiveSyncContext at message handling
- // time
- sendSyncFinishedOrCanceledMessage(this, result);
- }
-
- public void toString(StringBuilder sb) {
- sb.append("startTime ").append(mStartTime)
- .append(", mTimeoutStartTime ").append(mTimeoutStartTime)
- .append(", mHistoryRowId ").append(mHistoryRowId)
- .append(", syncOperation ").append(mSyncOperation);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- toString(sb);
- return sb.toString();
- }
- }
-
- protected void dump(FileDescriptor fd, PrintWriter pw) {
- StringBuilder sb = new StringBuilder();
- dumpSyncState(sb);
- sb.append("\n");
- if (isSyncEnabled()) {
- dumpSyncHistory(sb);
- }
- pw.println(sb.toString());
- }
-
- protected void dumpSyncState(StringBuilder sb) {
- sb.append("sync enabled: ").append(isSyncEnabled()).append("\n");
- sb.append("data connected: ").append(mDataConnectionIsConnected).append("\n");
- sb.append("memory low: ").append(mStorageIsLow).append("\n");
-
- final String[] accounts = mAccounts;
- sb.append("accounts: ");
- if (accounts != null) {
- sb.append(accounts.length);
- } else {
- sb.append("none");
- }
- sb.append("\n");
- final long now = SystemClock.elapsedRealtime();
- sb.append("now: ").append(now).append("\n");
- sb.append("uptime: ").append(DateUtils.formatElapsedTime(now/1000)).append(" (HH:MM:SS)\n");
- sb.append("time spent syncing : ")
- .append(DateUtils.formatElapsedTime(
- mSyncHandler.mSyncTimeTracker.timeSpentSyncing() / 1000))
- .append(" (HH:MM:SS), sync ")
- .append(mSyncHandler.mSyncTimeTracker.mLastWasSyncing ? "" : "not ")
- .append("in progress").append("\n");
- if (mSyncHandler.mAlarmScheduleTime != null) {
- sb.append("next alarm time: ").append(mSyncHandler.mAlarmScheduleTime)
- .append(" (")
- .append(DateUtils.formatElapsedTime((mSyncHandler.mAlarmScheduleTime-now)/1000))
- .append(" (HH:MM:SS) from now)\n");
- } else {
- sb.append("no alarm is scheduled (there had better not be any pending syncs)\n");
- }
-
- sb.append("active sync: ").append(mActiveSyncContext).append("\n");
-
- sb.append("notification info: ");
- mSyncHandler.mSyncNotificationInfo.toString(sb);
- sb.append("\n");
-
- synchronized (mSyncQueue) {
- sb.append("sync queue: ");
- mSyncQueue.dump(sb);
- }
-
- Cursor c = mSyncStorageEngine.query(Sync.Active.CONTENT_URI,
- SYNC_ACTIVE_PROJECTION, null, null, null);
- sb.append("\n");
- try {
- if (c.moveToNext()) {
- final long durationInSeconds = (now - c.getLong(2)) / 1000;
- sb.append("Active sync: ").append(c.getString(0))
- .append(" ").append(c.getString(1))
- .append(", duration is ")
- .append(DateUtils.formatElapsedTime(durationInSeconds)).append(".\n");
- } else {
- sb.append("No sync is in progress.\n");
- }
- } finally {
- c.close();
- }
-
- c = mSyncStorageEngine.query(Sync.Pending.CONTENT_URI,
- SYNC_PENDING_PROJECTION, null, null, "account, authority");
- sb.append("\nPending Syncs\n");
- try {
- if (c.getCount() != 0) {
- dumpSyncPendingHeader(sb);
- while (c.moveToNext()) {
- dumpSyncPendingRow(sb, c);
- }
- dumpSyncPendingFooter(sb);
- } else {
- sb.append("none\n");
- }
- } finally {
- c.close();
- }
-
- String currentAccount = null;
- c = mSyncStorageEngine.query(Sync.Status.CONTENT_URI,
- STATUS_PROJECTION, null, null, "account, authority");
- sb.append("\nSync history by account and authority\n");
- try {
- while (c.moveToNext()) {
- if (!TextUtils.equals(currentAccount, c.getString(0))) {
- if (currentAccount != null) {
- dumpSyncHistoryFooter(sb);
- }
- currentAccount = c.getString(0);
- dumpSyncHistoryHeader(sb, currentAccount);
- }
-
- dumpSyncHistoryRow(sb, c);
- }
- if (c.getCount() > 0) dumpSyncHistoryFooter(sb);
- } finally {
- c.close();
- }
- }
-
- private void dumpSyncHistoryHeader(StringBuilder sb, String account) {
- sb.append(" Account: ").append(account).append("\n");
- sb.append(" ___________________________________________________________________________________________________________________________\n");
- sb.append(" | | num times synced | total | last success | |\n");
- sb.append(" | authority | local | poll | server | user | total | duration | source | time | result if failing |\n");
- }
-
- private static String[] STATUS_PROJECTION = new String[]{
- Sync.Status.ACCOUNT, // 0
- Sync.Status.AUTHORITY, // 1
- Sync.Status.NUM_SYNCS, // 2
- Sync.Status.TOTAL_ELAPSED_TIME, // 3
- Sync.Status.NUM_SOURCE_LOCAL, // 4
- Sync.Status.NUM_SOURCE_POLL, // 5
- Sync.Status.NUM_SOURCE_SERVER, // 6
- Sync.Status.NUM_SOURCE_USER, // 7
- Sync.Status.LAST_SUCCESS_SOURCE, // 8
- Sync.Status.LAST_SUCCESS_TIME, // 9
- Sync.Status.LAST_FAILURE_SOURCE, // 10
- Sync.Status.LAST_FAILURE_TIME, // 11
- Sync.Status.LAST_FAILURE_MESG // 12
- };
-
- private void dumpSyncHistoryRow(StringBuilder sb, Cursor c) {
- boolean hasSuccess = !c.isNull(9);
- boolean hasFailure = !c.isNull(11);
- Time timeSuccess = new Time();
- if (hasSuccess) timeSuccess.set(c.getLong(9));
- Time timeFailure = new Time();
- if (hasFailure) timeFailure.set(c.getLong(11));
- sb.append(String.format(" | %-15s | %5d | %5d | %6d | %5d | %5d | %8s | %7s | %19s | %19s |\n",
- c.getString(1),
- c.getLong(4),
- c.getLong(5),
- c.getLong(6),
- c.getLong(7),
- c.getLong(2),
- DateUtils.formatElapsedTime(c.getLong(3)/1000),
- hasSuccess ? Sync.History.SOURCES[c.getInt(8)] : "",
- hasSuccess ? timeSuccess.format("%Y-%m-%d %H:%M:%S") : "",
- hasFailure ? History.mesgToString(c.getString(12)) : ""));
- }
-
- private void dumpSyncHistoryFooter(StringBuilder sb) {
- sb.append(" |___________________________________________________________________________________________________________________________|\n");
- }
-
- private void dumpSyncPendingHeader(StringBuilder sb) {
- sb.append(" ____________________________________________________\n");
- sb.append(" | account | authority |\n");
- }
-
- private void dumpSyncPendingRow(StringBuilder sb, Cursor c) {
- sb.append(String.format(" | %-30s | %-15s |\n", c.getString(0), c.getString(1)));
- }
-
- private void dumpSyncPendingFooter(StringBuilder sb) {
- sb.append(" |__________________________________________________|\n");
- }
-
- protected void dumpSyncHistory(StringBuilder sb) {
- Cursor c = mSyncStorageEngine.query(Sync.History.CONTENT_URI, null, "event=?",
- new String[]{String.valueOf(Sync.History.EVENT_STOP)},
- Sync.HistoryColumns.EVENT_TIME + " desc");
- try {
- long numSyncsLastHour = 0, durationLastHour = 0;
- long numSyncsLastDay = 0, durationLastDay = 0;
- long numSyncsLastWeek = 0, durationLastWeek = 0;
- long numSyncsLast4Weeks = 0, durationLast4Weeks = 0;
- long numSyncsTotal = 0, durationTotal = 0;
-
- long now = System.currentTimeMillis();
- int indexEventTime = c.getColumnIndexOrThrow(Sync.History.EVENT_TIME);
- int indexElapsedTime = c.getColumnIndexOrThrow(Sync.History.ELAPSED_TIME);
- while (c.moveToNext()) {
- long duration = c.getLong(indexElapsedTime);
- long endTime = c.getLong(indexEventTime) + duration;
- long millisSinceStart = now - endTime;
- numSyncsTotal++;
- durationTotal += duration;
- if (millisSinceStart < MILLIS_IN_HOUR) {
- numSyncsLastHour++;
- durationLastHour += duration;
- }
- if (millisSinceStart < MILLIS_IN_DAY) {
- numSyncsLastDay++;
- durationLastDay += duration;
- }
- if (millisSinceStart < MILLIS_IN_WEEK) {
- numSyncsLastWeek++;
- durationLastWeek += duration;
- }
- if (millisSinceStart < MILLIS_IN_4WEEKS) {
- numSyncsLast4Weeks++;
- durationLast4Weeks += duration;
- }
- }
- dumpSyncIntervalHeader(sb);
- dumpSyncInterval(sb, "hour", MILLIS_IN_HOUR, numSyncsLastHour, durationLastHour);
- dumpSyncInterval(sb, "day", MILLIS_IN_DAY, numSyncsLastDay, durationLastDay);
- dumpSyncInterval(sb, "week", MILLIS_IN_WEEK, numSyncsLastWeek, durationLastWeek);
- dumpSyncInterval(sb, "4 weeks",
- MILLIS_IN_4WEEKS, numSyncsLast4Weeks, durationLast4Weeks);
- dumpSyncInterval(sb, "total", 0, numSyncsTotal, durationTotal);
- dumpSyncIntervalFooter(sb);
- } finally {
- c.close();
- }
- }
-
- private void dumpSyncIntervalHeader(StringBuilder sb) {
- sb.append("Sync Stats\n");
- sb.append(" ___________________________________________________________\n");
- sb.append(" | | | duration in sec | |\n");
- sb.append(" | interval | count | average | total | % of interval |\n");
- }
-
- private void dumpSyncInterval(StringBuilder sb, String label,
- long interval, long numSyncs, long duration) {
- sb.append(String.format(" | %-8s | %6d | %8.1f | %8.1f",
- label, numSyncs, ((float)duration/numSyncs)/1000, (float)duration/1000));
- if (interval > 0) {
- sb.append(String.format(" | %13.2f |\n", ((float)duration/interval)*100.0));
- } else {
- sb.append(String.format(" | %13s |\n", "na"));
- }
- }
-
- private void dumpSyncIntervalFooter(StringBuilder sb) {
- sb.append(" |_________________________________________________________|\n");
- }
-
- /**
- * A helper object to keep track of the time we have spent syncing since the last boot
- */
- private class SyncTimeTracker {
- /** True if a sync was in progress on the most recent call to update() */
- boolean mLastWasSyncing = false;
- /** Used to track when lastWasSyncing was last set */
- long mWhenSyncStarted = 0;
- /** The cumulative time we have spent syncing */
- private long mTimeSpentSyncing;
-
- /** Call to let the tracker know that the sync state may have changed */
- public synchronized void update() {
- final boolean isSyncInProgress = mActiveSyncContext != null;
- if (isSyncInProgress == mLastWasSyncing) return;
- final long now = SystemClock.elapsedRealtime();
- if (isSyncInProgress) {
- mWhenSyncStarted = now;
- } else {
- mTimeSpentSyncing += now - mWhenSyncStarted;
- }
- mLastWasSyncing = isSyncInProgress;
- }
-
- /** Get how long we have been syncing, in ms */
- public synchronized long timeSpentSyncing() {
- if (!mLastWasSyncing) return mTimeSpentSyncing;
-
- final long now = SystemClock.elapsedRealtime();
- return mTimeSpentSyncing + (now - mWhenSyncStarted);
- }
- }
-
- /**
- * Handles SyncOperation Messages that are posted to the associated
- * HandlerThread.
- */
- class SyncHandler extends Handler {
- // Messages that can be sent on mHandler
- private static final int MESSAGE_SYNC_FINISHED = 1;
- private static final int MESSAGE_SYNC_ALARM = 2;
- private static final int MESSAGE_CHECK_ALARMS = 3;
-
- public final SyncNotificationInfo mSyncNotificationInfo = new SyncNotificationInfo();
- private Long mAlarmScheduleTime = null;
- public final SyncTimeTracker mSyncTimeTracker = new SyncTimeTracker();
-
- // used to track if we have installed the error notification so that we don't reinstall
- // it if sync is still failing
- private boolean mErrorNotificationInstalled = false;
-
- /**
- * Used to keep track of whether a sync notification is active and who it is for.
- */
- class SyncNotificationInfo {
- // only valid if isActive is true
- public String account;
-
- // only valid if isActive is true
- public String authority;
-
- // true iff the notification manager has been asked to send the notification
- public boolean isActive = false;
-
- // Set when we transition from not running a sync to running a sync, and cleared on
- // the opposite transition.
- public Long startTime = null;
-
- public void toString(StringBuilder sb) {
- sb.append("account ").append(account)
- .append(", authority ").append(authority)
- .append(", isActive ").append(isActive)
- .append(", startTime ").append(startTime);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- toString(sb);
- return sb.toString();
- }
- }
-
- public SyncHandler(Looper looper) {
- super(looper);
- }
-
- public void handleMessage(Message msg) {
- handleSyncHandlerMessage(msg);
- }
-
- private void handleSyncHandlerMessage(Message msg) {
- try {
- switch (msg.what) {
- case SyncHandler.MESSAGE_SYNC_FINISHED:
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_FINISHED");
- }
- SyncHandlerMessagePayload payload = (SyncHandlerMessagePayload)msg.obj;
- if (mActiveSyncContext != payload.activeSyncContext) {
- if (Config.LOGD) {
- Log.d(TAG, "handleSyncHandlerMessage: sync context doesn't match, "
- + "dropping: mActiveSyncContext " + mActiveSyncContext
- + " != " + payload.activeSyncContext);
- }
- return;
- }
- runSyncFinishedOrCanceled(payload.syncResult);
-
- // since we are no longer syncing, check if it is time to start a new sync
- runStateIdle();
- break;
-
- case SyncHandler.MESSAGE_SYNC_ALARM: {
- boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
- if (isLoggable) {
- Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_SYNC_ALARM");
- }
- mAlarmScheduleTime = null;
- try {
- if (mActiveSyncContext != null) {
- if (isLoggable) {
- Log.v(TAG, "handleSyncHandlerMessage: sync context is active");
- }
- runStateSyncing();
- }
-
- // if the above call to runStateSyncing() resulted in the end of a sync,
- // check if it is time to start a new sync
- if (mActiveSyncContext == null) {
- if (isLoggable) {
- Log.v(TAG, "handleSyncHandlerMessage: "
- + "sync context is not active");
- }
- runStateIdle();
- }
- } finally {
- mHandleAlarmWakeLock.release();
- }
- break;
- }
-
- case SyncHandler.MESSAGE_CHECK_ALARMS:
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "handleSyncHandlerMessage: MESSAGE_CHECK_ALARMS");
- }
- // we do all the work for this case in the finally block
- break;
- }
- } finally {
- final boolean isSyncInProgress = mActiveSyncContext != null;
- if (!isSyncInProgress) {
- mSyncWakeLock.release();
- }
- manageSyncNotification();
- manageErrorNotification();
- manageSyncAlarm();
- mSyncTimeTracker.update();
- }
- }
-
- private void runStateSyncing() {
- // if the sync timeout has been reached then cancel it
-
- ActiveSyncContext activeSyncContext = mActiveSyncContext;
-
- final long now = SystemClock.elapsedRealtime();
- if (now > activeSyncContext.mTimeoutStartTime + MAX_TIME_PER_SYNC) {
- SyncOperation nextSyncOperation;
- synchronized (mSyncQueue) {
- nextSyncOperation = mSyncQueue.head();
- }
- if (nextSyncOperation != null && nextSyncOperation.earliestRunTime <= now) {
- if (Config.LOGD) {
- Log.d(TAG, "canceling and rescheduling sync because it ran too long: "
- + activeSyncContext.mSyncOperation);
- }
- rescheduleImmediately(activeSyncContext.mSyncOperation);
- sendSyncFinishedOrCanceledMessage(activeSyncContext,
- null /* no result since this is a cancel */);
- } else {
- activeSyncContext.mTimeoutStartTime = now + MAX_TIME_PER_SYNC;
- }
- }
-
- // no need to schedule an alarm, as that will be done by our caller.
- }
-
- private void runStateIdle() {
- boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
- if (isLoggable) Log.v(TAG, "runStateIdle");
-
- // If we aren't ready to run (e.g. the data connection is down), get out.
- if (!mDataConnectionIsConnected) {
- if (isLoggable) {
- Log.v(TAG, "runStateIdle: no data connection, skipping");
- }
- setStatusText("No data connection");
- return;
- }
-
- if (mStorageIsLow) {
- if (isLoggable) {
- Log.v(TAG, "runStateIdle: memory low, skipping");
- }
- setStatusText("Memory low");
- return;
- }
-
- // If the accounts aren't known yet then we aren't ready to run. We will be kicked
- // when the account lookup request does complete.
- String[] accounts = mAccounts;
- if (accounts == null) {
- if (isLoggable) {
- Log.v(TAG, "runStateIdle: accounts not known, skipping");
- }
- setStatusText("Accounts not known yet");
- return;
- }
-
- // Otherwise consume SyncOperations from the head of the SyncQueue until one is
- // found that is runnable (not disabled, etc). If that one is ready to run then
- // start it, otherwise just get out.
- SyncOperation syncOperation;
- final Sync.Settings.QueryMap syncSettings = getSyncSettings();
- final ConnectivityManager connManager = (ConnectivityManager)
- mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- final boolean backgroundDataSetting = connManager.getBackgroundDataSetting();
- synchronized (mSyncQueue) {
- while (true) {
- syncOperation = mSyncQueue.head();
- if (syncOperation == null) {
- if (isLoggable) {
- Log.v(TAG, "runStateIdle: no more sync operations, returning");
- }
- return;
- }
-
- // Sync is disabled, drop this operation.
- if (!isSyncEnabled()) {
- if (isLoggable) {
- Log.v(TAG, "runStateIdle: sync disabled, dropping " + syncOperation);
- }
- mSyncQueue.popHead();
- continue;
- }
-
- // skip the sync if it isn't a force and the settings are off for this provider
- final boolean force = syncOperation.extras.getBoolean(
- ContentResolver.SYNC_EXTRAS_FORCE, false);
- if (!force && (!backgroundDataSetting
- || !syncSettings.getListenForNetworkTickles()
- || !syncSettings.getSyncProviderAutomatically(
- syncOperation.authority))) {
- if (isLoggable) {
- Log.v(TAG, "runStateIdle: sync off, dropping " + syncOperation);
- }
- mSyncQueue.popHead();
- continue;
- }
-
- // skip the sync if the account of this operation no longer exists
- if (!ArrayUtils.contains(accounts, syncOperation.account)) {
- mSyncQueue.popHead();
- if (isLoggable) {
- Log.v(TAG, "runStateIdle: account not present, dropping "
- + syncOperation);
- }
- continue;
- }
-
- // go ahead and try to sync this syncOperation
- if (isLoggable) {
- Log.v(TAG, "runStateIdle: found sync candidate: " + syncOperation);
- }
- break;
- }
-
- // If the first SyncOperation isn't ready to run schedule a wakeup and
- // get out.
- final long now = SystemClock.elapsedRealtime();
- if (syncOperation.earliestRunTime > now) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "runStateIdle: the time is " + now + " yet the next "
- + "sync operation is for " + syncOperation.earliestRunTime
- + ": " + syncOperation);
- }
- return;
- }
-
- // We will do this sync. Remove it from the queue and run it outside of the
- // synchronized block.
- if (isLoggable) {
- Log.v(TAG, "runStateIdle: we are going to sync " + syncOperation);
- }
- mSyncQueue.popHead();
- }
-
- String providerName = syncOperation.authority;
- ensureContentResolver();
- IContentProvider contentProvider;
-
- // acquire the provider and update the sync history
- try {
- contentProvider = mContentResolver.acquireProvider(providerName);
- if (contentProvider == null) {
- Log.e(TAG, "Provider " + providerName + " doesn't exist");
- return;
- }
- if (contentProvider.getSyncAdapter() == null) {
- Log.e(TAG, "Provider " + providerName + " isn't syncable, " + contentProvider);
- return;
- }
- } catch (RemoteException remoteExc) {
- Log.e(TAG, "Caught a RemoteException while preparing for sync, rescheduling "
- + syncOperation, remoteExc);
- rescheduleWithDelay(syncOperation);
- return;
- } catch (RuntimeException exc) {
- Log.e(TAG, "Caught a RuntimeException while validating sync of " + providerName,
- exc);
- return;
- }
-
- final long historyRowId = insertStartSyncEvent(syncOperation);
-
- try {
- ISyncAdapter syncAdapter = contentProvider.getSyncAdapter();
- ActiveSyncContext activeSyncContext = new ActiveSyncContext(syncOperation,
- contentProvider, syncAdapter, historyRowId);
- mSyncWakeLock.acquire();
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "starting sync of " + syncOperation);
- }
- syncAdapter.startSync(activeSyncContext, syncOperation.account,
- syncOperation.extras);
- mActiveSyncContext = activeSyncContext;
- mSyncStorageEngine.setActiveSync(mActiveSyncContext);
- } catch (RemoteException remoteExc) {
- if (Config.LOGD) {
- Log.d(TAG, "runStateIdle: caught a RemoteException, rescheduling", remoteExc);
- }
- mActiveSyncContext = null;
- mSyncStorageEngine.setActiveSync(mActiveSyncContext);
- rescheduleWithDelay(syncOperation);
- } catch (RuntimeException exc) {
- mActiveSyncContext = null;
- mSyncStorageEngine.setActiveSync(mActiveSyncContext);
- Log.e(TAG, "Caught a RuntimeException while starting the sync " + syncOperation,
- exc);
- }
-
- // no need to schedule an alarm, as that will be done by our caller.
- }
-
- private void runSyncFinishedOrCanceled(SyncResult syncResult) {
- boolean isLoggable = Log.isLoggable(TAG, Log.VERBOSE);
- if (isLoggable) Log.v(TAG, "runSyncFinishedOrCanceled");
- ActiveSyncContext activeSyncContext = mActiveSyncContext;
- mActiveSyncContext = null;
- mSyncStorageEngine.setActiveSync(mActiveSyncContext);
-
- final SyncOperation syncOperation = activeSyncContext.mSyncOperation;
-
- final long elapsedTime = SystemClock.elapsedRealtime() - activeSyncContext.mStartTime;
-
- String historyMessage;
- int downstreamActivity;
- int upstreamActivity;
- if (syncResult != null) {
- if (isLoggable) {
- Log.v(TAG, "runSyncFinishedOrCanceled: is a finished: operation "
- + syncOperation + ", result " + syncResult);
- }
-
- if (!syncResult.hasError()) {
- if (isLoggable) {
- Log.v(TAG, "finished sync operation " + syncOperation);
- }
- historyMessage = History.MESG_SUCCESS;
- // TODO: set these correctly when the SyncResult is extended to include it
- downstreamActivity = 0;
- upstreamActivity = 0;
- } else {
- maybeRescheduleSync(syncResult, syncOperation);
- if (Config.LOGD) {
- Log.d(TAG, "failed sync operation " + syncOperation);
- }
- historyMessage = Integer.toString(syncResultToErrorNumber(syncResult));
- // TODO: set these correctly when the SyncResult is extended to include it
- downstreamActivity = 0;
- upstreamActivity = 0;
- }
- } else {
- if (isLoggable) {
- Log.v(TAG, "runSyncFinishedOrCanceled: is a cancel: operation "
- + syncOperation);
- }
- try {
- activeSyncContext.mSyncAdapter.cancelSync();
- } catch (RemoteException e) {
- // we don't need to retry this in this case
- }
- historyMessage = History.MESG_CANCELED;
- downstreamActivity = 0;
- upstreamActivity = 0;
- }
-
- stopSyncEvent(activeSyncContext.mHistoryRowId, syncOperation, historyMessage,
- upstreamActivity, downstreamActivity, elapsedTime);
-
- mContentResolver.releaseProvider(activeSyncContext.mContentProvider);
-
- if (syncResult != null && syncResult.tooManyDeletions) {
- installHandleTooManyDeletesNotification(syncOperation.account,
- syncOperation.authority, syncResult.stats.numDeletes);
- } else {
- mNotificationMgr.cancel(
- syncOperation.account.hashCode() ^ syncOperation.authority.hashCode());
- }
-
- if (syncResult != null && syncResult.fullSyncRequested) {
- scheduleSyncOperation(new SyncOperation(syncOperation.account,
- syncOperation.syncSource, syncOperation.authority, new Bundle(), 0));
- }
- // no need to schedule an alarm, as that will be done by our caller.
- }
-
- /**
- * Convert the error-containing SyncResult into the Sync.History error number. Since
- * the SyncResult may indicate multiple errors at once, this method just returns the
- * most "serious" error.
- * @param syncResult the SyncResult from which to read
- * @return the most "serious" error set in the SyncResult
- * @throws IllegalStateException if the SyncResult does not indicate any errors.
- * If SyncResult.error() is true then it is safe to call this.
- */
- private int syncResultToErrorNumber(SyncResult syncResult) {
- if (syncResult.syncAlreadyInProgress) return History.ERROR_SYNC_ALREADY_IN_PROGRESS;
- if (syncResult.stats.numAuthExceptions > 0) return History.ERROR_AUTHENTICATION;
- if (syncResult.stats.numIoExceptions > 0) return History.ERROR_IO;
- if (syncResult.stats.numParseExceptions > 0) return History.ERROR_PARSE;
- if (syncResult.stats.numConflictDetectedExceptions > 0) return History.ERROR_CONFLICT;
- if (syncResult.tooManyDeletions) return History.ERROR_TOO_MANY_DELETIONS;
- if (syncResult.tooManyRetries) return History.ERROR_TOO_MANY_RETRIES;
- if (syncResult.databaseError) return History.ERROR_INTERNAL;
- throw new IllegalStateException("we are not in an error state, " + syncResult);
- }
-
- private void manageSyncNotification() {
- boolean shouldCancel;
- boolean shouldInstall;
-
- if (mActiveSyncContext == null) {
- mSyncNotificationInfo.startTime = null;
-
- // we aren't syncing. if the notification is active then remember that we need
- // to cancel it and then clear out the info
- shouldCancel = mSyncNotificationInfo.isActive;
- shouldInstall = false;
- } else {
- // we are syncing
- final SyncOperation syncOperation = mActiveSyncContext.mSyncOperation;
-
- final long now = SystemClock.elapsedRealtime();
- if (mSyncNotificationInfo.startTime == null) {
- mSyncNotificationInfo.startTime = now;
- }
-
- // cancel the notification if it is up and the authority or account is wrong
- shouldCancel = mSyncNotificationInfo.isActive &&
- (!syncOperation.authority.equals(mSyncNotificationInfo.authority)
- || !syncOperation.account.equals(mSyncNotificationInfo.account));
-
- // there are four cases:
- // - the notification is up and there is no change: do nothing
- // - the notification is up but we should cancel since it is stale:
- // need to install
- // - the notification is not up but it isn't time yet: don't install
- // - the notification is not up and it is time: need to install
-
- if (mSyncNotificationInfo.isActive) {
- shouldInstall = shouldCancel;
- } else {
- final boolean timeToShowNotification =
- now > mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY;
- final boolean syncIsForced = syncOperation.extras
- .getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false);
- shouldInstall = timeToShowNotification || syncIsForced;
- }
- }
-
- if (shouldCancel && !shouldInstall) {
- mNeedSyncActiveNotification = false;
- sendSyncStateIntent();
- mSyncNotificationInfo.isActive = false;
- }
-
- if (shouldInstall) {
- SyncOperation syncOperation = mActiveSyncContext.mSyncOperation;
- mNeedSyncActiveNotification = true;
- sendSyncStateIntent();
- mSyncNotificationInfo.isActive = true;
- mSyncNotificationInfo.account = syncOperation.account;
- mSyncNotificationInfo.authority = syncOperation.authority;
- }
- }
-
- /**
- * Check if there were any long-lasting errors, if so install the error notification,
- * otherwise cancel the error notification.
- */
- private void manageErrorNotification() {
- //
- long when = mSyncStorageEngine.getInitialSyncFailureTime();
- if ((when > 0) && (when + ERROR_NOTIFICATION_DELAY_MS < System.currentTimeMillis())) {
- if (!mErrorNotificationInstalled) {
- mNeedSyncErrorNotification = true;
- sendSyncStateIntent();
- }
- mErrorNotificationInstalled = true;
- } else {
- if (mErrorNotificationInstalled) {
- mNeedSyncErrorNotification = false;
- sendSyncStateIntent();
- }
- mErrorNotificationInstalled = false;
- }
- }
-
- private void manageSyncAlarm() {
- // in each of these cases the sync loop will be kicked, which will cause this
- // method to be called again
- if (!mDataConnectionIsConnected) return;
- if (mAccounts == null) return;
- if (mStorageIsLow) return;
-
- // Compute the alarm fire time:
- // - not syncing: time of the next sync operation
- // - syncing, no notification: time from sync start to notification create time
- // - syncing, with notification: time till timeout of the active sync operation
- Long alarmTime = null;
- ActiveSyncContext activeSyncContext = mActiveSyncContext;
- if (activeSyncContext == null) {
- SyncOperation syncOperation;
- synchronized (mSyncQueue) {
- syncOperation = mSyncQueue.head();
- }
- if (syncOperation != null) {
- alarmTime = syncOperation.earliestRunTime;
- }
- } else {
- final long notificationTime =
- mSyncHandler.mSyncNotificationInfo.startTime + SYNC_NOTIFICATION_DELAY;
- final long timeoutTime =
- mActiveSyncContext.mTimeoutStartTime + MAX_TIME_PER_SYNC;
- if (mSyncHandler.mSyncNotificationInfo.isActive) {
- alarmTime = timeoutTime;
- } else {
- alarmTime = Math.min(notificationTime, timeoutTime);
- }
- }
-
- // adjust the alarmTime so that we will wake up when it is time to
- // install the error notification
- if (!mErrorNotificationInstalled) {
- long when = mSyncStorageEngine.getInitialSyncFailureTime();
- if (when > 0) {
- when += ERROR_NOTIFICATION_DELAY_MS;
- // convert when fron absolute time to elapsed run time
- long delay = when - System.currentTimeMillis();
- when = SystemClock.elapsedRealtime() + delay;
- alarmTime = alarmTime != null ? Math.min(alarmTime, when) : when;
- }
- }
-
- // determine if we need to set or cancel the alarm
- boolean shouldSet = false;
- boolean shouldCancel = false;
- final boolean alarmIsActive = mAlarmScheduleTime != null;
- final boolean needAlarm = alarmTime != null;
- if (needAlarm) {
- if (!alarmIsActive || alarmTime < mAlarmScheduleTime) {
- shouldSet = true;
- }
- } else {
- shouldCancel = alarmIsActive;
- }
-
- // set or cancel the alarm as directed
- ensureAlarmService();
- if (shouldSet) {
- mAlarmScheduleTime = alarmTime;
- mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTime,
- mSyncAlarmIntent);
- } else if (shouldCancel) {
- mAlarmScheduleTime = null;
- mAlarmService.cancel(mSyncAlarmIntent);
- }
- }
-
- private void sendSyncStateIntent() {
- Intent syncStateIntent = new Intent(Intent.ACTION_SYNC_STATE_CHANGED);
- syncStateIntent.putExtra("active", mNeedSyncActiveNotification);
- syncStateIntent.putExtra("failing", mNeedSyncErrorNotification);
- mContext.sendBroadcast(syncStateIntent);
- }
-
- private void installHandleTooManyDeletesNotification(String account, String authority,
- long numDeletes) {
- if (mNotificationMgr == null) return;
- Intent clickIntent = new Intent();
- clickIntent.setClassName("com.android.providers.subscribedfeeds",
- "com.android.settings.SyncActivityTooManyDeletes");
- clickIntent.putExtra("account", account);
- clickIntent.putExtra("provider", authority);
- clickIntent.putExtra("numDeletes", numDeletes);
-
- if (!isActivityAvailable(clickIntent)) {
- Log.w(TAG, "No activity found to handle too many deletes.");
- return;
- }
-
- final PendingIntent pendingIntent = PendingIntent
- .getActivity(mContext, 0, clickIntent, PendingIntent.FLAG_CANCEL_CURRENT);
-
- CharSequence tooManyDeletesDescFormat = mContext.getResources().getText(
- R.string.contentServiceTooManyDeletesNotificationDesc);
-
- String[] authorities = authority.split(";");
- Notification notification =
- new Notification(R.drawable.stat_notify_sync_error,
- mContext.getString(R.string.contentServiceSync),
- System.currentTimeMillis());
- notification.setLatestEventInfo(mContext,
- mContext.getString(R.string.contentServiceSyncNotificationTitle),
- String.format(tooManyDeletesDescFormat.toString(), authorities[0]),
- pendingIntent);
- notification.flags |= Notification.FLAG_ONGOING_EVENT;
- mNotificationMgr.notify(account.hashCode() ^ authority.hashCode(), notification);
- }
-
- /**
- * Checks whether an activity exists on the system image for the given intent.
- *
- * @param intent The intent for an activity.
- * @return Whether or not an activity exists.
- */
- private boolean isActivityAvailable(Intent intent) {
- PackageManager pm = mContext.getPackageManager();
- List<ResolveInfo> list = pm.queryIntentActivities(intent, 0);
- int listSize = list.size();
- for (int i = 0; i < listSize; i++) {
- ResolveInfo resolveInfo = list.get(i);
- if ((resolveInfo.activityInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)
- != 0) {
- return true;
- }
- }
-
- return false;
- }
-
- public long insertStartSyncEvent(SyncOperation syncOperation) {
- final int source = syncOperation.syncSource;
- final long now = System.currentTimeMillis();
-
- EventLog.writeEvent(2720, syncOperation.authority, Sync.History.EVENT_START, source);
-
- return mSyncStorageEngine.insertStartSyncEvent(
- syncOperation.account, syncOperation.authority, now, source);
- }
-
- public void stopSyncEvent(long rowId, SyncOperation syncOperation, String resultMessage,
- int upstreamActivity, int downstreamActivity, long elapsedTime) {
- EventLog.writeEvent(2720, syncOperation.authority, Sync.History.EVENT_STOP, syncOperation.syncSource);
-
- mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime, resultMessage,
- downstreamActivity, upstreamActivity);
- }
- }
-
- static class SyncQueue {
- private SyncStorageEngine mSyncStorageEngine;
- private final String[] COLUMNS = new String[]{
- "_id",
- "authority",
- "account",
- "extras",
- "source"
- };
- private static final int COLUMN_ID = 0;
- private static final int COLUMN_AUTHORITY = 1;
- private static final int COLUMN_ACCOUNT = 2;
- private static final int COLUMN_EXTRAS = 3;
- private static final int COLUMN_SOURCE = 4;
-
- private static final boolean DEBUG_CHECK_DATA_CONSISTENCY = false;
-
- // A priority queue of scheduled SyncOperations that is designed to make it quick
- // to find the next SyncOperation that should be considered for running.
- private final PriorityQueue<SyncOperation> mOpsByWhen = new PriorityQueue<SyncOperation>();
-
- // A Map of SyncOperations operationKey -> SyncOperation that is designed for
- // quick lookup of an enqueued SyncOperation.
- private final HashMap<String, SyncOperation> mOpsByKey = Maps.newHashMap();
-
- public SyncQueue(SyncStorageEngine syncStorageEngine) {
- mSyncStorageEngine = syncStorageEngine;
- Cursor cursor = mSyncStorageEngine.getPendingSyncsCursor(COLUMNS);
- try {
- while (cursor.moveToNext()) {
- add(cursorToOperation(cursor),
- true /* this is being added from the database */);
- }
- } finally {
- cursor.close();
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
- }
- }
-
- public boolean add(SyncOperation operation) {
- return add(new SyncOperation(operation),
- false /* this is not coming from the database */);
- }
-
- private boolean add(SyncOperation operation, boolean fromDatabase) {
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(!fromDatabase);
-
- // If this operation is expedited then set its earliestRunTime to be immediately
- // before the head of the list, or not if none are in the list.
- if (operation.delay < 0) {
- SyncOperation headOperation = head();
- if (headOperation != null) {
- operation.earliestRunTime = Math.min(SystemClock.elapsedRealtime(),
- headOperation.earliestRunTime - 1);
- } else {
- operation.earliestRunTime = SystemClock.elapsedRealtime();
- }
- }
-
- // - if an operation with the same key exists and this one should run earlier,
- // delete the old one and add the new one
- // - if an operation with the same key exists and if this one should run
- // later, ignore it
- // - if no operation exists then add the new one
- final String operationKey = operation.key;
- SyncOperation existingOperation = mOpsByKey.get(operationKey);
-
- // if this operation matches an existing operation that is being retried (delay > 0)
- // and this operation isn't forced, ignore this operation
- if (existingOperation != null && existingOperation.delay > 0) {
- if (!operation.extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false)) {
- return false;
- }
- }
-
- if (existingOperation != null
- && operation.earliestRunTime >= existingOperation.earliestRunTime) {
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(!fromDatabase);
- return false;
- }
-
- if (existingOperation != null) {
- removeByKey(operationKey);
- }
-
- if (operation.rowId == null) {
- byte[] extrasData = null;
- Parcel parcel = Parcel.obtain();
- try {
- operation.extras.writeToParcel(parcel, 0);
- extrasData = parcel.marshall();
- } finally {
- parcel.recycle();
- }
- ContentValues values = new ContentValues();
- values.put("account", operation.account);
- values.put("authority", operation.authority);
- values.put("source", operation.syncSource);
- values.put("extras", extrasData);
- Uri pendingUri = mSyncStorageEngine.insertIntoPending(values);
- operation.rowId = pendingUri == null ? null : ContentUris.parseId(pendingUri);
- if (operation.rowId == null) {
- throw new IllegalStateException("error adding pending sync operation "
- + operation);
- }
- }
-
- if (DEBUG_CHECK_DATA_CONSISTENCY) {
- debugCheckDataStructures(
- false /* don't compare with the DB, since we know
- it is inconsistent right now */ );
- }
- mOpsByKey.put(operationKey, operation);
- mOpsByWhen.add(operation);
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(!fromDatabase);
- return true;
- }
-
- public void removeByKey(String operationKey) {
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
- SyncOperation operationToRemove = mOpsByKey.remove(operationKey);
- if (!mOpsByWhen.remove(operationToRemove)) {
- throw new IllegalStateException(
- "unable to find " + operationToRemove + " in mOpsByWhen");
- }
-
- if (mSyncStorageEngine.deleteFromPending(operationToRemove.rowId) != 1) {
- throw new IllegalStateException("unable to find pending row for "
- + operationToRemove);
- }
-
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
- }
-
- public SyncOperation head() {
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
- return mOpsByWhen.peek();
- }
-
- public void popHead() {
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
- SyncOperation operation = mOpsByWhen.remove();
- if (mOpsByKey.remove(operation.key) == null) {
- throw new IllegalStateException("unable to find " + operation + " in mOpsByKey");
- }
-
- if (mSyncStorageEngine.deleteFromPending(operation.rowId) != 1) {
- throw new IllegalStateException("unable to find pending row for " + operation);
- }
-
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
- }
-
- public void clear(String account, String authority) {
- Iterator<Map.Entry<String, SyncOperation>> entries = mOpsByKey.entrySet().iterator();
- while (entries.hasNext()) {
- Map.Entry<String, SyncOperation> entry = entries.next();
- SyncOperation syncOperation = entry.getValue();
- if (account != null && !syncOperation.account.equals(account)) continue;
- if (authority != null && !syncOperation.authority.equals(authority)) continue;
-
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
- entries.remove();
- if (!mOpsByWhen.remove(syncOperation)) {
- throw new IllegalStateException(
- "unable to find " + syncOperation + " in mOpsByWhen");
- }
-
- if (mSyncStorageEngine.deleteFromPending(syncOperation.rowId) != 1) {
- throw new IllegalStateException("unable to find pending row for "
- + syncOperation);
- }
-
- if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
- }
- }
-
- public void dump(StringBuilder sb) {
- sb.append("SyncQueue: ").append(mOpsByWhen.size()).append(" operation(s)\n");
- for (SyncOperation operation : mOpsByWhen) {
- sb.append(operation).append("\n");
- }
- }
-
- private void debugCheckDataStructures(boolean checkDatabase) {
- if (mOpsByKey.size() != mOpsByWhen.size()) {
- throw new IllegalStateException("size mismatch: "
- + mOpsByKey .size() + " != " + mOpsByWhen.size());
- }
- for (SyncOperation operation : mOpsByWhen) {
- if (!mOpsByKey.containsKey(operation.key)) {
- throw new IllegalStateException(
- "operation " + operation + " is in mOpsByWhen but not mOpsByKey");
- }
- }
- for (Map.Entry<String, SyncOperation> entry : mOpsByKey.entrySet()) {
- final SyncOperation operation = entry.getValue();
- final String key = entry.getKey();
- if (!key.equals(operation.key)) {
- throw new IllegalStateException(
- "operation " + operation + " in mOpsByKey doesn't match key " + key);
- }
- if (!mOpsByWhen.contains(operation)) {
- throw new IllegalStateException(
- "operation " + operation + " is in mOpsByKey but not mOpsByWhen");
- }
- }
-
- if (checkDatabase) {
- // check that the DB contains the same rows as the in-memory data structures
- Cursor cursor = mSyncStorageEngine.getPendingSyncsCursor(COLUMNS);
- try {
- if (mOpsByKey.size() != cursor.getCount()) {
- StringBuilder sb = new StringBuilder();
- DatabaseUtils.dumpCursor(cursor, sb);
- sb.append("\n");
- dump(sb);
- throw new IllegalStateException("DB size mismatch: "
- + mOpsByKey .size() + " != " + cursor.getCount() + "\n"
- + sb.toString());
- }
- } finally {
- cursor.close();
- }
- }
- }
-
- private SyncOperation cursorToOperation(Cursor cursor) {
- byte[] extrasData = cursor.getBlob(COLUMN_EXTRAS);
- Bundle extras;
- Parcel parcel = Parcel.obtain();
- try {
- parcel.unmarshall(extrasData, 0, extrasData.length);
- parcel.setDataPosition(0);
- extras = parcel.readBundle();
- } catch (RuntimeException e) {
- // A RuntimeException is thrown if we were unable to parse the parcel.
- // Create an empty parcel in this case.
- extras = new Bundle();
- } finally {
- parcel.recycle();
- }
-
- SyncOperation syncOperation = new SyncOperation(
- cursor.getString(COLUMN_ACCOUNT),
- cursor.getInt(COLUMN_SOURCE),
- cursor.getString(COLUMN_AUTHORITY),
- extras,
- 0 /* delay */);
- syncOperation.rowId = cursor.getLong(COLUMN_ID);
- return syncOperation;
- }
- }
-}
diff --git a/core/java/android/content/SyncProvider.java b/core/java/android/content/SyncProvider.java
deleted file mode 100644
index 6ddd046..0000000
--- a/core/java/android/content/SyncProvider.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2007 The Android Open Source Project
-package android.content;
-
-import android.database.Cursor;
-import android.net.Uri;
-
-/**
- * ContentProvider that tracks the sync data and overall sync
- * history on the device.
- *
- * @hide
- */
-public class SyncProvider extends ContentProvider {
- public SyncProvider() {
- }
-
- private SyncStorageEngine mSyncStorageEngine;
-
- @Override
- public boolean onCreate() {
- mSyncStorageEngine = SyncStorageEngine.getSingleton();
- return true;
- }
-
- @Override
- public Cursor query(Uri url, String[] projectionIn,
- String selection, String[] selectionArgs, String sort) {
- return mSyncStorageEngine.query(url, projectionIn, selection, selectionArgs, sort);
- }
-
- @Override
- public Uri insert(Uri url, ContentValues initialValues) {
- return mSyncStorageEngine.insert(true /* the caller is the provider */,
- url, initialValues);
- }
-
- @Override
- public int delete(Uri url, String where, String[] whereArgs) {
- return mSyncStorageEngine.delete(true /* the caller is the provider */,
- url, where, whereArgs);
- }
-
- @Override
- public int update(Uri url, ContentValues initialValues, String where, String[] whereArgs) {
- return mSyncStorageEngine.update(true /* the caller is the provider */,
- url, initialValues, where, whereArgs);
- }
-
- @Override
- public String getType(Uri url) {
- return mSyncStorageEngine.getType(url);
- }
-}
diff --git a/core/java/android/content/SyncResult.aidl b/core/java/android/content/SyncResult.aidl
deleted file mode 100644
index 061b81c..0000000
--- a/core/java/android/content/SyncResult.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-parcelable SyncResult;
diff --git a/core/java/android/content/SyncResult.java b/core/java/android/content/SyncResult.java
deleted file mode 100644
index f3260f3..0000000
--- a/core/java/android/content/SyncResult.java
+++ /dev/null
@@ -1,178 +0,0 @@
-package android.content;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * This class is used to store information about the result of a sync
- *
- * @hide
- */
-public final class SyncResult implements Parcelable {
- public final boolean syncAlreadyInProgress;
- public boolean tooManyDeletions;
- public boolean tooManyRetries;
- public boolean databaseError;
- public boolean fullSyncRequested;
- public boolean partialSyncUnavailable;
- public boolean moreRecordsToGet;
- public final SyncStats stats;
- public static final SyncResult ALREADY_IN_PROGRESS;
-
- static {
- ALREADY_IN_PROGRESS = new SyncResult(true);
- }
-
- public SyncResult() {
- this(false);
- }
-
- private SyncResult(boolean syncAlreadyInProgress) {
- this.syncAlreadyInProgress = syncAlreadyInProgress;
- this.tooManyDeletions = false;
- this.tooManyRetries = false;
- this.fullSyncRequested = false;
- this.partialSyncUnavailable = false;
- this.moreRecordsToGet = false;
- this.stats = new SyncStats();
- }
-
- private SyncResult(Parcel parcel) {
- syncAlreadyInProgress = parcel.readInt() != 0;
- tooManyDeletions = parcel.readInt() != 0;
- tooManyRetries = parcel.readInt() != 0;
- databaseError = parcel.readInt() != 0;
- fullSyncRequested = parcel.readInt() != 0;
- partialSyncUnavailable = parcel.readInt() != 0;
- moreRecordsToGet = parcel.readInt() != 0;
- stats = new SyncStats(parcel);
- }
-
- public boolean hasHardError() {
- return stats.numParseExceptions > 0
- || stats.numConflictDetectedExceptions > 0
- || stats.numAuthExceptions > 0
- || tooManyDeletions
- || tooManyRetries
- || databaseError;
- }
-
- public boolean hasSoftError() {
- return syncAlreadyInProgress || stats.numIoExceptions > 0;
- }
-
- public boolean hasError() {
- return hasSoftError() || hasHardError();
- }
-
- public boolean madeSomeProgress() {
- return ((stats.numDeletes > 0) && !tooManyDeletions)
- || stats.numInserts > 0
- || stats.numUpdates > 0;
- }
-
- public void clear() {
- if (syncAlreadyInProgress) {
- throw new UnsupportedOperationException(
- "you are not allowed to clear the ALREADY_IN_PROGRESS SyncStats");
- }
- tooManyDeletions = false;
- tooManyRetries = false;
- databaseError = false;
- fullSyncRequested = false;
- partialSyncUnavailable = false;
- moreRecordsToGet = false;
- stats.clear();
- }
-
- public static final Creator<SyncResult> CREATOR = new Creator<SyncResult>() {
- public SyncResult createFromParcel(Parcel in) {
- return new SyncResult(in);
- }
-
- public SyncResult[] newArray(int size) {
- return new SyncResult[size];
- }
- };
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeInt(syncAlreadyInProgress ? 1 : 0);
- parcel.writeInt(tooManyDeletions ? 1 : 0);
- parcel.writeInt(tooManyRetries ? 1 : 0);
- parcel.writeInt(databaseError ? 1 : 0);
- parcel.writeInt(fullSyncRequested ? 1 : 0);
- parcel.writeInt(partialSyncUnavailable ? 1 : 0);
- parcel.writeInt(moreRecordsToGet ? 1 : 0);
- stats.writeToParcel(parcel, flags);
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(" syncAlreadyInProgress: ").append(syncAlreadyInProgress);
- sb.append(" tooManyDeletions: ").append(tooManyDeletions);
- sb.append(" tooManyRetries: ").append(tooManyRetries);
- sb.append(" databaseError: ").append(databaseError);
- sb.append(" fullSyncRequested: ").append(fullSyncRequested);
- sb.append(" partialSyncUnavailable: ").append(partialSyncUnavailable);
- sb.append(" moreRecordsToGet: ").append(moreRecordsToGet);
- sb.append(" stats: ").append(stats);
- return sb.toString();
- }
-
- /**
- * Generates a debugging string indicating the status.
- * The string consist of a sequence of code letter followed by the count.
- * Code letters are f - fullSyncRequested, r - partialSyncUnavailable,
- * X - hardError, e - numParseExceptions, c - numConflictDetectedExceptions,
- * a - numAuthExceptions, D - tooManyDeletions, R - tooManyRetries,
- * b - databaseError, x - softError, l - syncAlreadyInProgress,
- * I - numIoExceptions
- * @return debugging string.
- */
- public String toDebugString() {
- StringBuffer sb = new StringBuffer();
-
- if (fullSyncRequested) {
- sb.append("f1");
- }
- if (partialSyncUnavailable) {
- sb.append("r1");
- }
- if (hasHardError()) {
- sb.append("X1");
- }
- if (stats.numParseExceptions > 0) {
- sb.append("e").append(stats.numParseExceptions);
- }
- if (stats.numConflictDetectedExceptions > 0) {
- sb.append("c").append(stats.numConflictDetectedExceptions);
- }
- if (stats.numAuthExceptions > 0) {
- sb.append("a").append(stats.numAuthExceptions);
- }
- if (tooManyDeletions) {
- sb.append("D1");
- }
- if (tooManyRetries) {
- sb.append("R1");
- }
- if (databaseError) {
- sb.append("b1");
- }
- if (hasSoftError()) {
- sb.append("x1");
- }
- if (syncAlreadyInProgress) {
- sb.append("l1");
- }
- if (stats.numIoExceptions > 0) {
- sb.append("I").append(stats.numIoExceptions);
- }
- return sb.toString();
- }
-}
diff --git a/core/java/android/content/SyncStateContentProviderHelper.java b/core/java/android/content/SyncStateContentProviderHelper.java
deleted file mode 100644
index f503e6f..0000000
--- a/core/java/android/content/SyncStateContentProviderHelper.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import com.android.internal.util.ArrayUtils;
-
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-
-/**
- * Extends the schema of a ContentProvider to include the _sync_state table
- * and implements query/insert/update/delete to access that table using the
- * authority "syncstate". This can be used to store the sync state for a
- * set of accounts.
- *
- * @hide
- */
-public class SyncStateContentProviderHelper {
- final SQLiteOpenHelper mOpenHelper;
-
- private static final String SYNC_STATE_AUTHORITY = "syncstate";
- private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-
- private static final int STATE = 0;
-
- private static final Uri CONTENT_URI =
- Uri.parse("content://" + SYNC_STATE_AUTHORITY + "/state");
-
- private static final String ACCOUNT_WHERE = "_sync_account = ?";
-
- private final Provider mInternalProviderInterface;
-
- private static final String SYNC_STATE_TABLE = "_sync_state";
- private static long DB_VERSION = 2;
-
- private static final String[] ACCOUNT_PROJECTION = new String[]{"_sync_account"};
-
- static {
- sURIMatcher.addURI(SYNC_STATE_AUTHORITY, "state", STATE);
- }
-
- public SyncStateContentProviderHelper(SQLiteOpenHelper openHelper) {
- mOpenHelper = openHelper;
- mInternalProviderInterface = new Provider();
- }
-
- public ContentProvider asContentProvider() {
- return mInternalProviderInterface;
- }
-
- public void createDatabase(SQLiteDatabase db) {
- db.execSQL("DROP TABLE IF EXISTS _sync_state");
- db.execSQL("CREATE TABLE _sync_state (" +
- "_id INTEGER PRIMARY KEY," +
- "_sync_account TEXT," +
- "data TEXT," +
- "UNIQUE(_sync_account)" +
- ");");
-
- db.execSQL("DROP TABLE IF EXISTS _sync_state_metadata");
- db.execSQL("CREATE TABLE _sync_state_metadata (" +
- "version INTEGER" +
- ");");
- ContentValues values = new ContentValues();
- values.put("version", DB_VERSION);
- db.insert("_sync_state_metadata", "version", values);
- }
-
- protected void onDatabaseOpened(SQLiteDatabase db) {
- long version = DatabaseUtils.longForQuery(db,
- "select version from _sync_state_metadata", null);
- if (version != DB_VERSION) {
- createDatabase(db);
- }
- }
-
- class Provider extends ContentProvider {
- public boolean onCreate() {
- throw new UnsupportedOperationException("not implemented");
- }
-
- public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- int match = sURIMatcher.match(url);
- switch (match) {
- case STATE:
- return db.query(SYNC_STATE_TABLE, projection, selection, selectionArgs,
- null, null, sortOrder);
- default:
- throw new UnsupportedOperationException("Cannot query URL: " + url);
- }
- }
-
- public String getType(Uri uri) {
- throw new UnsupportedOperationException("not implemented");
- }
-
- public Uri insert(Uri url, ContentValues values) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- int match = sURIMatcher.match(url);
- switch (match) {
- case STATE: {
- long id = db.insert(SYNC_STATE_TABLE, "feed", values);
- return CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).build();
- }
- default:
- throw new UnsupportedOperationException("Cannot insert into URL: " + url);
- }
- }
-
- public int delete(Uri url, String userWhere, String[] whereArgs) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- switch (sURIMatcher.match(url)) {
- case STATE:
- return db.delete(SYNC_STATE_TABLE, userWhere, whereArgs);
- default:
- throw new IllegalArgumentException("Unknown URL " + url);
- }
-
- }
-
- public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- switch (sURIMatcher.match(url)) {
- case STATE:
- return db.update(SYNC_STATE_TABLE, values, selection, selectionArgs);
- default:
- throw new UnsupportedOperationException("Cannot update URL: " + url);
- }
-
- }
- }
-
- /**
- * Check if the url matches content that this ContentProvider manages.
- * @param url the Uri to check
- * @return true if this ContentProvider can handle that Uri.
- */
- public boolean matches(Uri url) {
- return (SYNC_STATE_AUTHORITY.equals(url.getAuthority()));
- }
-
- /**
- * Replaces the contents of the _sync_state table in the destination ContentProvider
- * with the row that matches account, if any, in the source ContentProvider.
- * <p>
- * The ContentProviders must expose the _sync_state table as URI content://syncstate/state.
- * @param dbSrc the database to read from
- * @param dbDest the database to write to
- * @param account the account of the row that should be copied over.
- */
- public void copySyncState(SQLiteDatabase dbSrc, SQLiteDatabase dbDest,
- String account) {
- final String[] whereArgs = new String[]{account};
- Cursor c = dbSrc.query(SYNC_STATE_TABLE, new String[]{"_sync_account", "data"},
- ACCOUNT_WHERE, whereArgs, null, null, null);
- try {
- if (c.moveToNext()) {
- ContentValues values = new ContentValues();
- values.put("_sync_account", c.getString(0));
- values.put("data", c.getBlob(1));
- dbDest.replace(SYNC_STATE_TABLE, "_sync_account", values);
- }
- } finally {
- c.close();
- }
- }
-
- public void onAccountsChanged(String[] accounts) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- Cursor c = db.query(SYNC_STATE_TABLE, ACCOUNT_PROJECTION, null, null, null, null, null);
- try {
- while (c.moveToNext()) {
- final String account = c.getString(0);
- if (!ArrayUtils.contains(accounts, account)) {
- db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE, new String[]{account});
- }
- }
- } finally {
- c.close();
- }
- }
-
- public void discardSyncData(SQLiteDatabase db, String account) {
- if (account != null) {
- db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE, new String[]{account});
- } else {
- db.delete(SYNC_STATE_TABLE, null, null);
- }
- }
-
- /**
- * Retrieves the SyncData bytes for the given account. The byte array returned may be null.
- */
- public byte[] readSyncDataBytes(SQLiteDatabase db, String account) {
- Cursor c = db.query(SYNC_STATE_TABLE, null, ACCOUNT_WHERE,
- new String[]{account}, null, null, null);
- try {
- if (c.moveToFirst()) {
- return c.getBlob(c.getColumnIndexOrThrow("data"));
- }
- } finally {
- c.close();
- }
- return null;
- }
-
- /**
- * Sets the SyncData bytes for the given account. The bytes array may be null.
- */
- public void writeSyncDataBytes(SQLiteDatabase db, String account, byte[] data) {
- ContentValues values = new ContentValues();
- values.put("data", data);
- db.update(SYNC_STATE_TABLE, values, ACCOUNT_WHERE, new String[]{account});
- }
-}
diff --git a/core/java/android/content/SyncStats.aidl b/core/java/android/content/SyncStats.aidl
deleted file mode 100644
index dff0ebf..0000000
--- a/core/java/android/content/SyncStats.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-parcelable SyncStats;
diff --git a/core/java/android/content/SyncStats.java b/core/java/android/content/SyncStats.java
deleted file mode 100644
index b561b05..0000000
--- a/core/java/android/content/SyncStats.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.os.Parcelable;
-import android.os.Parcel;
-
-/**
- * @hide
- */
-public class SyncStats implements Parcelable {
- public long numAuthExceptions;
- public long numIoExceptions;
- public long numParseExceptions;
- public long numConflictDetectedExceptions;
- public long numInserts;
- public long numUpdates;
- public long numDeletes;
- public long numEntries;
- public long numSkippedEntries;
-
- public SyncStats() {
- numAuthExceptions = 0;
- numIoExceptions = 0;
- numParseExceptions = 0;
- numConflictDetectedExceptions = 0;
- numInserts = 0;
- numUpdates = 0;
- numDeletes = 0;
- numEntries = 0;
- numSkippedEntries = 0;
- }
-
- public SyncStats(Parcel in) {
- numAuthExceptions = in.readLong();
- numIoExceptions = in.readLong();
- numParseExceptions = in.readLong();
- numConflictDetectedExceptions = in.readLong();
- numInserts = in.readLong();
- numUpdates = in.readLong();
- numDeletes = in.readLong();
- numEntries = in.readLong();
- numSkippedEntries = in.readLong();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append("numAuthExceptions: ").append(numAuthExceptions);
- sb.append(" numIoExceptions: ").append(numIoExceptions);
- sb.append(" numParseExceptions: ").append(numParseExceptions);
- sb.append(" numConflictDetectedExceptions: ").append(numConflictDetectedExceptions);
- sb.append(" numInserts: ").append(numInserts);
- sb.append(" numUpdates: ").append(numUpdates);
- sb.append(" numDeletes: ").append(numDeletes);
- sb.append(" numEntries: ").append(numEntries);
- sb.append(" numSkippedEntries: ").append(numSkippedEntries);
- return sb.toString();
- }
-
- public void clear() {
- numAuthExceptions = 0;
- numIoExceptions = 0;
- numParseExceptions = 0;
- numConflictDetectedExceptions = 0;
- numInserts = 0;
- numUpdates = 0;
- numDeletes = 0;
- numEntries = 0;
- numSkippedEntries = 0;
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeLong(numAuthExceptions);
- dest.writeLong(numIoExceptions);
- dest.writeLong(numParseExceptions);
- dest.writeLong(numConflictDetectedExceptions);
- dest.writeLong(numInserts);
- dest.writeLong(numUpdates);
- dest.writeLong(numDeletes);
- dest.writeLong(numEntries);
- dest.writeLong(numSkippedEntries);
- }
-
- public static final Creator<SyncStats> CREATOR = new Creator<SyncStats>() {
- public SyncStats createFromParcel(Parcel in) {
- return new SyncStats(in);
- }
-
- public SyncStats[] newArray(int size) {
- return new SyncStats[size];
- }
- };
-}
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
deleted file mode 100644
index 282f6e7..0000000
--- a/core/java/android/content/SyncStorageEngine.java
+++ /dev/null
@@ -1,758 +0,0 @@
-package android.content;
-
-import android.Manifest;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.provider.Sync;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-
-/**
- * ContentProvider that tracks the sync data and overall sync
- * history on the device.
- *
- * @hide
- */
-public class SyncStorageEngine {
- private static final String TAG = "SyncManager";
-
- private static final String DATABASE_NAME = "syncmanager.db";
- private static final int DATABASE_VERSION = 10;
-
- private static final int STATS = 1;
- private static final int STATS_ID = 2;
- private static final int HISTORY = 3;
- private static final int HISTORY_ID = 4;
- private static final int SETTINGS = 5;
- private static final int PENDING = 7;
- private static final int ACTIVE = 8;
- private static final int STATUS = 9;
-
- private static final UriMatcher sURLMatcher =
- new UriMatcher(UriMatcher.NO_MATCH);
-
- private static final HashMap<String,String> HISTORY_PROJECTION_MAP;
- private static final HashMap<String,String> PENDING_PROJECTION_MAP;
- private static final HashMap<String,String> ACTIVE_PROJECTION_MAP;
- private static final HashMap<String,String> STATUS_PROJECTION_MAP;
-
- private final Context mContext;
- private final SQLiteOpenHelper mOpenHelper;
- private static SyncStorageEngine sSyncStorageEngine = null;
-
- static {
- sURLMatcher.addURI("sync", "stats", STATS);
- sURLMatcher.addURI("sync", "stats/#", STATS_ID);
- sURLMatcher.addURI("sync", "history", HISTORY);
- sURLMatcher.addURI("sync", "history/#", HISTORY_ID);
- sURLMatcher.addURI("sync", "settings", SETTINGS);
- sURLMatcher.addURI("sync", "status", STATUS);
- sURLMatcher.addURI("sync", "active", ACTIVE);
- sURLMatcher.addURI("sync", "pending", PENDING);
-
- HashMap<String,String> map;
- PENDING_PROJECTION_MAP = map = new HashMap<String,String>();
- map.put(Sync.History._ID, Sync.History._ID);
- map.put(Sync.History.ACCOUNT, Sync.History.ACCOUNT);
- map.put(Sync.History.AUTHORITY, Sync.History.AUTHORITY);
-
- ACTIVE_PROJECTION_MAP = map = new HashMap<String,String>();
- map.put(Sync.History._ID, Sync.History._ID);
- map.put(Sync.History.ACCOUNT, Sync.History.ACCOUNT);
- map.put(Sync.History.AUTHORITY, Sync.History.AUTHORITY);
- map.put("startTime", "startTime");
-
- HISTORY_PROJECTION_MAP = map = new HashMap<String,String>();
- map.put(Sync.History._ID, "history._id as _id");
- map.put(Sync.History.ACCOUNT, "stats.account as account");
- map.put(Sync.History.AUTHORITY, "stats.authority as authority");
- map.put(Sync.History.EVENT, Sync.History.EVENT);
- map.put(Sync.History.EVENT_TIME, Sync.History.EVENT_TIME);
- map.put(Sync.History.ELAPSED_TIME, Sync.History.ELAPSED_TIME);
- map.put(Sync.History.SOURCE, Sync.History.SOURCE);
- map.put(Sync.History.UPSTREAM_ACTIVITY, Sync.History.UPSTREAM_ACTIVITY);
- map.put(Sync.History.DOWNSTREAM_ACTIVITY, Sync.History.DOWNSTREAM_ACTIVITY);
- map.put(Sync.History.MESG, Sync.History.MESG);
-
- STATUS_PROJECTION_MAP = map = new HashMap<String,String>();
- map.put(Sync.Status._ID, "status._id as _id");
- map.put(Sync.Status.ACCOUNT, "stats.account as account");
- map.put(Sync.Status.AUTHORITY, "stats.authority as authority");
- map.put(Sync.Status.TOTAL_ELAPSED_TIME, Sync.Status.TOTAL_ELAPSED_TIME);
- map.put(Sync.Status.NUM_SYNCS, Sync.Status.NUM_SYNCS);
- map.put(Sync.Status.NUM_SOURCE_LOCAL, Sync.Status.NUM_SOURCE_LOCAL);
- map.put(Sync.Status.NUM_SOURCE_POLL, Sync.Status.NUM_SOURCE_POLL);
- map.put(Sync.Status.NUM_SOURCE_SERVER, Sync.Status.NUM_SOURCE_SERVER);
- map.put(Sync.Status.NUM_SOURCE_USER, Sync.Status.NUM_SOURCE_USER);
- map.put(Sync.Status.LAST_SUCCESS_SOURCE, Sync.Status.LAST_SUCCESS_SOURCE);
- map.put(Sync.Status.LAST_SUCCESS_TIME, Sync.Status.LAST_SUCCESS_TIME);
- map.put(Sync.Status.LAST_FAILURE_SOURCE, Sync.Status.LAST_FAILURE_SOURCE);
- map.put(Sync.Status.LAST_FAILURE_TIME, Sync.Status.LAST_FAILURE_TIME);
- map.put(Sync.Status.LAST_FAILURE_MESG, Sync.Status.LAST_FAILURE_MESG);
- map.put(Sync.Status.PENDING, Sync.Status.PENDING);
- }
-
- private static final String[] STATS_ACCOUNT_PROJECTION =
- new String[] { Sync.Stats.ACCOUNT };
-
- private static final int MAX_HISTORY_EVENTS_TO_KEEP = 5000;
-
- private static final String SELECT_INITIAL_FAILURE_TIME_QUERY_STRING = ""
- + "SELECT min(a) "
- + "FROM ("
- + " SELECT initialFailureTime AS a "
- + " FROM status "
- + " WHERE stats_id=? AND a IS NOT NULL "
- + " UNION "
- + " SELECT ? AS a"
- + " )";
-
- private SyncStorageEngine(Context context) {
- mContext = context;
- mOpenHelper = new SyncStorageEngine.DatabaseHelper(context);
- sSyncStorageEngine = this;
- }
-
- public static SyncStorageEngine newTestInstance(Context context) {
- return new SyncStorageEngine(context);
- }
-
- public static void init(Context context) {
- if (sSyncStorageEngine != null) {
- throw new IllegalStateException("already initialized");
- }
- sSyncStorageEngine = new SyncStorageEngine(context);
- }
-
- public static SyncStorageEngine getSingleton() {
- if (sSyncStorageEngine == null) {
- throw new IllegalStateException("not initialized");
- }
- return sSyncStorageEngine;
- }
-
- private class DatabaseHelper extends SQLiteOpenHelper {
- DatabaseHelper(Context context) {
- super(context, DATABASE_NAME, null, DATABASE_VERSION);
- }
-
- @Override
- public void onCreate(SQLiteDatabase db) {
- db.execSQL("CREATE TABLE pending ("
- + "_id INTEGER PRIMARY KEY,"
- + "authority TEXT NOT NULL,"
- + "account TEXT NOT NULL,"
- + "extras BLOB NOT NULL,"
- + "source INTEGER NOT NULL"
- + ");");
-
- db.execSQL("CREATE TABLE stats (" +
- "_id INTEGER PRIMARY KEY," +
- "account TEXT, " +
- "authority TEXT, " +
- "syncdata TEXT, " +
- "UNIQUE (account, authority)" +
- ");");
-
- db.execSQL("CREATE TABLE history (" +
- "_id INTEGER PRIMARY KEY," +
- "stats_id INTEGER," +
- "eventTime INTEGER," +
- "elapsedTime INTEGER," +
- "source INTEGER," +
- "event INTEGER," +
- "upstreamActivity INTEGER," +
- "downstreamActivity INTEGER," +
- "mesg TEXT);");
-
- db.execSQL("CREATE TABLE status ("
- + "_id INTEGER PRIMARY KEY,"
- + "stats_id INTEGER NOT NULL,"
- + "totalElapsedTime INTEGER NOT NULL DEFAULT 0,"
- + "numSyncs INTEGER NOT NULL DEFAULT 0,"
- + "numSourcePoll INTEGER NOT NULL DEFAULT 0,"
- + "numSourceServer INTEGER NOT NULL DEFAULT 0,"
- + "numSourceLocal INTEGER NOT NULL DEFAULT 0,"
- + "numSourceUser INTEGER NOT NULL DEFAULT 0,"
- + "lastSuccessTime INTEGER,"
- + "lastSuccessSource INTEGER,"
- + "lastFailureTime INTEGER,"
- + "lastFailureSource INTEGER,"
- + "lastFailureMesg STRING,"
- + "initialFailureTime INTEGER,"
- + "pending INTEGER NOT NULL DEFAULT 0);");
-
- db.execSQL("CREATE TABLE active ("
- + "_id INTEGER PRIMARY KEY,"
- + "authority TEXT,"
- + "account TEXT,"
- + "startTime INTEGER);");
-
- db.execSQL("CREATE INDEX historyEventTime ON history (eventTime)");
-
- db.execSQL("CREATE TABLE settings (" +
- "name TEXT PRIMARY KEY," +
- "value TEXT);");
- }
-
- @Override
- public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
- if (oldVersion == 9 && newVersion == 10) {
- Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
- + newVersion + ", which will preserve old data");
- db.execSQL("ALTER TABLE status ADD COLUMN initialFailureTime INTEGER");
- return;
- }
-
- Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
- + newVersion + ", which will destroy all old data");
- db.execSQL("DROP TABLE IF EXISTS pending");
- db.execSQL("DROP TABLE IF EXISTS stats");
- db.execSQL("DROP TABLE IF EXISTS history");
- db.execSQL("DROP TABLE IF EXISTS settings");
- db.execSQL("DROP TABLE IF EXISTS active");
- db.execSQL("DROP TABLE IF EXISTS status");
- onCreate(db);
- }
-
- @Override
- public void onOpen(SQLiteDatabase db) {
- if (!db.isReadOnly()) {
- db.delete("active", null, null);
- db.insert("active", "account", null);
- }
- }
- }
-
- protected void doDatabaseCleanup(String[] accounts) {
- HashSet<String> currentAccounts = new HashSet<String>();
- for (String account : accounts) currentAccounts.add(account);
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- Cursor cursor = db.query("stats", STATS_ACCOUNT_PROJECTION,
- null /* where */, null /* where args */, Sync.Stats.ACCOUNT,
- null /* having */, null /* order by */);
- try {
- while (cursor.moveToNext()) {
- String account = cursor.getString(0);
- if (TextUtils.isEmpty(account)) {
- continue;
- }
- if (!currentAccounts.contains(account)) {
- String where = Sync.Stats.ACCOUNT + "=?";
- int numDeleted;
- numDeleted = db.delete("stats", where, new String[]{account});
- if (Config.LOGD) {
- Log.d(TAG, "deleted " + numDeleted
- + " records from stats table"
- + " for account " + account);
- }
- }
- }
- } finally {
- cursor.close();
- }
- }
-
- protected void setActiveSync(SyncManager.ActiveSyncContext activeSyncContext) {
- if (activeSyncContext != null) {
- updateActiveSync(activeSyncContext.mSyncOperation.account,
- activeSyncContext.mSyncOperation.authority, activeSyncContext.mStartTime);
- } else {
- // we indicate that the sync is not active by passing null for all the parameters
- updateActiveSync(null, null, null);
- }
- }
-
- private int updateActiveSync(String account, String authority, Long startTime) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- ContentValues values = new ContentValues();
- values.put("account", account);
- values.put("authority", authority);
- values.put("startTime", startTime);
- int numChanges = db.update("active", values, null, null);
- if (numChanges > 0) {
- mContext.getContentResolver().notifyChange(Sync.Active.CONTENT_URI,
- null /* this change wasn't made through an observer */);
- }
- return numChanges;
- }
-
- /**
- * Implements the {@link ContentProvider#query} method
- */
- public Cursor query(Uri url, String[] projectionIn,
- String selection, String[] selectionArgs, String sort) {
- SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-
- // Generate the body of the query
- int match = sURLMatcher.match(url);
- String groupBy = null;
- switch (match) {
- case STATS:
- qb.setTables("stats");
- break;
- case STATS_ID:
- qb.setTables("stats");
- qb.appendWhere("_id=");
- qb.appendWhere(url.getPathSegments().get(1));
- break;
- case HISTORY:
- // join the stats and history tables, so the caller can get
- // the account and authority information as part of this query.
- qb.setTables("stats, history");
- qb.setProjectionMap(HISTORY_PROJECTION_MAP);
- qb.appendWhere("stats._id = history.stats_id");
- break;
- case ACTIVE:
- qb.setTables("active");
- qb.setProjectionMap(ACTIVE_PROJECTION_MAP);
- qb.appendWhere("account is not null");
- break;
- case PENDING:
- qb.setTables("pending");
- qb.setProjectionMap(PENDING_PROJECTION_MAP);
- groupBy = "account, authority";
- break;
- case STATUS:
- // join the stats and status tables, so the caller can get
- // the account and authority information as part of this query.
- qb.setTables("stats, status");
- qb.setProjectionMap(STATUS_PROJECTION_MAP);
- qb.appendWhere("stats._id = status.stats_id");
- break;
- case HISTORY_ID:
- // join the stats and history tables, so the caller can get
- // the account and authority information as part of this query.
- qb.setTables("stats, history");
- qb.setProjectionMap(HISTORY_PROJECTION_MAP);
- qb.appendWhere("stats._id = history.stats_id");
- qb.appendWhere("AND history._id=");
- qb.appendWhere(url.getPathSegments().get(1));
- break;
- case SETTINGS:
- qb.setTables("settings");
- break;
- default:
- throw new IllegalArgumentException("Unknown URL " + url);
- }
-
- if (match == SETTINGS) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
- "no permission to read the sync settings");
- } else {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
- "no permission to read the sync stats");
- }
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- Cursor c = qb.query(db, projectionIn, selection, selectionArgs, groupBy, null, sort);
- c.setNotificationUri(mContext.getContentResolver(), url);
- return c;
- }
-
- /**
- * Implements the {@link ContentProvider#insert} method
- * @param callerIsTheProvider true if this is being called via the
- * {@link ContentProvider#insert} in method rather than directly.
- * @throws UnsupportedOperationException if callerIsTheProvider is true and the url isn't
- * for the Settings table.
- */
- public Uri insert(boolean callerIsTheProvider, Uri url, ContentValues values) {
- String table;
- long rowID;
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- final int match = sURLMatcher.match(url);
- checkCaller(callerIsTheProvider, match);
- switch (match) {
- case SETTINGS:
- mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
- "no permission to write the sync settings");
- table = "settings";
- rowID = db.replace(table, null, values);
- break;
- default:
- throw new IllegalArgumentException("Unknown URL " + url);
- }
-
-
- if (rowID > 0) {
- mContext.getContentResolver().notifyChange(url, null /* observer */);
- return Uri.parse("content://sync/" + table + "/" + rowID);
- }
-
- return null;
- }
-
- private static void checkCaller(boolean callerIsTheProvider, int match) {
- if (callerIsTheProvider && match != SETTINGS) {
- throw new UnsupportedOperationException(
- "only the settings are modifiable via the ContentProvider interface");
- }
- }
-
- /**
- * Implements the {@link ContentProvider#delete} method
- * @param callerIsTheProvider true if this is being called via the
- * {@link ContentProvider#delete} in method rather than directly.
- * @throws UnsupportedOperationException if callerIsTheProvider is true and the url isn't
- * for the Settings table.
- */
- public int delete(boolean callerIsTheProvider, Uri url, String where, String[] whereArgs) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- int match = sURLMatcher.match(url);
-
- int numRows;
- switch (match) {
- case SETTINGS:
- mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
- "no permission to write the sync settings");
- numRows = db.delete("settings", where, whereArgs);
- break;
- default:
- throw new UnsupportedOperationException("Cannot delete URL: " + url);
- }
-
- if (numRows > 0) {
- mContext.getContentResolver().notifyChange(url, null /* observer */);
- }
- return numRows;
- }
-
- /**
- * Implements the {@link ContentProvider#update} method
- * @param callerIsTheProvider true if this is being called via the
- * {@link ContentProvider#update} in method rather than directly.
- * @throws UnsupportedOperationException if callerIsTheProvider is true and the url isn't
- * for the Settings table.
- */
- public int update(boolean callerIsTheProvider, Uri url, ContentValues initialValues,
- String where, String[] whereArgs) {
- switch (sURLMatcher.match(url)) {
- case SETTINGS:
- throw new UnsupportedOperationException("updating url " + url
- + " is not allowed, use insert instead");
- default:
- throw new UnsupportedOperationException("Cannot update URL: " + url);
- }
- }
-
- /**
- * Implements the {@link ContentProvider#getType} method
- */
- public String getType(Uri url) {
- int match = sURLMatcher.match(url);
- switch (match) {
- case SETTINGS:
- return "vnd.android.cursor.dir/sync-settings";
- default:
- throw new IllegalArgumentException("Unknown URL");
- }
- }
-
- protected Uri insertIntoPending(ContentValues values) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- try {
- db.beginTransaction();
- long rowId = db.insert("pending", Sync.Pending.ACCOUNT, values);
- if (rowId < 0) return null;
- String account = values.getAsString(Sync.Pending.ACCOUNT);
- String authority = values.getAsString(Sync.Pending.AUTHORITY);
-
- long statsId = createStatsRowIfNecessary(account, authority);
- createStatusRowIfNecessary(statsId);
-
- values.clear();
- values.put(Sync.Status.PENDING, 1);
- int numUpdatesStatus = db.update("status", values, "stats_id=" + statsId, null);
-
- db.setTransactionSuccessful();
-
- mContext.getContentResolver().notifyChange(Sync.Pending.CONTENT_URI,
- null /* no observer initiated this change */);
- if (numUpdatesStatus > 0) {
- mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
- null /* no observer initiated this change */);
- }
- return ContentUris.withAppendedId(Sync.Pending.CONTENT_URI, rowId);
- } finally {
- db.endTransaction();
- }
- }
-
- int deleteFromPending(long rowId) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- String account;
- String authority;
- Cursor c = db.query("pending",
- new String[]{Sync.Pending.ACCOUNT, Sync.Pending.AUTHORITY},
- "_id=" + rowId, null, null, null, null);
- try {
- if (c.getCount() != 1) {
- return 0;
- }
- c.moveToNext();
- account = c.getString(0);
- authority = c.getString(1);
- } finally {
- c.close();
- }
- db.delete("pending", "_id=" + rowId, null /* no where args */);
- final String[] accountAuthorityWhereArgs = new String[]{account, authority};
- boolean isPending = 0 < DatabaseUtils.longForQuery(db,
- "SELECT COUNT(*) FROM PENDING WHERE account=? AND authority=?",
- accountAuthorityWhereArgs);
- if (!isPending) {
- long statsId = createStatsRowIfNecessary(account, authority);
- db.execSQL("UPDATE status SET pending=0 WHERE stats_id=" + statsId);
- }
- db.setTransactionSuccessful();
-
- mContext.getContentResolver().notifyChange(Sync.Pending.CONTENT_URI,
- null /* no observer initiated this change */);
- if (!isPending) {
- mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
- null /* no observer initiated this change */);
- }
- return 1;
- } finally {
- db.endTransaction();
- }
- }
-
- int clearPending() {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- int numChanges = db.delete("pending", null, null /* no where args */);
- if (numChanges > 0) {
- db.execSQL("UPDATE status SET pending=0");
- mContext.getContentResolver().notifyChange(Sync.Pending.CONTENT_URI,
- null /* no observer initiated this change */);
- mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
- null /* no observer initiated this change */);
- }
- db.setTransactionSuccessful();
- return numChanges;
- } finally {
- db.endTransaction();
- }
- }
-
- /**
- * Returns a cursor over all the pending syncs in no particular order. This cursor is not
- * "live", in that if changes are made to the pending table any observers on this cursor
- * will not be notified.
- * @param projection Return only these columns. If null then all columns are returned.
- * @return the cursor of pending syncs
- */
- public Cursor getPendingSyncsCursor(String[] projection) {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- return db.query("pending", projection, null, null, null, null, null);
- }
-
- // @VisibleForTesting
- static final long MILLIS_IN_4WEEKS = 1000L * 60 * 60 * 24 * 7 * 4;
-
- private boolean purgeOldHistoryEvents(long now) {
- // remove events that are older than MILLIS_IN_4WEEKS
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- int numDeletes = db.delete("history", "eventTime<" + (now - MILLIS_IN_4WEEKS), null);
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- if (numDeletes > 0) {
- Log.v(TAG, "deleted " + numDeletes + " old event(s) from the sync history");
- }
- }
-
- // keep only the last MAX_HISTORY_EVENTS_TO_KEEP history events
- numDeletes += db.delete("history", "eventTime < (select min(eventTime) from "
- + "(select eventTime from history order by eventTime desc limit ?))",
- new String[]{String.valueOf(MAX_HISTORY_EVENTS_TO_KEEP)});
-
- return numDeletes > 0;
- }
-
- public long insertStartSyncEvent(String account, String authority, long now, int source) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- long statsId = createStatsRowIfNecessary(account, authority);
-
- purgeOldHistoryEvents(now);
- ContentValues values = new ContentValues();
- values.put(Sync.History.STATS_ID, statsId);
- values.put(Sync.History.EVENT_TIME, now);
- values.put(Sync.History.SOURCE, source);
- values.put(Sync.History.EVENT, Sync.History.EVENT_START);
- long rowId = db.insert("history", null, values);
- mContext.getContentResolver().notifyChange(Sync.History.CONTENT_URI, null /* observer */);
- mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI, null /* observer */);
- return rowId;
- }
-
- public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage,
- long downstreamActivity, long upstreamActivity) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- db.beginTransaction();
- try {
- ContentValues values = new ContentValues();
- values.put(Sync.History.ELAPSED_TIME, elapsedTime);
- values.put(Sync.History.EVENT, Sync.History.EVENT_STOP);
- values.put(Sync.History.MESG, resultMessage);
- values.put(Sync.History.DOWNSTREAM_ACTIVITY, downstreamActivity);
- values.put(Sync.History.UPSTREAM_ACTIVITY, upstreamActivity);
-
- int count = db.update("history", values, "_id=?",
- new String[]{Long.toString(historyId)});
- // We think that count should always be 1 but don't want to change this until after
- // launch.
- if (count > 0) {
- int source = (int) DatabaseUtils.longForQuery(db,
- "SELECT source FROM history WHERE _id=" + historyId, null);
- long eventTime = DatabaseUtils.longForQuery(db,
- "SELECT eventTime FROM history WHERE _id=" + historyId, null);
- long statsId = DatabaseUtils.longForQuery(db,
- "SELECT stats_id FROM history WHERE _id=" + historyId, null);
-
- createStatusRowIfNecessary(statsId);
-
- // update the status table to reflect this sync
- StringBuilder sb = new StringBuilder();
- ArrayList<String> bindArgs = new ArrayList<String>();
- sb.append("UPDATE status SET");
- sb.append(" numSyncs=numSyncs+1");
- sb.append(", totalElapsedTime=totalElapsedTime+" + elapsedTime);
- switch (source) {
- case Sync.History.SOURCE_LOCAL:
- sb.append(", numSourceLocal=numSourceLocal+1");
- break;
- case Sync.History.SOURCE_POLL:
- sb.append(", numSourcePoll=numSourcePoll+1");
- break;
- case Sync.History.SOURCE_USER:
- sb.append(", numSourceUser=numSourceUser+1");
- break;
- case Sync.History.SOURCE_SERVER:
- sb.append(", numSourceServer=numSourceServer+1");
- break;
- }
-
- final String statsIdString = String.valueOf(statsId);
- final long lastSyncTime = (eventTime + elapsedTime);
- if (Sync.History.MESG_SUCCESS.equals(resultMessage)) {
- // - if successful, update the successful columns
- sb.append(", lastSuccessTime=" + lastSyncTime);
- sb.append(", lastSuccessSource=" + source);
- sb.append(", lastFailureTime=null");
- sb.append(", lastFailureSource=null");
- sb.append(", lastFailureMesg=null");
- sb.append(", initialFailureTime=null");
- } else if (!Sync.History.MESG_CANCELED.equals(resultMessage)) {
- sb.append(", lastFailureTime=" + lastSyncTime);
- sb.append(", lastFailureSource=" + source);
- sb.append(", lastFailureMesg=?");
- bindArgs.add(resultMessage);
- long initialFailureTime = DatabaseUtils.longForQuery(db,
- SELECT_INITIAL_FAILURE_TIME_QUERY_STRING,
- new String[]{statsIdString, String.valueOf(lastSyncTime)});
- sb.append(", initialFailureTime=" + initialFailureTime);
- }
- sb.append(" WHERE stats_id=?");
- bindArgs.add(statsIdString);
- db.execSQL(sb.toString(), bindArgs.toArray());
- db.setTransactionSuccessful();
- mContext.getContentResolver().notifyChange(Sync.History.CONTENT_URI,
- null /* observer */);
- mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
- null /* observer */);
- }
- } finally {
- db.endTransaction();
- }
- }
-
- /**
- * If sync is failing for any of the provider/accounts then determine the time at which it
- * started failing and return the earliest time over all the provider/accounts. If none are
- * failing then return 0.
- */
- public long getInitialSyncFailureTime() {
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- // Join the settings for a provider with the status so that we can easily
- // check if each provider is enabled for syncing. We also join in the overall
- // enabled flag ("listen_for_tickles") to each row so that we don't need to
- // make a separate DB lookup to access it.
- Cursor c = db.rawQuery(""
- + "SELECT initialFailureTime, s1.value, s2.value "
- + "FROM status "
- + "LEFT JOIN stats ON status.stats_id=stats._id "
- + "LEFT JOIN settings as s1 ON 'sync_provider_' || authority=s1.name "
- + "LEFT JOIN settings as s2 ON s2.name='listen_for_tickles' "
- + "where initialFailureTime is not null "
- + " AND lastFailureMesg!=" + Sync.History.ERROR_TOO_MANY_DELETIONS
- + " AND lastFailureMesg!=" + Sync.History.ERROR_AUTHENTICATION
- + " AND lastFailureMesg!=" + Sync.History.ERROR_SYNC_ALREADY_IN_PROGRESS
- + " AND authority!='subscribedfeeds' "
- + " ORDER BY initialFailureTime", null);
- try {
- while (c.moveToNext()) {
- // these settings default to true, so if they are null treat them as enabled
- final String providerEnabledString = c.getString(1);
- if (providerEnabledString != null && !Boolean.parseBoolean(providerEnabledString)) {
- continue;
- }
- final String allEnabledString = c.getString(2);
- if (allEnabledString != null && !Boolean.parseBoolean(allEnabledString)) {
- continue;
- }
- return c.getLong(0);
- }
- } finally {
- c.close();
- }
- return 0;
- }
-
- private void createStatusRowIfNecessary(long statsId) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- boolean statusExists = 0 != DatabaseUtils.longForQuery(db,
- "SELECT count(*) FROM status WHERE stats_id=" + statsId, null);
- if (!statusExists) {
- ContentValues values = new ContentValues();
- values.put("stats_id", statsId);
- db.insert("status", null, values);
- }
- }
-
- private long createStatsRowIfNecessary(String account, String authority) {
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- StringBuilder where = new StringBuilder();
- where.append(Sync.Stats.ACCOUNT + "= ?");
- where.append(" and " + Sync.Stats.AUTHORITY + "= ?");
- Cursor cursor = query(Sync.Stats.CONTENT_URI,
- Sync.Stats.SYNC_STATS_PROJECTION,
- where.toString(), new String[] { account, authority },
- null /* order */);
- try {
- long id;
- if (cursor.moveToFirst()) {
- id = cursor.getLong(cursor.getColumnIndexOrThrow(Sync.Stats._ID));
- } else {
- ContentValues values = new ContentValues();
- values.put(Sync.Stats.ACCOUNT, account);
- values.put(Sync.Stats.AUTHORITY, authority);
- id = db.insert("stats", null, values);
- }
- return id;
- } finally {
- cursor.close();
- }
- }
-}
diff --git a/core/java/android/content/SyncUIContext.java b/core/java/android/content/SyncUIContext.java
deleted file mode 100644
index 6dde004..0000000
--- a/core/java/android/content/SyncUIContext.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-/**
- * Class with callback methods for SyncAdapters and ContentProviders
- * that are called in response to the calls on SyncContext. This class
- * is really only meant to be used by the Sync UI activities.
- *
- * <p>All of the onXXX callback methods here are called from a handler
- * on the thread this object was created in.
- *
- * <p>This interface is unused. It should be removed.
- *
- * @hide
- */
-@Deprecated
-public interface SyncUIContext {
-
- void setStatusText(String text);
-
- Context context();
-}
diff --git a/core/java/android/content/SyncableContentProvider.java b/core/java/android/content/SyncableContentProvider.java
deleted file mode 100644
index e0cd786..0000000
--- a/core/java/android/content/SyncableContentProvider.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-
-import java.util.Map;
-
-/**
- * A specialization of the ContentProvider that centralizes functionality
- * used by ContentProviders that are syncable. It also wraps calls to the ContentProvider
- * inside of database transactions.
- *
- * @hide
- */
-public abstract class SyncableContentProvider extends ContentProvider {
- protected abstract boolean isTemporary();
-
- /**
- * Close resources that must be closed. You must call this to properly release
- * the resources used by the SyncableContentProvider.
- */
- public abstract void close();
-
- /**
- * Override to create your schema and do anything else you need to do with a new database.
- * This is run inside a transaction (so you don't need to use one).
- * This method may not use getDatabase(), or call content provider methods, it must only
- * use the database handle passed to it.
- */
- protected abstract void bootstrapDatabase(SQLiteDatabase db);
-
- /**
- * Override to upgrade your database from an old version to the version you specified.
- * Don't set the DB version, this will automatically be done after the method returns.
- * This method may not use getDatabase(), or call content provider methods, it must only
- * use the database handle passed to it.
- *
- * @param oldVersion version of the existing database
- * @param newVersion current version to upgrade to
- * @return true if the upgrade was lossless, false if it was lossy
- */
- protected abstract boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion);
-
- /**
- * Override to do anything (like cleanups or checks) you need to do after opening a database.
- * Does nothing by default. This is run inside a transaction (so you don't need to use one).
- * This method may not use getDatabase(), or call content provider methods, it must only
- * use the database handle passed to it.
- */
- protected abstract void onDatabaseOpened(SQLiteDatabase db);
-
- /**
- * Get a non-persistent instance of this content provider.
- * You must call {@link #close} on the returned
- * SyncableContentProvider when you are done with it.
- *
- * @return a non-persistent content provider with the same layout as this
- * provider.
- */
- public abstract SyncableContentProvider getTemporaryInstance();
-
- public abstract SQLiteDatabase getDatabase();
-
- public abstract boolean getContainsDiffs();
-
- public abstract void setContainsDiffs(boolean containsDiffs);
-
- /**
- * Each subclass of this class should define a subclass of {@link
- * AbstractTableMerger} for each table they wish to merge. It
- * should then override this method and return one instance of
- * each merger, in sequence. Their {@link
- * AbstractTableMerger#merge merge} methods will be called, one at a
- * time, in the order supplied.
- *
- * <p>The default implementation returns an empty list, so that no
- * merging will occur.
- * @return A sequence of subclasses of {@link
- * AbstractTableMerger}, one for each table that should be merged.
- */
- protected abstract Iterable<? extends AbstractTableMerger> getMergers();
-
- /**
- * Check if changes to this URI can be syncable changes.
- * @param uri the URI of the resource that was changed
- * @return true if changes to this URI can be syncable changes, false otherwise
- */
- public abstract boolean changeRequiresLocalSync(Uri uri);
-
- /**
- * Called right before a sync is started.
- *
- * @param context the sync context for the operation
- * @param account
- */
- public abstract void onSyncStart(SyncContext context, String account);
-
- /**
- * Called right after a sync is completed
- *
- * @param context the sync context for the operation
- * @param success true if the sync succeeded, false if an error occurred
- */
- public abstract void onSyncStop(SyncContext context, boolean success);
-
- /**
- * The account of the most recent call to onSyncStart()
- * @return the account
- */
- public abstract String getSyncingAccount();
-
- /**
- * Merge diffs from a sync source with this content provider.
- *
- * @param context the SyncContext within which this merge is taking place
- * @param diffs A temporary content provider containing diffs from a sync
- * source.
- * @param result a MergeResult that contains information about the merge, including
- * a temporary content provider with the same layout as this provider containing
- * @param syncResult
- */
- public abstract void merge(SyncContext context, SyncableContentProvider diffs,
- TempProviderSyncResult result, SyncResult syncResult);
-
-
- /**
- * Invoked when the active sync has been canceled. The default
- * implementation doesn't do anything (except ensure that this
- * provider is syncable). Subclasses of ContentProvider
- * that support canceling of sync should override this.
- */
- public abstract void onSyncCanceled();
-
-
- public abstract boolean isMergeCancelled();
-
- /**
- * Subclasses should override this instead of update(). See update()
- * for details.
- *
- * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
- * which means a database transaction will be active during the call;
- */
- protected abstract int updateInternal(Uri url, ContentValues values,
- String selection, String[] selectionArgs);
-
- /**
- * Subclasses should override this instead of delete(). See delete()
- * for details.
- *
- * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
- * which means a database transaction will be active during the call;
- */
- protected abstract int deleteInternal(Uri url, String selection, String[] selectionArgs);
-
- /**
- * Subclasses should override this instead of insert(). See insert()
- * for details.
- *
- * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
- * which means a database transaction will be active during the call;
- */
- protected abstract Uri insertInternal(Uri url, ContentValues values);
-
- /**
- * Subclasses should override this instead of query(). See query()
- * for details.
- *
- * <p> This method is *not* called within a acquireDbLock()/releaseDbLock()
- * block for performance reasons. If an implementation needs atomic access
- * to the database the lock can be acquired then.
- */
- protected abstract Cursor queryInternal(Uri url, String[] projection,
- String selection, String[] selectionArgs, String sortOrder);
-
- /**
- * Make sure that there are no entries for accounts that no longer exist
- * @param accountsArray the array of currently-existing accounts
- */
- protected abstract void onAccountsChanged(String[] accountsArray);
-
- /**
- * A helper method to delete all rows whose account is not in the accounts
- * map. The accountColumnName is the name of the column that is expected
- * to hold the account. If a row has an empty account it is never deleted.
- *
- * @param accounts a map of existing accounts
- * @param table the table to delete from
- * @param accountColumnName the name of the column that is expected
- * to hold the account.
- */
- protected abstract void deleteRowsForRemovedAccounts(Map<String, Boolean> accounts,
- String table, String accountColumnName);
-
- /**
- * Called when the sync system determines that this provider should no longer
- * contain records for the specified account.
- */
- public abstract void wipeAccount(String account);
-
- /**
- * Retrieves the SyncData bytes for the given account. The byte array returned may be null.
- */
- public abstract byte[] readSyncDataBytes(String account);
-
- /**
- * Sets the SyncData bytes for the given account. The bytes array may be null.
- */
- public abstract void writeSyncDataBytes(String account, byte[] data);
-}
-
diff --git a/core/java/android/content/TempProviderSyncAdapter.java b/core/java/android/content/TempProviderSyncAdapter.java
deleted file mode 100644
index eb3a5da..0000000
--- a/core/java/android/content/TempProviderSyncAdapter.java
+++ /dev/null
@@ -1,550 +0,0 @@
-package android.content;
-
-import android.database.SQLException;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.NetStat;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.TimingLogger;
-
-/**
- * @hide
- */
-public abstract class TempProviderSyncAdapter extends SyncAdapter {
- private static final String TAG = "Sync";
-
- private static final int MAX_GET_SERVER_DIFFS_LOOP_COUNT = 20;
- private static final int MAX_UPLOAD_CHANGES_LOOP_COUNT = 10;
- private static final int NUM_ALLOWED_SIMULTANEOUS_DELETIONS = 5;
- private static final long PERCENT_ALLOWED_SIMULTANEOUS_DELETIONS = 20;
-
- private volatile SyncableContentProvider mProvider;
- private volatile SyncThread mSyncThread = null;
- private volatile boolean mProviderSyncStarted;
- private volatile boolean mAdapterSyncStarted;
-
- public TempProviderSyncAdapter(SyncableContentProvider provider) {
- super();
- mProvider = provider;
- }
-
- /**
- * Used by getServerDiffs() to track the sync progress for a given
- * sync adapter. Implementations of SyncAdapter generally specialize
- * this class in order to track specific data about that SyncAdapter's
- * sync. If an implementation of SyncAdapter doesn't need to store
- * any data for a sync it may use TrivialSyncData.
- */
- public static abstract class SyncData implements Parcelable {
-
- }
-
- public final void setContext(Context context) {
- mContext = context;
- }
-
- /**
- * Retrieve the Context this adapter is running in. Only available
- * once onSyncStarting() is called (not available from constructor).
- */
- final public Context getContext() {
- return mContext;
- }
-
- /**
- * Called right before a sync is started.
- *
- * @param context allows you to publish status and interact with the
- * @param account the account to sync
- * @param forced if true then the sync was forced
- * @param result information to track what happened during this sync attempt
- * @return true, if the sync was successfully started. One reason it can
- * fail to start is if there is no user configured on the device.
- */
- public abstract void onSyncStarting(SyncContext context, String account, boolean forced,
- SyncResult result);
-
- /**
- * Called right after a sync is completed
- *
- * @param context allows you to publish status and interact with the
- * user during interactive syncs.
- * @param success true if the sync suceeded, false if an error occured
- */
- public abstract void onSyncEnding(SyncContext context, boolean success);
-
- /**
- * Implement this to return true if the data in your content provider
- * is read only.
- */
- public abstract boolean isReadOnly();
-
- /**
- * Get diffs from the server since the last completed sync and put them
- * into a temporary provider.
- *
- * @param context allows you to publish status and interact with the
- * user during interactive syncs.
- * @param syncData used to track the progress this client has made in syncing data
- * from the server
- * @param tempProvider this is where the diffs should be stored
- * @param extras any extra data describing the sync that is desired
- * @param syncInfo sync adapter-specific data that is used during a single sync operation
- * @param syncResult information to track what happened during this sync attempt
- */
- public abstract void getServerDiffs(SyncContext context,
- SyncData syncData, SyncableContentProvider tempProvider,
- Bundle extras, Object syncInfo, SyncResult syncResult);
-
- /**
- * Send client diffs to the server, optionally receiving more diffs from the server
- *
- * @param context allows you to publish status and interact with the
- * user during interactive syncs.
- * @param clientDiffs the diffs from the client
- * @param serverDiffs the SyncableContentProvider that should be populated with
-* the entries that were returned in response to an insert/update/delete request
-* to the server
- * @param syncResult information to track what happened during this sync attempt
- * @param dontActuallySendDeletes
- */
- public abstract void sendClientDiffs(SyncContext context,
- SyncableContentProvider clientDiffs,
- SyncableContentProvider serverDiffs, SyncResult syncResult,
- boolean dontActuallySendDeletes);
-
- /**
- * Reads the sync data from the ContentProvider
- * @param contentProvider the ContentProvider to read from
- * @return the SyncData for the provider. This may be null.
- */
- public SyncData readSyncData(SyncableContentProvider contentProvider) {
- return null;
- }
-
- /**
- * Create and return a new, empty SyncData object
- */
- public SyncData newSyncData() {
- return null;
- }
-
- /**
- * Stores the sync data in the Sync Stats database, keying it by
- * the account that was set in the last call to onSyncStarting()
- */
- public void writeSyncData(SyncData syncData, SyncableContentProvider contentProvider) {}
-
- /**
- * Indicate to the SyncAdapter that the last sync that was started has
- * been cancelled.
- */
- public abstract void onSyncCanceled();
-
- /**
- * Initializes the temporary content providers used during
- * {@link TempProviderSyncAdapter#sendClientDiffs}.
- * May copy relevant data from the underlying db into this provider so
- * joins, etc., can work.
- *
- * @param cp The ContentProvider to initialize.
- */
- protected void initTempProvider(SyncableContentProvider cp) {}
-
- protected Object createSyncInfo() {
- return null;
- }
-
- /**
- * Called when the accounts list possibly changed, to give the
- * SyncAdapter a chance to do any necessary bookkeeping, e.g.
- * to make sure that any required SubscribedFeeds subscriptions
- * exist.
- * @param accounts the list of accounts
- */
- public abstract void onAccountsChanged(String[] accounts);
-
- private Context mContext;
-
- private class SyncThread extends Thread {
- private final String mAccount;
- private final Bundle mExtras;
- private final SyncContext mSyncContext;
- private volatile boolean mIsCanceled = false;
- private long mInitialTxBytes;
- private long mInitialRxBytes;
- private final SyncResult mResult;
-
- SyncThread(SyncContext syncContext, String account, Bundle extras) {
- super("SyncThread");
- mAccount = account;
- mExtras = extras;
- mSyncContext = syncContext;
- mResult = new SyncResult();
- }
-
- void cancelSync() {
- mIsCanceled = true;
- if (mAdapterSyncStarted) onSyncCanceled();
- if (mProviderSyncStarted) mProvider.onSyncCanceled();
- // We may lose the last few sync events when canceling. Oh well.
- int uid = Process.myUid();
- logSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
- NetStat.getUidRxBytes(uid) - mInitialRxBytes, mResult);
- }
-
- @Override
- public void run() {
- Process.setThreadPriority(Process.myTid(),
- Process.THREAD_PRIORITY_BACKGROUND);
- int uid = Process.myUid();
- mInitialTxBytes = NetStat.getUidTxBytes(uid);
- mInitialRxBytes = NetStat.getUidRxBytes(uid);
- try {
- sync(mSyncContext, mAccount, mExtras);
- } catch (SQLException e) {
- Log.e(TAG, "Sync failed", e);
- mResult.databaseError = true;
- } finally {
- mSyncThread = null;
- if (!mIsCanceled) {
- logSyncDetails(NetStat.getUidTxBytes(uid) - mInitialTxBytes,
- NetStat.getUidRxBytes(uid) - mInitialRxBytes, mResult);
- mSyncContext.onFinished(mResult);
- }
- }
- }
-
- private void sync(SyncContext syncContext, String account, Bundle extras) {
- mIsCanceled = false;
-
- mProviderSyncStarted = false;
- mAdapterSyncStarted = false;
- String message = null;
-
- boolean syncForced = extras.getBoolean(ContentResolver.SYNC_EXTRAS_FORCE, false);
-
- try {
- mProvider.onSyncStart(syncContext, account);
- mProviderSyncStarted = true;
- onSyncStarting(syncContext, account, syncForced, mResult);
- if (mResult.hasError()) {
- message = "SyncAdapter failed while trying to start sync";
- return;
- }
- mAdapterSyncStarted = true;
- if (mIsCanceled) {
- return;
- }
- final String syncTracingEnabledValue = SystemProperties.get(TAG + "Tracing");
- final boolean syncTracingEnabled = !TextUtils.isEmpty(syncTracingEnabledValue);
- try {
- if (syncTracingEnabled) {
- System.gc();
- System.gc();
- Debug.startMethodTracing("synctrace." + System.currentTimeMillis());
- }
- runSyncLoop(syncContext, account, extras);
- } finally {
- if (syncTracingEnabled) Debug.stopMethodTracing();
- }
- onSyncEnding(syncContext, !mResult.hasError());
- mAdapterSyncStarted = false;
- mProvider.onSyncStop(syncContext, true);
- mProviderSyncStarted = false;
- } finally {
- if (mAdapterSyncStarted) {
- mAdapterSyncStarted = false;
- onSyncEnding(syncContext, false);
- }
- if (mProviderSyncStarted) {
- mProviderSyncStarted = false;
- mProvider.onSyncStop(syncContext, false);
- }
- if (!mIsCanceled) {
- if (message != null) syncContext.setStatusText(message);
- }
- }
- }
-
- private void runSyncLoop(SyncContext syncContext, String account, Bundle extras) {
- TimingLogger syncTimer = new TimingLogger(TAG + "Profiling", "sync");
- syncTimer.addSplit("start");
- int loopCount = 0;
- boolean tooManyGetServerDiffsAttempts = false;
-
- final boolean overrideTooManyDeletions =
- extras.getBoolean(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS,
- false);
- final boolean discardLocalDeletions =
- extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS, false);
- boolean uploadOnly = extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD,
- false /* default this flag to false */);
- SyncableContentProvider serverDiffs = null;
- TempProviderSyncResult result = new TempProviderSyncResult();
- try {
- if (!uploadOnly) {
- /**
- * This loop repeatedly calls SyncAdapter.getServerDiffs()
- * (to get changes from the feed) followed by
- * ContentProvider.merge() (to incorporate these changes
- * into the provider), stopping when the SyncData returned
- * from getServerDiffs() indicates that all the data was
- * fetched.
- */
- while (!mIsCanceled) {
- // Don't let a bad sync go forever
- if (loopCount++ == MAX_GET_SERVER_DIFFS_LOOP_COUNT) {
- Log.e(TAG, "runSyncLoop: Hit max loop count while getting server diffs "
- + getClass().getName());
- // TODO: change the structure here to schedule a new sync
- // with a backoff time, keeping track to be sure
- // we don't keep doing this forever (due to some bug or
- // mismatch between the client and the server)
- tooManyGetServerDiffsAttempts = true;
- break;
- }
-
- // Get an empty content provider to put the diffs into
- if (serverDiffs != null) serverDiffs.close();
- serverDiffs = mProvider.getTemporaryInstance();
-
- // Get records from the server which will be put into the serverDiffs
- initTempProvider(serverDiffs);
- Object syncInfo = createSyncInfo();
- SyncData syncData = readSyncData(serverDiffs);
- // syncData will only be null if there was a demarshalling error
- // while reading the sync data.
- if (syncData == null) {
- mProvider.wipeAccount(account);
- syncData = newSyncData();
- }
- mResult.clear();
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: running getServerDiffs using syncData "
- + syncData.toString());
- }
- getServerDiffs(syncContext, syncData, serverDiffs, extras, syncInfo,
- mResult);
-
- if (mIsCanceled) return;
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: result: " + mResult);
- }
- if (mResult.hasError()) return;
- if (mResult.partialSyncUnavailable) {
- if (Config.LOGD) {
- Log.d(TAG, "partialSyncUnavailable is set, setting "
- + "ignoreSyncData and retrying");
- }
- mProvider.wipeAccount(account);
- continue;
- }
-
- // write the updated syncData back into the temp provider
- writeSyncData(syncData, serverDiffs);
-
- // apply the downloaded changes to the provider
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: running merge");
- }
- mProvider.merge(syncContext, serverDiffs,
- null /* don't return client diffs */, mResult);
- if (mIsCanceled) return;
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: result: " + mResult);
- }
-
- // if the server has no more changes then break out of the loop
- if (!mResult.moreRecordsToGet) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: fetched all data, moving on");
- }
- break;
- }
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: more data to fetch, looping");
- }
- }
- }
-
- /**
- * This loop repeatedly calls ContentProvider.merge() followed
- * by SyncAdapter.merge() until either indicate that there is
- * no more work to do by returning null.
- * <p>
- * The initial ContentProvider.merge() returns a temporary
- * ContentProvider that contains any local changes that need
- * to be committed to the server.
- * <p>
- * The SyncAdapter.merge() calls upload the changes to the server
- * and populates temporary provider (the serverDiffs) with the
- * result.
- * <p>
- * Subsequent calls to ContentProvider.merge() incoporate the
- * result of previous SyncAdapter.merge() calls into the
- * real ContentProvider and again return a temporary
- * ContentProvider that contains any local changes that need
- * to be committed to the server.
- */
- loopCount = 0;
- boolean readOnly = isReadOnly();
- long previousNumModifications = 0;
- if (serverDiffs != null) {
- serverDiffs.close();
- serverDiffs = null;
- }
-
- // If we are discarding local deletions then we need to redownload all the items
- // again (since some of them might have been deleted). We do this by deleting the
- // sync data for the current account by writing in a null one.
- if (discardLocalDeletions) {
- serverDiffs = mProvider.getTemporaryInstance();
- initTempProvider(serverDiffs);
- writeSyncData(null, serverDiffs);
- }
-
- while (!mIsCanceled) {
- if (Config.LOGV) {
- Log.v(TAG, "runSyncLoop: Merging diffs from server to client");
- }
- if (result.tempContentProvider != null) {
- result.tempContentProvider.close();
- result.tempContentProvider = null;
- }
- mResult.clear();
- mProvider.merge(syncContext, serverDiffs, readOnly ? null : result,
- mResult);
- if (mIsCanceled) return;
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: result: " + mResult);
- }
-
- SyncableContentProvider clientDiffs =
- readOnly ? null : result.tempContentProvider;
- if (clientDiffs == null) {
- // Nothing to commit back to the server
- if (Config.LOGV) Log.v(TAG, "runSyncLoop: No client diffs");
- break;
- }
-
- long numModifications = mResult.stats.numUpdates
- + mResult.stats.numDeletes
- + mResult.stats.numInserts;
-
- // as long as we are making progress keep resetting the loop count
- if (numModifications < previousNumModifications) {
- loopCount = 0;
- }
- previousNumModifications = numModifications;
-
- // Don't let a bad sync go forever
- if (loopCount++ >= MAX_UPLOAD_CHANGES_LOOP_COUNT) {
- Log.e(TAG, "runSyncLoop: Hit max loop count while syncing "
- + getClass().getName());
- mResult.tooManyRetries = true;
- break;
- }
-
- if (!overrideTooManyDeletions && !discardLocalDeletions
- && hasTooManyDeletions(mResult.stats)) {
- if (Config.LOGD) {
- Log.d(TAG, "runSyncLoop: Too many deletions were found in provider "
- + getClass().getName() + ", not doing any more updates");
- }
- long numDeletes = mResult.stats.numDeletes;
- mResult.stats.clear();
- mResult.tooManyDeletions = true;
- mResult.stats.numDeletes = numDeletes;
- break;
- }
-
- if (Config.LOGV) Log.v(TAG, "runSyncLoop: Merging diffs from client to server");
- if (serverDiffs != null) serverDiffs.close();
- serverDiffs = clientDiffs.getTemporaryInstance();
- initTempProvider(serverDiffs);
- mResult.clear();
- sendClientDiffs(syncContext, clientDiffs, serverDiffs, mResult,
- discardLocalDeletions);
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: result: " + mResult);
- }
-
- if (!mResult.madeSomeProgress()) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: No data from client diffs merge");
- }
- break;
- }
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: made some progress, looping");
- }
- }
-
- // add in any status codes that we saved from earlier
- mResult.tooManyRetries |= tooManyGetServerDiffsAttempts;
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "runSyncLoop: final result: " + mResult);
- }
- } finally {
- // do this in the finally block to guarantee that is is set and not overwritten
- if (discardLocalDeletions) {
- mResult.fullSyncRequested = true;
- }
- if (serverDiffs != null) serverDiffs.close();
- if (result.tempContentProvider != null) result.tempContentProvider.close();
- syncTimer.addSplit("stop");
- syncTimer.dumpToLog();
- }
- }
- }
-
- /**
- * Logs details on the sync.
- * Normally this will be overridden by a subclass that will provide
- * provider-specific details.
- *
- * @param bytesSent number of bytes the sync sent over the network
- * @param bytesReceived number of bytes the sync received over the network
- * @param result The SyncResult object holding info on the sync
- */
- protected void logSyncDetails(long bytesSent, long bytesReceived, SyncResult result) {
- EventLog.writeEvent(SyncAdapter.LOG_SYNC_DETAILS, TAG, bytesSent, bytesReceived, "");
- }
-
- public void startSync(SyncContext syncContext, String account, Bundle extras) {
- if (mSyncThread != null) {
- syncContext.onFinished(SyncResult.ALREADY_IN_PROGRESS);
- return;
- }
-
- mSyncThread = new SyncThread(syncContext, account, extras);
- mSyncThread.start();
- }
-
- public void cancelSync() {
- if (mSyncThread != null) {
- mSyncThread.cancelSync();
- }
- }
-
- protected boolean hasTooManyDeletions(SyncStats stats) {
- long numEntries = stats.numEntries;
- long numDeletedEntries = stats.numDeletes;
-
- long percentDeleted = (numDeletedEntries == 0)
- ? 0
- : (100 * numDeletedEntries /
- (numEntries + numDeletedEntries));
- boolean tooManyDeletions =
- (numDeletedEntries > NUM_ALLOWED_SIMULTANEOUS_DELETIONS)
- && (percentDeleted > PERCENT_ALLOWED_SIMULTANEOUS_DELETIONS);
- return tooManyDeletions;
- }
-}
diff --git a/core/java/android/content/TempProviderSyncResult.java b/core/java/android/content/TempProviderSyncResult.java
deleted file mode 100644
index 81f6f79..0000000
--- a/core/java/android/content/TempProviderSyncResult.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-/**
- * Used to hold data returned from a given phase of a TempProviderSync.
- * @hide
- */
-public class TempProviderSyncResult {
- /**
- * An interface to a temporary content provider that contains
- * the result of updates that were sent to the server. This
- * provider must be merged into the permanent content provider.
- * This may be null, which indicates that there is nothing to
- * merge back into the content provider.
- */
- public SyncableContentProvider tempContentProvider;
-
- public TempProviderSyncResult() {
- tempContentProvider = null;
- }
-}
diff --git a/core/java/android/content/UriMatcher.java b/core/java/android/content/UriMatcher.java
deleted file mode 100644
index a98e6d5..0000000
--- a/core/java/android/content/UriMatcher.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.net.Uri;
-
-import java.util.ArrayList;
-import java.util.regex.Pattern;
-
-/**
-Utility class to aid in matching URIs in content providers.
-
-<p>To use this class, build up a tree of UriMatcher objects.
-Typically, it looks something like this:
-<pre>
- private static final int PEOPLE = 1;
- private static final int PEOPLE_ID = 2;
- private static final int PEOPLE_PHONES = 3;
- private static final int PEOPLE_PHONES_ID = 4;
- private static final int PEOPLE_CONTACTMETHODS = 7;
- private static final int PEOPLE_CONTACTMETHODS_ID = 8;
-
- private static final int DELETED_PEOPLE = 20;
-
- private static final int PHONES = 9;
- private static final int PHONES_ID = 10;
- private static final int PHONES_FILTER = 14;
-
- private static final int CONTACTMETHODS = 18;
- private static final int CONTACTMETHODS_ID = 19;
-
- private static final int CALLS = 11;
- private static final int CALLS_ID = 12;
- private static final int CALLS_FILTER = 15;
-
- private static final UriMatcher sURIMatcher = new UriMatcher();
-
- static
- {
- sURIMatcher.addURI("contacts", "/people", PEOPLE);
- sURIMatcher.addURI("contacts", "/people/#", PEOPLE_ID);
- sURIMatcher.addURI("contacts", "/people/#/phones", PEOPLE_PHONES);
- sURIMatcher.addURI("contacts", "/people/#/phones/#", PEOPLE_PHONES_ID);
- sURIMatcher.addURI("contacts", "/people/#/contact_methods", PEOPLE_CONTACTMETHODS);
- sURIMatcher.addURI("contacts", "/people/#/contact_methods/#", PEOPLE_CONTACTMETHODS_ID);
- sURIMatcher.addURI("contacts", "/deleted_people", DELETED_PEOPLE);
- sURIMatcher.addURI("contacts", "/phones", PHONES);
- sURIMatcher.addURI("contacts", "/phones/filter/*", PHONES_FILTER);
- sURIMatcher.addURI("contacts", "/phones/#", PHONES_ID);
- sURIMatcher.addURI("contacts", "/contact_methods", CONTACTMETHODS);
- sURIMatcher.addURI("contacts", "/contact_methods/#", CONTACTMETHODS_ID);
- sURIMatcher.addURI("call_log", "/calls", CALLS);
- sURIMatcher.addURI("call_log", "/calls/filter/*", CALLS_FILTER);
- sURIMatcher.addURI("call_log", "/calls/#", CALLS_ID);
- }
-</pre>
-<p>Then when you need to match match against a URI, call {@link #match}, providing
-the tokenized url you've been given, and the value you want if there isn't
-a match. You can use the result to build a query, return a type, insert or
-delete a row, or whatever you need, without duplicating all of the if-else
-logic you'd otherwise need. Like this:
-<pre>
- public String getType(String[] url)
- {
- int match = sURIMatcher.match(url, NO_MATCH);
- switch (match)
- {
- case PEOPLE:
- return "vnd.android.cursor.dir/person";
- case PEOPLE_ID:
- return "vnd.android.cursor.item/person";
-... snip ...
- return "vnd.android.cursor.dir/snail-mail";
- case PEOPLE_ADDRESS_ID:
- return "vnd.android.cursor.item/snail-mail";
- default:
- return null;
- }
- }
-</pre>
-instead of
-<pre>
- public String getType(String[] url)
- {
- if (url.length >= 2) {
- if (url[1].equals("people")) {
- if (url.length == 2) {
- return "vnd.android.cursor.dir/person";
- } else if (url.length == 3) {
- return "vnd.android.cursor.item/person";
-... snip ...
- return "vnd.android.cursor.dir/snail-mail";
- } else if (url.length == 3) {
- return "vnd.android.cursor.item/snail-mail";
- }
- }
- }
- return null;
- }
-</pre>
-*/
-public class UriMatcher
-{
- public static final int NO_MATCH = -1;
- /**
- * Creates the root node of the URI tree.
- *
- * @param code the code to match for the root URI
- */
- public UriMatcher(int code)
- {
- mCode = code;
- mWhich = -1;
- mChildren = new ArrayList<UriMatcher>();
- mText = null;
- }
-
- private UriMatcher()
- {
- mCode = NO_MATCH;
- mWhich = -1;
- mChildren = new ArrayList<UriMatcher>();
- mText = null;
- }
-
- /**
- * Add a URI to match, and the code to return when this URI is
- * matched. URI nodes may be exact match string, the token "*"
- * that matches any text, or the token "#" that matches only
- * numbers.
- *
- * @param authority the authority to match
- * @param path the path to match. * may be used as a wild card for
- * any text, and # may be used as a wild card for numbers.
- * @param code the code that is returned when a URI is matched
- * against the given components. Must be positive.
- */
- public void addURI(String authority, String path, int code)
- {
- if (code < 0) {
- throw new IllegalArgumentException("code " + code + " is invalid: it must be positive");
- }
- String[] tokens = path != null ? PATH_SPLIT_PATTERN.split(path) : null;
- int numTokens = tokens != null ? tokens.length : 0;
- UriMatcher node = this;
- for (int i = -1; i < numTokens; i++) {
- String token = i < 0 ? authority : tokens[i];
- ArrayList<UriMatcher> children = node.mChildren;
- int numChildren = children.size();
- UriMatcher child;
- int j;
- for (j = 0; j < numChildren; j++) {
- child = children.get(j);
- if (token.equals(child.mText)) {
- node = child;
- break;
- }
- }
- if (j == numChildren) {
- // Child not found, create it
- child = new UriMatcher();
- if (token.equals("#")) {
- child.mWhich = NUMBER;
- } else if (token.equals("*")) {
- child.mWhich = TEXT;
- } else {
- child.mWhich = EXACT;
- }
- child.mText = token;
- node.mChildren.add(child);
- node = child;
- }
- }
- node.mCode = code;
- }
-
- static final Pattern PATH_SPLIT_PATTERN = Pattern.compile("/");
-
- /**
- * Try to match against the path in a url.
- *
- * @param uri The url whose path we will match against.
- *
- * @return The code for the matched node (added using addURI),
- * or -1 if there is no matched node.
- */
- public int match(Uri uri)
- {
- final int li = uri.getPathSegments().size();
-
- UriMatcher node = this;
-
- if (li == 0 && uri.getAuthority() == null) {
- return this.mCode;
- }
-
- for (int i=-1; i<li; i++) {
- String u = i < 0 ? uri.getAuthority() : uri.getPathSegments().get(i);
- ArrayList<UriMatcher> list = node.mChildren;
- if (list == null) {
- break;
- }
- node = null;
- int lj = list.size();
- for (int j=0; j<lj; j++) {
- UriMatcher n = list.get(j);
- which_switch:
- switch (n.mWhich) {
- case EXACT:
- if (n.mText.equals(u)) {
- node = n;
- }
- break;
- case NUMBER:
- int lk = u.length();
- for (int k=0; k<lk; k++) {
- char c = u.charAt(k);
- if (c < '0' || c > '9') {
- break which_switch;
- }
- }
- node = n;
- break;
- case TEXT:
- node = n;
- break;
- }
- if (node != null) {
- break;
- }
- }
- if (node == null) {
- return NO_MATCH;
- }
- }
-
- return node.mCode;
- }
-
- private static final int EXACT = 0;
- private static final int NUMBER = 1;
- private static final int TEXT = 2;
-
- private int mCode;
- private int mWhich;
- private String mText;
- private ArrayList<UriMatcher> mChildren;
-}
diff --git a/core/java/android/content/package.html b/core/java/android/content/package.html
deleted file mode 100644
index dd5360f..0000000
--- a/core/java/android/content/package.html
+++ /dev/null
@@ -1,650 +0,0 @@
-<html>
-<head>
-<script type="text/javascript" src="http://www.corp.google.com/style/prettify.js"></script>
-<script src="http://www.corp.google.com/eng/techpubs/include/navbar.js" type="text/javascript"></script>
-</head>
-
-<body>
-
-<p>Contains classes for accessing and publishing data
-on the device. It includes three main categories of APIs:
-the {@link android.content.res.Resources Resources} for
-retrieving resource data associated with an application;
-{@link android.content.ContentProvider Content Providers} and
-{@link android.content.ContentResolver ContentResolver} for managing and
-publishing persistent data associated with an application; and
-the {@link android.content.pm.PackageManager Package Manager}
-for finding out information about the application packages installed
-on the device.</p>
-
-<p>In addition, the {@link android.content.Context Context} abstract class
-is a base API for pulling these pieces together, allowing you to access
-an application's resources and transfer data between applications.</p>
-
-<p>This package builds on top of the lower-level Android packages
-{@link android.database}, {@link android.text},
-{@link android.graphics.drawable}, {@link android.graphics},
-{@link android.os}, and {@link android.util}.</p>
-
-<ol>
- <li> <a href="#Resources">Resources</a>
- <ol>
- <li> <a href="#ResourcesTerminology">Terminology</a>
- <li> <a href="#ResourcesQuickStart">Examples</a>
- <ol>
- <li> <a href="#UsingSystemResources">Using System Resources</a>
- <li> <a href="#StringResources">String Resources</a>
- <li> <a href="#ColorResources">Color Resources</a>
- <li> <a href="#DrawableResources">Drawable Resources</a>
- <li> <a href="#LayoutResources">Layout Resources</a>
- <li> <a href="#ReferencesToResources">References to Resources</a>
- <li> <a href="#ReferencesToThemeAttributes">References to Theme Attributes</a>
- <li> <a href="#StyleResources">Style Resources</a>
- <li> <a href="#StylesInLayoutResources">Styles in Layout Resources</a>
- </ol>
- </ol>
-</ol>
-
-<a name="Resources"></a>
-<h2>Resources</h2>
-
-<p>This topic includes a terminology list associated with resources, and a series
- of examples of using resources in code. For a complete guide on creating and
- using resources, see the document on <a href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources
- and Internationalization</a>. For a reference on the supported Android resource types,
- see <a href="{@docRoot}guide/topics/resources/available-resources.html">Available Resource Types</a>.</p>
-<p>The Android resource system keeps track of all non-code
- assets associated with an application. You use the
- {@link android.content.res.Resources Resources} class to access your
- application's resources; the Resources instance associated with your
- application can generally be found through
- {@link android.content.Context#getResources Context.getResources()}.</p>
-<p>An application's resources are compiled into the application
-binary at build time for you by the build system. To use a resource,
-you must install it correctly in the source tree and build your
-application. As part of the build process, Java symbols for each
-of the resources are generated that you can use in your source
-code -- this allows the compiler to verify that your application code matches
-up with the resources you defined.</p>
-
-<p>The rest of this section is organized as a tutorial on how to
-use resources in an application.</p>
-
-<a name="ResourcesTerminology"></a>
-<h3>Terminology</h3>
-
-<p>The resource system brings a number of different pieces together to
-form the final complete resource functionality. To help understand the
-overall system, here are some brief definitions of the core concepts and
-components you will encounter in using it:</p>
-
-<p><b>Asset</b>: A single blob of data associated with an application. This
-includes Java object files, graphics (such as PNG images), XML files, etc.
-These files are organized in a directory hierarchy that, during final packaging
-of the application, is bundled together into a single ZIP file.</p>
-
-<p><b>aapt</b>: The tool that generates the final ZIP file of application
-assets. In addition to collecting raw assets together, it also parses
-resource definitions into binary asset data.</p>
-
-<p><b>Resource Table</b>: A special asset that aapt generates for you,
-describing all of the resources contained in an application/package.
-This file is accessed for you by the Resources class; it is not touched
-directly by applications.</p>
-
-<p><b>Resource</b>: An entry in the Resource Table describing a single
-named value. Broadly, there are two types of resources: primitives and
-bags.</p>
-
-<p><b>Resource Identifier</b>: In the Resource Table all resources are
-identified by a unique integer number. In source code (resource descriptions,
-XML files, Java code) you can use symbolic names that stand as constants for
-the actual resource identifier integer.</p>
-
-<p><b>Primitive Resource</b>: All primitive resources can be written as a
-simple string, using formatting to describe a variety of primitive types
-included in the resource system: integers, colors, strings, references to
-other resources, etc. Complex resources, such as bitmaps and XML
-describes, are stored as a primitive string resource whose value is the path
-of the underlying Asset holding its actual data.</p>
-
-<p><b>Bag Resource</b>: A special kind of resource entry that, instead of a
-simple string, holds an arbitrary list of name/value pairs. Each name is
-itself a resource identifier, and each value can hold
-the same kinds of string formatted data as a normal resource. Bags also
-support inheritance: a bag can inherit the values from another bag, selectively
-replacing or extending them to generate its own contents.</p>
-
-<p><b>Kind</b>: The resource kind is a way to organize resource identifiers
-for various purposes. For example, drawable resources are used to
-instantiate Drawable objects, so their data is a primitive resource containing
-either a color constant or string path to a bitmap or XML asset. Other
-common resource kinds are string (localized string primitives), color
-(color primitives), layout (a string path to an XML asset describing a view
-layout), and style (a bag resource describing user interface attributes).
-There is also a standard "attr" resource kind, which defines the resource
-identifiers to be used for naming bag items and XML attributes</p>
-
-<p><b>Style</b>: The name of the resource kind containing bags that are used
-to supply a set of user interface attributes. For example, a TextView class may
-be given a style resource that defines its text size, color, and alignment.
-In a layout XML file, you associate a style with a bag using the "style"
-attribute, whose value is the name of the style resource.</p>
-
-<p><b>Style Class</b>: Specifies a related set of attribute resources.
-This data is not placed in the resource table itself, but used to generate
-Java constants that make it easier for you to retrieve values out of
-a style resource and/or XML tag's attributes. For example, the
-Android platform defines a "View" style class that
-contains all of the standard view attributes: padding, visibility,
-background, etc.; when View is inflated it uses this style class to
-retrieve those values from the XML file (at which point style and theme
-information is applied as approriate) and load them into its instance.</p>
-
-<p><b>Configuration</b>: For any particular resource identifier, there may be
-multiple different available values depending on the current configuration.
-The configuration includes the locale (language and country), screen
-orientation, screen density, etc. The current configuration is used to
-select which resource values are in effect when the resource table is
-loaded.</p>
-
-<p><b>Theme</b>: A standard style resource that supplies global
-attribute values for a particular context. For example, when writing a
-Activity the application developer can select a standard theme to use, such
-as the Theme.White or Theme.Black styles; this style supplies information
-such as the screen background image/color, default text color, button style,
-text editor style, text size, etc. When inflating a layout resource, most
-values for widgets (the text color, selector, background) if not explicitly
-set will come from the current theme; style and attribute
-values supplied in the layout can also assign their value from explicitly
-named values in the theme attributes if desired.</p>
-
-<p><b>Overlay</b>: A resource table that does not define a new set of resources,
-but instead replaces the values of resources that are in another resource table.
-Like a configuration, this is applied at load time
-to the resource data; it can add new configuration values (for example
-strings in a new locale), replace existing values (for example change
-the standard white background image to a "Hello Kitty" background image),
-and modify resource bags (for example change the font size of the Theme.White
-style to have an 18 pt font size). This is the facility that allows the
-user to select between different global appearances of their device, or
-download files with new appearances.</p>
-
-<a name="ResourcesQuickStart"></a>
-<h3>Examples</h3>
-
-<p>This section gives a few quick examples you can use to make your own resources.
- For more details on how to define and use resources, see <a
- href="{@docRoot}guide/topics/resources/resources-i18n.html">Resources and
- Internationalization</a>. </p>
-
-<a name="UsingSystemResources"></a>
-<h4>Using System Resources</h4>
-
-<p>Many resources included with the system are available to applications.
-All such resources are defined under the class "android.R". For example,
-you can display the standard application icon in a screen with the following
-code:</p>
-
-<pre class="prettyprint">
-public class MyActivity extends Activity
-{
- public void onStart()
- {
- requestScreenFeatures(FEATURE_BADGE_IMAGE);
-
- super.onStart();
-
- setBadgeResource(android.R.drawable.sym_def_app_icon);
- }
-}
-</pre>
-
-<p>In a similar way, this code will apply to your screen the standard
-"green background" visual treatment defined by the system:</p>
-
-<pre class="prettyprint">
-public class MyActivity extends Activity
-{
- public void onStart()
- {
- super.onStart();
-
- setTheme(android.R.style.Theme_Black);
- }
-}
-</pre>
-
-<a name="StringResources"></a>
-<h4>String Resources</h4>
-
-<p>String resources are defined using an XML resource description syntax.
-The file or multiple files containing these resources can be given any name
-(as long as it has a .xml suffix) and placed at an appropriate location in
-the source tree for the desired configuration (locale/orientation/density).
-
-<p>Here is a simple resource file describing a few strings:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;resources&gt;
- &lt;string id="mainLabel"&gt;Hello &lt;u&gt;th&lt;ignore&gt;e&lt;/ignore&gt;re&lt;/u&gt;, &lt;i&gt;you&lt;/i&gt; &lt;b&gt;Activity&lt;/b&gt;!&lt;/string&gt;
- &lt;string id="back"&gt;Back&lt;/string&gt;
- &lt;string id="clear"&gt;Clear&lt;/string&gt;
-&lt;/resources&gt;
-</pre>
-
-<p>Typically this file will be called "strings.xml", and must be placed
-in the <code>values</code> directory:</p>
-
-<pre>
-MyApp/res/values/strings.xml
-</pre>
-
-<p>The strings can now be retrieved by your application through the
-symbol specified in the "id" attribute:</p>
-
-<pre class="prettyprint">
-public class MyActivity extends Activity
-{
- public void onStart()
- {
- super.onStart();
-
- String back = getResources().getString(R.string.back).toString();
- back = getString(R.string.back).toString(); // synonym
- }
-}
-</pre>
-
-<p>Unlike system resources, the resource symbol (the R class) we are using
-here comes from our own application's package, not android.R.</p>
-
-<p>Note that the "mainLabel" string is complex, including style information.
-To support this, the <code>getString()</code> method returns a
-<code>CharSequence</code> object that you can pass to a
-<code>TextView</code> to retain those style. This is why code
-must call <code>toString()</code> on the returned resource if it wants
-a raw string.</p>
-
-<a name="ColorResources"></a>
-<h4>Color Resources</h4>
-
-<p>Color resources are created in a way very similar to string resources,
-but with the &lt;color&gt; resource tag. The data for these resources
-must be a hex color constant of the form "#rgb", "#argb", "#rrggbb", or
-"#aarrggbb". The alpha channel is 0xff (or 0xf) for opaque and 0
-for transparent.</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;resources&gt;
- &lt;color id="opaque_red"&gt;#ffff0000&lt;/color&gt;
- &lt;color id="transparent_red"&gt;#80ff0000&lt;/color&gt;
- &lt;color id="opaque_blue"&gt;#0000ff&lt;/color&gt;
- &lt;color id="opaque_green"&gt;#0f0&lt;/color&gt;
-&lt;/resources&gt;
-</pre>
-
-<p>While color definitions could be placed in the same resource file
-as the previously shown string data, usually you will place the colors in
-their own file:</p>
-
-<pre>
-MyApp/res/values/colors.xml
-</pre>
-
-<p>The colors can now be retrieved by your application through the
-symbol specified in the "id" attribute:</p>
-
-<pre class="prettyprint">
-public class MyActivity extends Activity
-{
- public void onStart()
- {
- super.onStart();
-
- int red = getResources().getColor(R.color.opaque_red);
- }
-}
-</pre>
-
-<a name="DrawableResources"></a>
-<h4>Drawable Resources</h4>
-
-<p>For simple drawable resources, all you need to do is place your
-image in a special resource sub-directory called "drawable". Files here
-are things that can be handled by an implementation of the
-{@link android.graphics.drawable.Drawable Drawable} class, often bitmaps
-(such as PNG images) but also various kinds of XML descriptions
-for selectors, gradients, etc.</p>
-
-<p>The drawable files will be scanned by the
-resource tool, automatically generating a resource entry for each found.
-For example the file <code>res/drawable/&lt;myimage&gt;.&lt;ext&gt;</code>
-will result in a resource symbol named "myimage" (without the extension). Note
-that these file names <em>must</em> be valid Java identifiers, and should
-have only lower-case letters.</p>
-
-<p>For example, to use your own custom image as a badge in a screen,
-you can place the image here:</p>
-
-<pre>
-MyApp/res/drawable/my_badge.png
-</pre>
-
-<p>The image can then be used in your code like this:</p>
-
-<pre class="prettyprint">
-public class MyActivity extends Activity
-{
- public void onStart()
- {
- requestScreenFeatures(FEATURE_BADGE_IMAGE);
-
- super.onStart();
-
- setBadgeResource(R.drawable.my_badge);
- }
-}
-</pre>
-
-<p>For drawables that are a single solid color, you can also define them
-in a resource file very much like colors shown previously. The only
-difference is that here we use the &lt;drawable&gt; tag to create a
-drawable resource.</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;resources&gt;
- &lt;drawable id="opaque_red"&gt;#ffff0000&lt;/drawable&gt;
- &lt;drawable id="transparent_red"&gt;#80ff0000&lt;/drawable&gt;
- &lt;drawable id="opaque_blue"&gt;#0000ff&lt;/drawable&gt;
- &lt;drawable id="opaque_green"&gt;#0f0&lt;/drawable&gt;
-&lt;/resources&gt;
-</pre>
-
-<p>These resource entries are often placed in the same resource file
-as color definitions:</p>
-
-<pre>
-MyApp/res/values/colors.xml
-</pre>
-
-<a name="LayoutResources"></a>
-<h4>Layout Resources</h4>
-
-<p>Layout resources describe a view hierarchy configuration that is
-generated at runtime. These resources are XML files placed in the
-resource directory "layout", and are how you should create the content
-views inside of your screen (instead of creating them by hand) so that
-they can be themed, styled, configured, and overlayed.</p>
-
-<p>Here is a simple layout resource consisting of a single view, a text
-editor:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;root&gt;
- &lt;EditText id="text"
- android:layout_width="fill-parent" android:layout_height="fill-parent"
- android:text="Hello, World!" /&gt;
-&lt;/root&gt;
-</pre>
-
-<p>To use this layout, it can be placed in a file like this:</p>
-
-<pre>
-MyApp/res/layout/my_layout.xml
-</pre>
-
-<p>The layout can then be instantiated in your screen like this:</p>
-
-<pre class="prettyprint">
-public class MyActivity extends Activity
-{
- public void onStart()
- {
- super.onStart();
- setContentView(R.layout.my_layout);
- }
-}
-</pre>
-
-<p>Note that there are a number of visual attributes that can be supplied
-to TextView (including textSize, textColor, and textStyle) that we did
-not define in the previous example; in such a sitation, the default values for
-those attributes come from the theme. If we want to customize them, we
-can supply them explicitly in the XML file:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;root&gt;
- &lt;EditText id="text"
- android:layout_width="fill_parent" android:layout_height="fill_parent"
- <b>android:textSize="18" android:textColor="#008"</b>
- android:text="Hello, World!" /&gt;
-&lt;/root&gt;
-</pre>
-
-<p>However, usually these kinds of attributes (those being attributes that
-usually make sense to vary with theme or overlay) should be defined through
-the theme or separate style resource. Later we will see how this is done.</p>
-
-<a name="ReferencesToResources"></a>
-<h4>References to Resources</h4>
-
-<p>A value supplied in an attribute (or resource) can also be a reference to
-a resource. This is often used in layout files to supply strings (so they
-can be localized) and images (which exist in another file), though a reference
-can be do any resource type including colors and integers.</p>
-
-<p>For example, if we have the previously defined color resources, we can
-write a layout file that sets the text color size to be the value contained in
-one of those resources:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;root&gt;
- &lt;EditText id="text"
- android:layout_width="fill_parent" android:layout_height="fill_parent"
- <b>android:textColor="@color/opaque_red"</b>
- android:text="Hello, World!" /&gt;
-&lt;/root&gt;
-</pre>
-
-<p>Note here the use of the '@' prefix to introduce a resource reference -- the
-text following that is the name of a resource in the form
-of <code>@[package:]type/name</code>. In this case we didn't need to specify
-the package because we are referencing a resource in our own package. To
-reference a system resource, you would need to write:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;root&gt;
- &lt;EditText id="text"
- android:layout_width="fill_parent" android:layout_height="fill_parent"
- android:textColor="@<b>android:</b>color/opaque_red"
- android:text="Hello, World!" /&gt;
-&lt;/root&gt;
-</pre>
-
-<p>As another example, you should always use resource references when supplying
-strings in a layout file so that they can be localized:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;root&gt;
- &lt;EditText id="text"
- android:layout_width="fill_parent" android:layout_height="fill_parent"
- android:textColor="@android:color/opaque_red"
- android:text="@string/hello_world" /&gt;
-&lt;/root&gt;
-</pre>
-
-<p>This facility can also be used to create references between resources.
-For example, we can create new drawable resources that are aliases for
-existing images:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;resources&gt;
- &lt;drawable id="my_background"&gt;@android:drawable/theme2_background&lt;/drawable&gt;
-&lt;/resources&gt;
-</pre>
-
-<a name="ReferencesToThemeAttributes"></a>
-<h4>References to Theme Attributes</h4>
-
-<p>Another kind of resource value allows you to reference the value of an
-attribute in the current theme. This attribute reference can <em>only</em>
-be used in style resources and XML attributes; it allows you to customize the
-look of UI elements by changing them to standard variations supplied by the
-current theme, instead of supplying more concrete values.</p>
-
-<p>As an example, we can use this in our layout to set the text color to
-one of the standard colors defined in the base system theme:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;root&gt;
- &lt;EditText id="text"
- android:layout_width="fill_parent" android:layout_height="fill_parent"
- <b>android:textColor="?android:textDisabledColor"</b>
- android:text="@string/hello_world" /&gt;
-&lt;/root&gt;
-</pre>
-
-<p>Note that this is very similar to a resource reference, except we are using
-an '?' prefix instead of '@'. When you use this markup, you are supplying
-the name of an attribute resource that will be looked up in the theme --
-because the resource tool knows that an attribute resource is expected,
-you do not need to explicitly state the type (which would be
-<code>?android:attr/android:textDisabledColor</code>).</p>
-
-<p>Other than using this resource identifier to find the value in the
-theme instead of raw resources, the name syntax is identical to the '@' format:
-<code>?[package:]type/name</code> with the type here being optional.</p>
-
-<a name="StyleResources"></a>
-<h4>Style Resources</h4>
-
-<p>A style resource is a set of name/value pairs describing a group
-of related attributes. There are two main uses for these resources:
-defining overall visual themes, and describing a set of visual attributes
-to apply to a class in a layout resource. In this section we will look
-at their use to describe themes; later we will look at using them in
-conjunction with layouts.</p>
-
-<p>Like strings, styles are defined through a resource XML file. In the
-situation where we want to define a new theme, we can create a custom theme
-style that inherits from one of the standard system themes:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;resources&gt;
- &lt;style id="Theme" parent="android:Theme.White"&gt;
- &lt;item id="android:foregroundColor"&gt;#FFF8D96F&lt;/item&gt;
- &lt;item id="android:textColor"&gt;@color/opaque_blue&lt;/item&gt;
- &lt;item id="android:textSelectedColor"&gt;?android:textColor&lt;/item&gt;
- &lt;/style&gt;
-&lt;/resources&gt;
-</pre>
-
-<p>Typically these resource definitions will be placed in a file
-called "styles.xml" , and must be placed in the <code>values</code>
-directory:</p>
-
-<pre>
-MyApp/res/values/styles.xml
-</pre>
-
-<p>Similar to how we previously used a system style for an Activity theme,
-you can apply this style to your Activity:</p>
-
-<pre class="prettyprint">
-public class MyActivity extends Activity
-{
- public void onStart()
- {
- super.onStart();
-
- setTheme(R.style.Theme);
- }
-}
-</pre>
-
-<p>In the style resource shown here, we used the <code>parent</code>
-attribute to specify another style resource from which it inherits
-its values -- in this case the <code>Theme.White</code> system resource:</p>
-
-<pre>
- &lt;style id="Home" parent="android:Theme.White"&gt;
- ...
- &lt;/style&gt;
-</pre>
-
-<p>Note, when doing this, that you must use the "android" prefix in front
-to tell the compiler the namespace to look in for the resource --
-the resources you are specifying here are in your application's namespace,
-not the system. This explicit namespace specification ensures that names
-the application uses will not accidentally conflict with those defined by
-the system.</p>
-
-<p>If you don't specify an explicit parent style, it will be inferred
-from the style name -- everything before the final '.' in the name of the
-style being defined is taken as the parent style name. Thus, to make
-another style in your application that inherits from this base Theme style,
-you can write:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;resources&gt;
- &lt;style id="Theme.WhiteText"&gt;
- &lt;item id="android:foregroundColor"&gt;#FFFFFFFF&lt;/item&gt;
- &lt;item id="android:textColor"&gt;?android:foregroundColor&lt;/item&gt;
- &lt;/style&gt;
-&lt;/resources&gt;
-</pre>
-
-<p>This results in the symbol <code>R.style.Theme_WhiteText</code> that
-can be used in Java just like we did with <code>R.style.Theme</code>
-above.</p>
-
-<a name="StylesInLayoutResources"></a>
-<h4>Styles in Layout Resources</h4>
-
-<p>Often you will have a number fo views in a layout that all use the same
-set of attributes, or want to allow resource overlays to modify the values of
-attributes. Style resources can be used for both of these purposes, to put
-attribute definitions in a single place that can be references by multiple
-XML tags and modified by overlays. To do this, you simply define a
-new style resource with the desired values:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;resources&gt;
- &lt;style id="SpecialText"&gt;
- &lt;item id="android:textSize"&gt;18&lt;/item&gt;
- &lt;item id="android:textColor"&gt;#008&lt;/item&gt;
- &lt;/style&gt;
-&lt;/resources&gt;
-</pre>
-
-<p>You can now apply this style to your TextView in the XML file:</p>
-
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?&gt;
-&lt;root&gt;
- &lt;EditText id="text1" <b>style="@style/SpecialText"</b>
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:text="Hello, World!" /&gt;
- &lt;EditText id="text2" <b>style="@style/SpecialText"</b>
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:text="I love you all." /&gt;
-&lt;/root&gt;</pre>
-<h4>&nbsp;</h4>
-
-</body>
-</html>
-
diff --git a/core/java/android/content/pm/ActivityInfo.aidl b/core/java/android/content/pm/ActivityInfo.aidl
deleted file mode 100755
index dd90302..0000000
--- a/core/java/android/content/pm/ActivityInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable ActivityInfo;
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
deleted file mode 100644
index 85d877a..0000000
--- a/core/java/android/content/pm/ActivityInfo.java
+++ /dev/null
@@ -1,353 +0,0 @@
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Printer;
-
-/**
- * Information you can retrieve about a particular application
- * activity or receiver. This corresponds to information collected
- * from the AndroidManifest.xml's &lt;activity&gt; and
- * &lt;receiver&gt; tags.
- */
-public class ActivityInfo extends ComponentInfo
- implements Parcelable {
- /**
- * A style resource identifier (in the package's resources) of this
- * activity's theme. From the "theme" attribute or, if not set, 0.
- */
- public int theme;
-
- /**
- * Constant corresponding to <code>standard</code> in
- * the {@link android.R.attr#launchMode} attribute.
- */
- public static final int LAUNCH_MULTIPLE = 0;
- /**
- * Constant corresponding to <code>singleTop</code> in
- * the {@link android.R.attr#launchMode} attribute.
- */
- public static final int LAUNCH_SINGLE_TOP = 1;
- /**
- * Constant corresponding to <code>singleTask</code> in
- * the {@link android.R.attr#launchMode} attribute.
- */
- public static final int LAUNCH_SINGLE_TASK = 2;
- /**
- * Constant corresponding to <code>singleInstance</code> in
- * the {@link android.R.attr#launchMode} attribute.
- */
- public static final int LAUNCH_SINGLE_INSTANCE = 3;
- /**
- * The launch mode style requested by the activity. From the
- * {@link android.R.attr#launchMode} attribute, one of
- * {@link #LAUNCH_MULTIPLE},
- * {@link #LAUNCH_SINGLE_TOP}, {@link #LAUNCH_SINGLE_TASK}, or
- * {@link #LAUNCH_SINGLE_INSTANCE}.
- */
- public int launchMode;
-
- /**
- * Optional name of a permission required to be able to access this
- * Activity. From the "permission" attribute.
- */
- public String permission;
-
- /**
- * The affinity this activity has for another task in the system. The
- * string here is the name of the task, often the package name of the
- * overall package. If null, the activity has no affinity. Set from the
- * {@link android.R.attr#taskAffinity} attribute.
- */
- public String taskAffinity;
-
- /**
- * If this is an activity alias, this is the real activity class to run
- * for it. Otherwise, this is null.
- */
- public String targetActivity;
-
- /**
- * Bit in {@link #flags} indicating whether this activity is able to
- * run in multiple processes. If
- * true, the system may instantiate it in the some process as the
- * process starting it in order to conserve resources. If false, the
- * default, it always runs in {@link #processName}. Set from the
- * {@link android.R.attr#multiprocess} attribute.
- */
- public static final int FLAG_MULTIPROCESS = 0x0001;
- /**
- * Bit in {@link #flags} indicating that, when the activity's task is
- * relaunched from home, this activity should be finished.
- * Set from the
- * {@link android.R.attr#finishOnTaskLaunch} attribute.
- */
- public static final int FLAG_FINISH_ON_TASK_LAUNCH = 0x0002;
- /**
- * Bit in {@link #flags} indicating that, when the activity is the root
- * of a task, that task's stack should be cleared each time the user
- * re-launches it from home. As a result, the user will always
- * return to the original activity at the top of the task.
- * This flag only applies to activities that
- * are used to start the root of a new task. Set from the
- * {@link android.R.attr#clearTaskOnLaunch} attribute.
- */
- public static final int FLAG_CLEAR_TASK_ON_LAUNCH = 0x0004;
- /**
- * Bit in {@link #flags} indicating that, when the activity is the root
- * of a task, that task's stack should never be cleared when it is
- * relaunched from home. Set from the
- * {@link android.R.attr#alwaysRetainTaskState} attribute.
- */
- public static final int FLAG_ALWAYS_RETAIN_TASK_STATE = 0x0008;
- /**
- * Bit in {@link #flags} indicating that the activity's state
- * is not required to be saved, so that if there is a failure the
- * activity will not be removed from the activity stack. Set from the
- * {@link android.R.attr#stateNotNeeded} attribute.
- */
- public static final int FLAG_STATE_NOT_NEEDED = 0x0010;
- /**
- * Bit in {@link #flags} that indicates that the activity should not
- * appear in the list of recently launched activities. Set from the
- * {@link android.R.attr#excludeFromRecents} attribute.
- */
- public static final int FLAG_EXCLUDE_FROM_RECENTS = 0x0020;
- /**
- * Bit in {@link #flags} that indicates that the activity can be moved
- * between tasks based on its task affinity. Set from the
- * {@link android.R.attr#allowTaskReparenting} attribute.
- */
- public static final int FLAG_ALLOW_TASK_REPARENTING = 0x0040;
- /**
- * Bit in {@link #flags} indicating that, when the user navigates away
- * from an activity, it should be finished.
- * Set from the
- * {@link android.R.attr#noHistory} attribute.
- */
- public static final int FLAG_NO_HISTORY = 0x0080;
- /**
- * Options that have been set in the activity declaration in the
- * manifest: {@link #FLAG_MULTIPROCESS},
- * {@link #FLAG_FINISH_ON_TASK_LAUNCH}, {@link #FLAG_CLEAR_TASK_ON_LAUNCH},
- * {@link #FLAG_ALWAYS_RETAIN_TASK_STATE},
- * {@link #FLAG_STATE_NOT_NEEDED}, {@link #FLAG_EXCLUDE_FROM_RECENTS},
- * {@link #FLAG_ALLOW_TASK_REPARENTING}, {@link #FLAG_NO_HISTORY}.
- */
- public int flags;
-
- /**
- * Constant corresponding to <code>unspecified</code> in
- * the {@link android.R.attr#screenOrientation} attribute.
- */
- public static final int SCREEN_ORIENTATION_UNSPECIFIED = -1;
- /**
- * Constant corresponding to <code>landscape</code> in
- * the {@link android.R.attr#screenOrientation} attribute.
- */
- public static final int SCREEN_ORIENTATION_LANDSCAPE = 0;
- /**
- * Constant corresponding to <code>portrait</code> in
- * the {@link android.R.attr#screenOrientation} attribute.
- */
- public static final int SCREEN_ORIENTATION_PORTRAIT = 1;
- /**
- * Constant corresponding to <code>user</code> in
- * the {@link android.R.attr#screenOrientation} attribute.
- */
- public static final int SCREEN_ORIENTATION_USER = 2;
- /**
- * Constant corresponding to <code>behind</code> in
- * the {@link android.R.attr#screenOrientation} attribute.
- */
- public static final int SCREEN_ORIENTATION_BEHIND = 3;
- /**
- * Constant corresponding to <code>sensor</code> in
- * the {@link android.R.attr#screenOrientation} attribute.
- */
- public static final int SCREEN_ORIENTATION_SENSOR = 4;
-
- /**
- * Constant corresponding to <code>sensor</code> in
- * the {@link android.R.attr#screenOrientation} attribute.
- */
- public static final int SCREEN_ORIENTATION_NOSENSOR = 5;
- /**
- * The preferred screen orientation this activity would like to run in.
- * From the {@link android.R.attr#screenOrientation} attribute, one of
- * {@link #SCREEN_ORIENTATION_UNSPECIFIED},
- * {@link #SCREEN_ORIENTATION_LANDSCAPE},
- * {@link #SCREEN_ORIENTATION_PORTRAIT},
- * {@link #SCREEN_ORIENTATION_USER},
- * {@link #SCREEN_ORIENTATION_BEHIND},
- * {@link #SCREEN_ORIENTATION_SENSOR},
- * {@link #SCREEN_ORIENTATION_NOSENSOR}.
- */
- public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
-
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the IMSI MCC. Set from the
- * {@link android.R.attr#configChanges} attribute.
- */
- public static final int CONFIG_MCC = 0x0001;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the IMSI MNC. Set from the
- * {@link android.R.attr#configChanges} attribute.
- */
- public static final int CONFIG_MNC = 0x0002;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the locale. Set from the
- * {@link android.R.attr#configChanges} attribute.
- */
- public static final int CONFIG_LOCALE = 0x0004;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the touchscreen type. Set from the
- * {@link android.R.attr#configChanges} attribute.
- */
- public static final int CONFIG_TOUCHSCREEN = 0x0008;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the keyboard type. Set from the
- * {@link android.R.attr#configChanges} attribute.
- */
- public static final int CONFIG_KEYBOARD = 0x0010;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the keyboard being hidden/exposed.
- * Set from the {@link android.R.attr#configChanges} attribute.
- */
- public static final int CONFIG_KEYBOARD_HIDDEN = 0x0020;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the navigation type. Set from the
- * {@link android.R.attr#configChanges} attribute.
- */
- public static final int CONFIG_NAVIGATION = 0x0040;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the screen orientation. Set from the
- * {@link android.R.attr#configChanges} attribute.
- */
- public static final int CONFIG_ORIENTATION = 0x0080;
- /**
- * Bit in {@link #configChanges} that indicates that the activity
- * can itself handle changes to the font scaling factor. Set from the
- * {@link android.R.attr#configChanges} attribute. This is
- * not a core resource configutation, but a higher-level value, so its
- * constant starts at the high bits.
- */
- public static final int CONFIG_FONT_SCALE = 0x40000000;
-
- /**
- * Bit mask of kinds of configuration changes that this activity
- * can handle itself (without being restarted by the system).
- * Contains any combination of {@link #CONFIG_FONT_SCALE},
- * {@link #CONFIG_MCC}, {@link #CONFIG_MNC},
- * {@link #CONFIG_LOCALE}, {@link #CONFIG_TOUCHSCREEN},
- * {@link #CONFIG_KEYBOARD}, {@link #CONFIG_NAVIGATION}, and
- * {@link #CONFIG_ORIENTATION}. Set from the
- * {@link android.R.attr#configChanges} attribute.
- */
- public int configChanges;
-
- /**
- * The desired soft input mode for this activity's main window.
- * Set from the {@link android.R.attr#windowSoftInputMode} attribute
- * in the activity's manifest. May be any of the same values allowed
- * for {@link android.view.WindowManager.LayoutParams#softInputMode
- * WindowManager.LayoutParams.softInputMode}. If 0 (unspecified),
- * the mode from the theme will be used.
- */
- public int softInputMode;
-
- public ActivityInfo() {
- }
-
- public ActivityInfo(ActivityInfo orig) {
- super(orig);
- theme = orig.theme;
- launchMode = orig.launchMode;
- permission = orig.permission;
- taskAffinity = orig.taskAffinity;
- targetActivity = orig.targetActivity;
- flags = orig.flags;
- screenOrientation = orig.screenOrientation;
- configChanges = orig.configChanges;
- softInputMode = orig.softInputMode;
- }
-
- /**
- * Return the theme resource identifier to use for this activity. If
- * the activity defines a theme, that is used; else, the application
- * theme is used.
- *
- * @return The theme associated with this activity.
- */
- public final int getThemeResource() {
- return theme != 0 ? theme : applicationInfo.theme;
- }
-
- public void dump(Printer pw, String prefix) {
- super.dumpFront(pw, prefix);
- pw.println(prefix + "permission=" + permission);
- pw.println(prefix + "taskAffinity=" + taskAffinity
- + " targetActivity=" + targetActivity);
- pw.println(prefix + "launchMode=" + launchMode
- + " flags=0x" + Integer.toHexString(flags)
- + " theme=0x" + Integer.toHexString(theme));
- pw.println(prefix + "screenOrientation=" + screenOrientation
- + " configChanges=0x" + Integer.toHexString(configChanges)
- + " softInputMode=0x" + Integer.toHexString(softInputMode));
- super.dumpBack(pw, prefix);
- }
-
- public String toString() {
- return "ActivityInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + name + "}";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- super.writeToParcel(dest, parcelableFlags);
- dest.writeInt(theme);
- dest.writeInt(launchMode);
- dest.writeString(permission);
- dest.writeString(taskAffinity);
- dest.writeString(targetActivity);
- dest.writeInt(flags);
- dest.writeInt(screenOrientation);
- dest.writeInt(configChanges);
- dest.writeInt(softInputMode);
- }
-
- public static final Parcelable.Creator<ActivityInfo> CREATOR
- = new Parcelable.Creator<ActivityInfo>() {
- public ActivityInfo createFromParcel(Parcel source) {
- return new ActivityInfo(source);
- }
- public ActivityInfo[] newArray(int size) {
- return new ActivityInfo[size];
- }
- };
-
- private ActivityInfo(Parcel source) {
- super(source);
- theme = source.readInt();
- launchMode = source.readInt();
- permission = source.readString();
- taskAffinity = source.readString();
- targetActivity = source.readString();
- flags = source.readInt();
- screenOrientation = source.readInt();
- configChanges = source.readInt();
- softInputMode = source.readInt();
- }
-}
diff --git a/core/java/android/content/pm/ApplicationInfo.aidl b/core/java/android/content/pm/ApplicationInfo.aidl
deleted file mode 100755
index 006d1bd..0000000
--- a/core/java/android/content/pm/ApplicationInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable ApplicationInfo;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
deleted file mode 100644
index 8d727ed..0000000
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ /dev/null
@@ -1,310 +0,0 @@
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.Printer;
-
-import java.text.Collator;
-import java.util.Comparator;
-
-/**
- * Information you can retrieve about a particular application. This
- * corresponds to information collected from the AndroidManifest.xml's
- * &lt;application&gt; tag.
- */
-public class ApplicationInfo extends PackageItemInfo implements Parcelable {
-
- /**
- * Default task affinity of all activities in this application. See
- * {@link ActivityInfo#taskAffinity} for more information. This comes
- * from the "taskAffinity" attribute.
- */
- public String taskAffinity;
-
- /**
- * Optional name of a permission required to be able to access this
- * application's components. From the "permission" attribute.
- */
- public String permission;
-
- /**
- * The name of the process this application should run in. From the
- * "process" attribute or, if not set, the same as
- * <var>packageName</var>.
- */
- public String processName;
-
- /**
- * Class implementing the Application object. From the "class"
- * attribute.
- */
- public String className;
-
- /**
- * A style resource identifier (in the package's resources) of the
- * description of an application. From the "description" attribute
- * or, if not set, 0.
- */
- public int descriptionRes;
-
- /**
- * A style resource identifier (in the package's resources) of the
- * default visual theme of the application. From the "theme" attribute
- * or, if not set, 0.
- */
- public int theme;
-
- /**
- * Class implementing the Application's manage space
- * functionality. From the "manageSpaceActivity"
- * attribute. This is an optional attribute and will be null if
- * application's dont specify it in their manifest
- */
- public String manageSpaceActivityName;
-
- /**
- * Value for {@link #flags}: if set, this application is installed in the
- * device's system image.
- */
- public static final int FLAG_SYSTEM = 1<<0;
-
- /**
- * Value for {@link #flags}: set to true if this application would like to
- * allow debugging of its
- * code, even when installed on a non-development system. Comes
- * from {@link android.R.styleable#AndroidManifestApplication_debuggable
- * android:debuggable} of the &lt;application&gt; tag.
- */
- public static final int FLAG_DEBUGGABLE = 1<<1;
-
- /**
- * Value for {@link #flags}: set to true if this application has code
- * associated with it. Comes
- * from {@link android.R.styleable#AndroidManifestApplication_hasCode
- * android:hasCode} of the &lt;application&gt; tag.
- */
- public static final int FLAG_HAS_CODE = 1<<2;
-
- /**
- * Value for {@link #flags}: set to true if this application is persistent.
- * Comes from {@link android.R.styleable#AndroidManifestApplication_persistent
- * android:persistent} of the &lt;application&gt; tag.
- */
- public static final int FLAG_PERSISTENT = 1<<3;
-
- /**
- * Value for {@link #flags}: set to true iif this application holds the
- * {@link android.Manifest.permission#FACTORY_TEST} permission and the
- * device is running in factory test mode.
- */
- public static final int FLAG_FACTORY_TEST = 1<<4;
-
- /**
- * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
- * Comes from {@link android.R.styleable#AndroidManifestApplication_allowTaskReparenting
- * android:allowTaskReparenting} of the &lt;application&gt; tag.
- */
- public static final int FLAG_ALLOW_TASK_REPARENTING = 1<<5;
-
- /**
- * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
- * Comes from {@link android.R.styleable#AndroidManifestApplication_allowClearUserData
- * android:allowClearUserData} of the &lt;application&gt; tag.
- */
- public static final int FLAG_ALLOW_CLEAR_USER_DATA = 1<<6;
-
-
- /**
- * Value for {@link #flags}: default value for the corresponding ActivityInfo flag.
- * {@hide}
- */
- public static final int FLAG_UPDATED_SYSTEM_APP = 1<<7;
-
- /**
- * Flags associated with the application. Any combination of
- * {@link #FLAG_SYSTEM}, {@link #FLAG_DEBUGGABLE}, {@link #FLAG_HAS_CODE},
- * {@link #FLAG_PERSISTENT}, {@link #FLAG_FACTORY_TEST}, and
- * {@link #FLAG_ALLOW_TASK_REPARENTING}
- * {@link #FLAG_ALLOW_CLEAR_USER_DATA}.
- */
- public int flags = 0;
-
- /**
- * Full path to the location of this package.
- */
- public String sourceDir;
-
- /**
- * Full path to the location of the publicly available parts of this package (i.e. the resources
- * and manifest). For non-forward-locked apps this will be the same as {@link #sourceDir).
- */
- public String publicSourceDir;
-
- /**
- * Paths to all shared libraries this application is linked against. This
- * field is only set if the {@link PackageManager#GET_SHARED_LIBRARY_FILES
- * PackageManager.GET_SHARED_LIBRARY_FILES} flag was used when retrieving
- * the structure.
- */
- public String[] sharedLibraryFiles;
-
- /**
- * Full path to a directory assigned to the package for its persistent
- * data.
- */
- public String dataDir;
-
- /**
- * The kernel user-ID that has been assigned to this application;
- * currently this is not a unique ID (multiple applications can have
- * the same uid).
- */
- public int uid;
-
- /**
- * When false, indicates that all components within this application are
- * considered disabled, regardless of their individually set enabled status.
- */
- public boolean enabled = true;
-
- public void dump(Printer pw, String prefix) {
- super.dumpFront(pw, prefix);
- pw.println(prefix + "className=" + className);
- pw.println(prefix + "permission=" + permission
- + " uid=" + uid);
- pw.println(prefix + "taskAffinity=" + taskAffinity);
- pw.println(prefix + "theme=0x" + Integer.toHexString(theme));
- pw.println(prefix + "flags=0x" + Integer.toHexString(flags)
- + " processName=" + processName);
- pw.println(prefix + "sourceDir=" + sourceDir);
- pw.println(prefix + "publicSourceDir=" + publicSourceDir);
- pw.println(prefix + "sharedLibraryFiles=" + sharedLibraryFiles);
- pw.println(prefix + "dataDir=" + dataDir);
- pw.println(prefix + "enabled=" + enabled);
- pw.println(prefix+"manageSpaceActivityName="+manageSpaceActivityName);
- pw.println(prefix+"description=0x"+Integer.toHexString(descriptionRes));
- super.dumpBack(pw, prefix);
- }
-
- public static class DisplayNameComparator
- implements Comparator<ApplicationInfo> {
- public DisplayNameComparator(PackageManager pm) {
- mPM = pm;
- }
-
- public final int compare(ApplicationInfo aa, ApplicationInfo ab) {
- CharSequence sa = mPM.getApplicationLabel(aa);
- if (sa == null) {
- sa = aa.packageName;
- }
- CharSequence sb = mPM.getApplicationLabel(ab);
- if (sb == null) {
- sb = ab.packageName;
- }
-
- return sCollator.compare(sa.toString(), sb.toString());
- }
-
- private final Collator sCollator = Collator.getInstance();
- private PackageManager mPM;
- }
-
- public ApplicationInfo() {
- }
-
- public ApplicationInfo(ApplicationInfo orig) {
- super(orig);
- taskAffinity = orig.taskAffinity;
- permission = orig.permission;
- processName = orig.processName;
- className = orig.className;
- theme = orig.theme;
- flags = orig.flags;
- sourceDir = orig.sourceDir;
- publicSourceDir = orig.publicSourceDir;
- sharedLibraryFiles = orig.sharedLibraryFiles;
- dataDir = orig.dataDir;
- uid = orig.uid;
- enabled = orig.enabled;
- manageSpaceActivityName = orig.manageSpaceActivityName;
- descriptionRes = orig.descriptionRes;
- }
-
-
- public String toString() {
- return "ApplicationInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + packageName + "}";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- super.writeToParcel(dest, parcelableFlags);
- dest.writeString(taskAffinity);
- dest.writeString(permission);
- dest.writeString(processName);
- dest.writeString(className);
- dest.writeInt(theme);
- dest.writeInt(flags);
- dest.writeString(sourceDir);
- dest.writeString(publicSourceDir);
- dest.writeStringArray(sharedLibraryFiles);
- dest.writeString(dataDir);
- dest.writeInt(uid);
- dest.writeInt(enabled ? 1 : 0);
- dest.writeString(manageSpaceActivityName);
- dest.writeInt(descriptionRes);
- }
-
- public static final Parcelable.Creator<ApplicationInfo> CREATOR
- = new Parcelable.Creator<ApplicationInfo>() {
- public ApplicationInfo createFromParcel(Parcel source) {
- return new ApplicationInfo(source);
- }
- public ApplicationInfo[] newArray(int size) {
- return new ApplicationInfo[size];
- }
- };
-
- private ApplicationInfo(Parcel source) {
- super(source);
- taskAffinity = source.readString();
- permission = source.readString();
- processName = source.readString();
- className = source.readString();
- theme = source.readInt();
- flags = source.readInt();
- sourceDir = source.readString();
- publicSourceDir = source.readString();
- sharedLibraryFiles = source.readStringArray();
- dataDir = source.readString();
- uid = source.readInt();
- enabled = source.readInt() != 0;
- manageSpaceActivityName = source.readString();
- descriptionRes = source.readInt();
- }
-
- /**
- * Retrieve the textual description of the application. This
- * will call back on the given PackageManager to load the description from
- * the application.
- *
- * @param pm A PackageManager from which the label can be loaded; usually
- * the PackageManager from which you originally retrieved this item.
- *
- * @return Returns a CharSequence containing the application's description.
- * If there is no description, null is returned.
- */
- public CharSequence loadDescription(PackageManager pm) {
- if (descriptionRes != 0) {
- CharSequence label = pm.getText(packageName, descriptionRes, null);
- if (label != null) {
- return label;
- }
- }
- return null;
- }
-}
diff --git a/core/java/android/content/pm/ComponentInfo.java b/core/java/android/content/pm/ComponentInfo.java
deleted file mode 100644
index 73c9244..0000000
--- a/core/java/android/content/pm/ComponentInfo.java
+++ /dev/null
@@ -1,138 +0,0 @@
-package android.content.pm;
-
-import android.graphics.drawable.Drawable;
-import android.os.Parcel;
-import android.util.Printer;
-
-/**
- * Base class containing information common to all application components
- * ({@link ActivityInfo}, {@link ServiceInfo}). This class is not intended
- * to be used by itself; it is simply here to share common definitions
- * between all application components. As such, it does not itself
- * implement Parcelable, but does provide convenience methods to assist
- * in the implementation of Parcelable in subclasses.
- */
-public class ComponentInfo extends PackageItemInfo {
- /**
- * Global information about the application/package this component is a
- * part of.
- */
- public ApplicationInfo applicationInfo;
-
- /**
- * The name of the process this component should run in.
- * From the "android:process" attribute or, if not set, the same
- * as <var>applicationInfo.processName</var>.
- */
- public String processName;
-
- /**
- * Indicates whether or not this component may be instantiated. Note that this value can be
- * overriden by the one in its parent {@link ApplicationInfo}.
- */
- public boolean enabled = true;
-
- /**
- * Set to true if this component is available for use by other applications.
- * Comes from {@link android.R.attr#exported android:exported} of the
- * &lt;activity&gt;, &lt;receiver&gt;, &lt;service&gt;, or
- * &lt;provider&gt; tag.
- */
- public boolean exported = false;
-
- public ComponentInfo() {
- }
-
- public ComponentInfo(ComponentInfo orig) {
- super(orig);
- applicationInfo = orig.applicationInfo;
- processName = orig.processName;
- enabled = orig.enabled;
- exported = orig.exported;
- }
-
- @Override public CharSequence loadLabel(PackageManager pm) {
- if (nonLocalizedLabel != null) {
- return nonLocalizedLabel;
- }
- ApplicationInfo ai = applicationInfo;
- CharSequence label;
- if (labelRes != 0) {
- label = pm.getText(packageName, labelRes, ai);
- if (label != null) {
- return label;
- }
- }
- if (ai.nonLocalizedLabel != null) {
- return ai.nonLocalizedLabel;
- }
- if (ai.labelRes != 0) {
- label = pm.getText(packageName, ai.labelRes, ai);
- if (label != null) {
- return label;
- }
- }
- return name;
- }
-
- @Override public Drawable loadIcon(PackageManager pm) {
- ApplicationInfo ai = applicationInfo;
- Drawable dr;
- if (icon != 0) {
- dr = pm.getDrawable(packageName, icon, ai);
- if (dr != null) {
- return dr;
- }
- }
- if (ai.icon != 0) {
- dr = pm.getDrawable(packageName, ai.icon, ai);
- if (dr != null) {
- return dr;
- }
- }
- return pm.getDefaultActivityIcon();
- }
-
- /**
- * Return the icon resource identifier to use for this component. If
- * the component defines an icon, that is used; else, the application
- * icon is used.
- *
- * @return The icon associated with this component.
- */
- public final int getIconResource() {
- return icon != 0 ? icon : applicationInfo.icon;
- }
-
- protected void dumpFront(Printer pw, String prefix) {
- super.dumpFront(pw, prefix);
- pw.println(prefix + "enabled=" + enabled + " exported=" + exported
- + " processName=" + processName);
- }
-
- protected void dumpBack(Printer pw, String prefix) {
- if (applicationInfo != null) {
- pw.println(prefix + "ApplicationInfo:");
- applicationInfo.dump(pw, prefix + " ");
- } else {
- pw.println(prefix + "ApplicationInfo: null");
- }
- super.dumpBack(pw, prefix);
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- super.writeToParcel(dest, parcelableFlags);
- applicationInfo.writeToParcel(dest, parcelableFlags);
- dest.writeString(processName);
- dest.writeInt(enabled ? 1 : 0);
- dest.writeInt(exported ? 1 : 0);
- }
-
- protected ComponentInfo(Parcel source) {
- super(source);
- applicationInfo = ApplicationInfo.CREATOR.createFromParcel(source);
- processName = source.readString();
- enabled = (source.readInt() != 0);
- exported = (source.readInt() != 0);
- }
-}
diff --git a/core/java/android/content/pm/ConfigurationInfo.java b/core/java/android/content/pm/ConfigurationInfo.java
deleted file mode 100755
index dcc7463..0000000
--- a/core/java/android/content/pm/ConfigurationInfo.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Information you can retrieve about hardware configuration preferences
- * declared by an application. This corresponds to information collected from the
- * AndroidManifest.xml's &lt;uses-configuration&gt; tags.
- */
-public class ConfigurationInfo implements Parcelable {
- /**
- * The kind of touch screen attached to the device.
- * One of: {@link android.content.res.Configuration#TOUCHSCREEN_NOTOUCH},
- * {@link android.content.res.Configuration#TOUCHSCREEN_STYLUS},
- * {@link android.content.res.Configuration#TOUCHSCREEN_FINGER}.
- */
- public int reqTouchScreen;
-
- /**
- * Application's input method preference.
- * One of: {@link android.content.res.Configuration#KEYBOARD_UNDEFINED},
- * {@link android.content.res.Configuration#KEYBOARD_NOKEYS},
- * {@link android.content.res.Configuration#KEYBOARD_QWERTY},
- * {@link android.content.res.Configuration#KEYBOARD_12KEY}
- */
- public int reqKeyboardType;
-
- /**
- * A flag indicating whether any keyboard is available.
- * one of: {@link android.content.res.Configuration#NAVIGATION_UNDEFINED},
- * {@link android.content.res.Configuration#NAVIGATION_DPAD},
- * {@link android.content.res.Configuration#NAVIGATION_TRACKBALL},
- * {@link android.content.res.Configuration#NAVIGATION_WHEEL}
- */
- public int reqNavigation;
-
- /**
- * Value for {@link #reqInputFeatures}: if set, indicates that the application
- * requires a hard keyboard
- */
- public static final int INPUT_FEATURE_HARD_KEYBOARD = 0x00000001;
-
- /**
- * Value for {@link #reqInputFeatures}: if set, indicates that the application
- * requires a five way navigation device
- */
- public static final int INPUT_FEATURE_FIVE_WAY_NAV = 0x00000002;
-
- /**
- * Flags associated with the input features. Any combination of
- * {@link #INPUT_FEATURE_HARD_KEYBOARD},
- * {@link #INPUT_FEATURE_FIVE_WAY_NAV}
- */
- public int reqInputFeatures = 0;
-
- public ConfigurationInfo() {
- }
-
- public ConfigurationInfo(ConfigurationInfo orig) {
- reqTouchScreen = orig.reqTouchScreen;
- reqKeyboardType = orig.reqKeyboardType;
- reqNavigation = orig.reqNavigation;
- reqInputFeatures = orig.reqInputFeatures;
- }
-
- public String toString() {
- return "ApplicationHardwarePreferences{"
- + Integer.toHexString(System.identityHashCode(this))
- + ", touchscreen = " + reqTouchScreen + "}"
- + ", inputMethod = " + reqKeyboardType + "}"
- + ", navigation = " + reqNavigation + "}"
- + ", reqInputFeatures = " + reqInputFeatures + "}";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- dest.writeInt(reqTouchScreen);
- dest.writeInt(reqKeyboardType);
- dest.writeInt(reqNavigation);
- dest.writeInt(reqInputFeatures);
- }
-
- public static final Creator<ConfigurationInfo> CREATOR =
- new Creator<ConfigurationInfo>() {
- public ConfigurationInfo createFromParcel(Parcel source) {
- return new ConfigurationInfo(source);
- }
- public ConfigurationInfo[] newArray(int size) {
- return new ConfigurationInfo[size];
- }
- };
-
- private ConfigurationInfo(Parcel source) {
- reqTouchScreen = source.readInt();
- reqKeyboardType = source.readInt();
- reqNavigation = source.readInt();
- reqInputFeatures = source.readInt();
- }
-}
diff --git a/core/java/android/content/pm/IPackageDataObserver.aidl b/core/java/android/content/pm/IPackageDataObserver.aidl
deleted file mode 100755
index d010ee4..0000000
--- a/core/java/android/content/pm/IPackageDataObserver.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-/**
- * API for package data change related callbacks from the Package Manager.
- * Some usage scenarios include deletion of cache directory, generate
- * statistics related to code, data, cache usage(TODO)
- * {@hide}
- */
-oneway interface IPackageDataObserver {
- void onRemoveCompleted(in String packageName, boolean succeeded);
-}
diff --git a/core/java/android/content/pm/IPackageDeleteObserver.aidl b/core/java/android/content/pm/IPackageDeleteObserver.aidl
deleted file mode 100644
index bc16b3e..0000000
--- a/core/java/android/content/pm/IPackageDeleteObserver.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-/**
- * API for deletion callbacks from the Package Manager.
- *
- * {@hide}
- */
-oneway interface IPackageDeleteObserver {
- void packageDeleted(in boolean succeeded);
-}
-
diff --git a/core/java/android/content/pm/IPackageInstallObserver.aidl b/core/java/android/content/pm/IPackageInstallObserver.aidl
deleted file mode 100644
index e83bbc6..0000000
--- a/core/java/android/content/pm/IPackageInstallObserver.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-/**
- * API for installation callbacks from the Package Manager.
- *
- */
-oneway interface IPackageInstallObserver {
- void packageInstalled(in String packageName, int returnCode);
-}
-
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
deleted file mode 100644
index d3f6f3c..0000000
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageInstallObserver;
-import android.content.pm.IPackageDeleteObserver;
-import android.content.pm.IPackageDataObserver;
-import android.content.pm.IPackageStatsObserver;
-import android.content.pm.InstrumentationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.ProviderInfo;
-import android.content.pm.PermissionGroupInfo;
-import android.content.pm.PermissionInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
-import android.net.Uri;
-import android.app.PendingIntent;
-
-/**
- * See {@link PackageManager} for documentation on most of the APIs
- * here.
- *
- * {@hide}
- */
-interface IPackageManager {
- PackageInfo getPackageInfo(String packageName, int flags);
- int getPackageUid(String packageName);
- int[] getPackageGids(String packageName);
-
- PermissionInfo getPermissionInfo(String name, int flags);
-
- List<PermissionInfo> queryPermissionsByGroup(String group, int flags);
-
- PermissionGroupInfo getPermissionGroupInfo(String name, int flags);
-
- List<PermissionGroupInfo> getAllPermissionGroups(int flags);
-
- ApplicationInfo getApplicationInfo(String packageName, int flags);
-
- ActivityInfo getActivityInfo(in ComponentName className, int flags);
-
- ActivityInfo getReceiverInfo(in ComponentName className, int flags);
-
- ServiceInfo getServiceInfo(in ComponentName className, int flags);
-
- int checkPermission(String permName, String pkgName);
-
- int checkUidPermission(String permName, int uid);
-
- boolean addPermission(in PermissionInfo info);
-
- void removePermission(String name);
-
- int checkSignatures(String pkg1, String pkg2);
-
- String[] getPackagesForUid(int uid);
-
- String getNameForUid(int uid);
-
- int getUidForSharedUser(String sharedUserName);
-
- ResolveInfo resolveIntent(in Intent intent, String resolvedType, int flags);
-
- List<ResolveInfo> queryIntentActivities(in Intent intent,
- String resolvedType, int flags);
-
- List<ResolveInfo> queryIntentActivityOptions(
- in ComponentName caller, in Intent[] specifics,
- in String[] specificTypes, in Intent intent,
- String resolvedType, int flags);
-
- List<ResolveInfo> queryIntentReceivers(in Intent intent,
- String resolvedType, int flags);
-
- ResolveInfo resolveService(in Intent intent,
- String resolvedType, int flags);
-
- List<ResolveInfo> queryIntentServices(in Intent intent,
- String resolvedType, int flags);
-
- List<PackageInfo> getInstalledPackages(int flags);
-
- List<ApplicationInfo> getInstalledApplications(int flags);
-
- /**
- * Retrieve all applications that are marked as persistent.
- *
- * @return A List&lt;applicationInfo> containing one entry for each persistent
- * application.
- */
- List<ApplicationInfo> getPersistentApplications(int flags);
-
- ProviderInfo resolveContentProvider(String name, int flags);
-
- /**
- * Retrieve sync information for all content providers.
- *
- * @param outNames Filled in with a list of the root names of the content
- * providers that can sync.
- * @param outInfo Filled in with a list of the ProviderInfo for each
- * name in 'outNames'.
- */
- void querySyncProviders(inout List<String> outNames,
- inout List<ProviderInfo> outInfo);
-
- List<ProviderInfo> queryContentProviders(
- String processName, int uid, int flags);
-
- InstrumentationInfo getInstrumentationInfo(
- in ComponentName className, int flags);
-
- List<InstrumentationInfo> queryInstrumentation(
- String targetPackage, int flags);
-
- /**
- * Install a package.
- *
- * @param packageURI The location of the package file to install.
- * @param observer a callback to use to notify when the package installation in finished.
- * @param flags - possible values: {@link #FORWARD_LOCK_PACKAGE},
- * {@link #REPLACE_EXISITING_PACKAGE}
- */
- void installPackage(in Uri packageURI, IPackageInstallObserver observer, int flags);
-
- /**
- * Delete a package.
- *
- * @param packageName The fully qualified name of the package to delete.
- * @param observer a callback to use to notify when the package deletion in finished.
- * @param flags - possible values: {@link #DONT_DELETE_DATA}
- */
- void deletePackage(in String packageName, IPackageDeleteObserver observer, int flags);
-
- void addPackageToPreferred(String packageName);
-
- void removePackageFromPreferred(String packageName);
-
- List<PackageInfo> getPreferredPackages(int flags);
-
- void addPreferredActivity(in IntentFilter filter, int match,
- in ComponentName[] set, in ComponentName activity);
- void clearPackagePreferredActivities(String packageName);
- int getPreferredActivities(out List<IntentFilter> outFilters,
- out List<ComponentName> outActivities, String packageName);
-
- /**
- * As per {@link android.content.pm.PackageManager#setComponentEnabledSetting}.
- */
- void setComponentEnabledSetting(in ComponentName componentName,
- in int newState, in int flags);
-
- /**
- * As per {@link android.content.pm.PackageManager#getComponentEnabledSetting}.
- */
- int getComponentEnabledSetting(in ComponentName componentName);
-
- /**
- * As per {@link android.content.pm.PackageManager#setApplicationEnabledSetting}.
- */
- void setApplicationEnabledSetting(in String packageName, in int newState, int flags);
-
- /**
- * As per {@link android.content.pm.PackageManager#getApplicationEnabledSetting}.
- */
- int getApplicationEnabledSetting(in String packageName);
-
- /**
- * Free storage by deleting LRU sorted list of cache files across
- * all applications. If the currently available free storage
- * on the device is greater than or equal to the requested
- * free storage, no cache files are cleared. If the currently
- * available storage on the device is less than the requested
- * free storage, some or all of the cache files across
- * all applications are deleted (based on last accessed time)
- * to increase the free storage space on the device to
- * the requested value. There is no guarantee that clearing all
- * the cache files from all applications will clear up
- * enough storage to achieve the desired value.
- * @param freeStorageSize The number of bytes of storage to be
- * freed by the system. Say if freeStorageSize is XX,
- * and the current free storage is YY,
- * if XX is less than YY, just return. if not free XX-YY number
- * of bytes if possible.
- * @param observer call back used to notify when
- * the operation is completed
- */
- void freeStorageAndNotify(in long freeStorageSize,
- IPackageDataObserver observer);
-
- /**
- * Free storage by deleting LRU sorted list of cache files across
- * all applications. If the currently available free storage
- * on the device is greater than or equal to the requested
- * free storage, no cache files are cleared. If the currently
- * available storage on the device is less than the requested
- * free storage, some or all of the cache files across
- * all applications are deleted (based on last accessed time)
- * to increase the free storage space on the device to
- * the requested value. There is no guarantee that clearing all
- * the cache files from all applications will clear up
- * enough storage to achieve the desired value.
- * @param freeStorageSize The number of bytes of storage to be
- * freed by the system. Say if freeStorageSize is XX,
- * and the current free storage is YY,
- * if XX is less than YY, just return. if not free XX-YY number
- * of bytes if possible.
- * @param opFinishedIntent PendingIntent call back used to
- * notify when the operation is completed.May be null
- * to indicate that no call back is desired.
- */
- void freeStorage(in long freeStorageSize,
- in PendingIntent opFinishedIntent);
-
- /**
- * Delete all the cache files in an applications cache directory
- * @param packageName The package name of the application whose cache
- * files need to be deleted
- * @param observer a callback used to notify when the deletion is finished.
- */
- void deleteApplicationCacheFiles(in String packageName, IPackageDataObserver observer);
-
- /**
- * Clear the user data directory of an application.
- * @param packageName The package name of the application whose cache
- * files need to be deleted
- * @param observer a callback used to notify when the operation is completed.
- */
- void clearApplicationUserData(in String packageName, IPackageDataObserver observer);
-
- /**
- * Get package statistics including the code, data and cache size for
- * an already installed package
- * @param packageName The package name of the application
- * @param observer a callback to use to notify when the asynchronous
- * retrieval of information is complete.
- */
- void getPackageSizeInfo(in String packageName, IPackageStatsObserver observer);
-
- /**
- * Get a list of shared libraries that are available on the
- * system.
- */
- String[] getSystemSharedLibraryNames();
-
- void enterSafeMode();
- boolean isSafeMode();
- void systemReady();
- boolean hasSystemUidErrors();
-}
diff --git a/core/java/android/content/pm/IPackageStatsObserver.aidl b/core/java/android/content/pm/IPackageStatsObserver.aidl
deleted file mode 100755
index ede4d1d..0000000
--- a/core/java/android/content/pm/IPackageStatsObserver.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-import android.content.pm.PackageStats;
-/**
- * API for package data change related callbacks from the Package Manager.
- * Some usage scenarios include deletion of cache directory, generate
- * statistics related to code, data, cache usage(TODO)
- * {@hide}
- */
-oneway interface IPackageStatsObserver {
-
- void onGetStatsCompleted(in PackageStats pStats, boolean succeeded);
-}
diff --git a/core/java/android/content/pm/InstrumentationInfo.aidl b/core/java/android/content/pm/InstrumentationInfo.aidl
deleted file mode 100755
index 3d847ae..0000000
--- a/core/java/android/content/pm/InstrumentationInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable InstrumentationInfo;
diff --git a/core/java/android/content/pm/InstrumentationInfo.java b/core/java/android/content/pm/InstrumentationInfo.java
deleted file mode 100644
index 30ca002..0000000
--- a/core/java/android/content/pm/InstrumentationInfo.java
+++ /dev/null
@@ -1,98 +0,0 @@
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.text.Collator;
-import java.util.Comparator;
-
-/**
- * Information you can retrieve about a particular piece of test
- * instrumentation. This corresponds to information collected
- * from the AndroidManifest.xml's &lt;instrumentation&gt; tag.
- */
-public class InstrumentationInfo extends PackageItemInfo implements Parcelable {
- /**
- * The name of the application package being instrumented. From the
- * "package" attribute.
- */
- public String targetPackage;
-
- /**
- * Full path to the location of this package.
- */
- public String sourceDir;
-
- /**
- * Full path to the location of the publicly available parts of this package (i.e. the resources
- * and manifest). For non-forward-locked apps this will be the same as {@link #sourceDir).
- */
- public String publicSourceDir;
- /**
- * Full path to a directory assigned to the package for its persistent
- * data.
- */
- public String dataDir;
-
- /**
- * Specifies whether or not this instrumentation will handle profiling.
- */
- public boolean handleProfiling;
-
- /** Specifies whether or not to run this instrumentation as a functional test */
- public boolean functionalTest;
-
- public InstrumentationInfo() {
- }
-
- public InstrumentationInfo(InstrumentationInfo orig) {
- super(orig);
- targetPackage = orig.targetPackage;
- sourceDir = orig.sourceDir;
- publicSourceDir = orig.publicSourceDir;
- dataDir = orig.dataDir;
- handleProfiling = orig.handleProfiling;
- functionalTest = orig.functionalTest;
- }
-
- public String toString() {
- return "InstrumentationInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + packageName + "}";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- super.writeToParcel(dest, parcelableFlags);
- dest.writeString(targetPackage);
- dest.writeString(sourceDir);
- dest.writeString(publicSourceDir);
- dest.writeString(dataDir);
- dest.writeInt((handleProfiling == false) ? 0 : 1);
- dest.writeInt((functionalTest == false) ? 0 : 1);
- }
-
- public static final Parcelable.Creator<InstrumentationInfo> CREATOR
- = new Parcelable.Creator<InstrumentationInfo>() {
- public InstrumentationInfo createFromParcel(Parcel source) {
- return new InstrumentationInfo(source);
- }
- public InstrumentationInfo[] newArray(int size) {
- return new InstrumentationInfo[size];
- }
- };
-
- private InstrumentationInfo(Parcel source) {
- super(source);
- targetPackage = source.readString();
- sourceDir = source.readString();
- publicSourceDir = source.readString();
- dataDir = source.readString();
- handleProfiling = source.readInt() != 0;
- functionalTest = source.readInt() != 0;
- }
-}
diff --git a/core/java/android/content/pm/PackageInfo.aidl b/core/java/android/content/pm/PackageInfo.aidl
deleted file mode 100755
index 35e2322..0000000
--- a/core/java/android/content/pm/PackageInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable PackageInfo;
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
deleted file mode 100644
index d9326f2..0000000
--- a/core/java/android/content/pm/PackageInfo.java
+++ /dev/null
@@ -1,199 +0,0 @@
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Overall information about the contents of a package. This corresponds
- * to all of the information collected from AndroidManifest.xml.
- */
-public class PackageInfo implements Parcelable {
- /**
- * The name of this package. From the &lt;manifest&gt; tag's "name"
- * attribute.
- */
- public String packageName;
-
- /**
- * The version number of this package, as specified by the &lt;manifest&gt;
- * tag's {@link android.R.styleable#AndroidManifest_versionCode versionCode}
- * attribute.
- */
- public int versionCode;
-
- /**
- * The version name of this package, as specified by the &lt;manifest&gt;
- * tag's {@link android.R.styleable#AndroidManifest_versionName versionName}
- * attribute.
- */
- public String versionName;
-
- /**
- * The shared user ID name of this package, as specified by the &lt;manifest&gt;
- * tag's {@link android.R.styleable#AndroidManifest_sharedUserId sharedUserId}
- * attribute.
- */
- public String sharedUserId;
-
- /**
- * The shared user ID label of this package, as specified by the &lt;manifest&gt;
- * tag's {@link android.R.styleable#AndroidManifest_sharedUserLabel sharedUserLabel}
- * attribute.
- */
- public int sharedUserLabel;
-
- /**
- * Information collected from the &lt;application&gt; tag, or null if
- * there was none.
- */
- public ApplicationInfo applicationInfo;
-
- /**
- * All kernel group-IDs that have been assigned to this package.
- * This is only filled in if the flag {@link PackageManager#GET_GIDS} was set.
- */
- public int[] gids;
-
- /**
- * Array of all {@link android.R.styleable#AndroidManifestActivity
- * &lt;activity&gt;} tags included under &lt;application&gt;,
- * or null if there were none. This is only filled in if the flag
- * {@link PackageManager#GET_ACTIVITIES} was set.
- */
- public ActivityInfo[] activities;
-
- /**
- * Array of all {@link android.R.styleable#AndroidManifestReceiver
- * &lt;receiver&gt;} tags included under &lt;application&gt;,
- * or null if there were none. This is only filled in if the flag
- * {@link PackageManager#GET_RECEIVERS} was set.
- */
- public ActivityInfo[] receivers;
-
- /**
- * Array of all {@link android.R.styleable#AndroidManifestService
- * &lt;service&gt;} tags included under &lt;application&gt;,
- * or null if there were none. This is only filled in if the flag
- * {@link PackageManager#GET_SERVICES} was set.
- */
- public ServiceInfo[] services;
-
- /**
- * Array of all {@link android.R.styleable#AndroidManifestProvider
- * &lt;provider&gt;} tags included under &lt;application&gt;,
- * or null if there were none. This is only filled in if the flag
- * {@link PackageManager#GET_PROVIDERS} was set.
- */
- public ProviderInfo[] providers;
-
- /**
- * Array of all {@link android.R.styleable#AndroidManifestInstrumentation
- * &lt;instrumentation&gt;} tags included under &lt;manifest&gt;,
- * or null if there were none. This is only filled in if the flag
- * {@link PackageManager#GET_INSTRUMENTATION} was set.
- */
- public InstrumentationInfo[] instrumentation;
-
- /**
- * Array of all {@link android.R.styleable#AndroidManifestPermission
- * &lt;permission&gt;} tags included under &lt;manifest&gt;,
- * or null if there were none. This is only filled in if the flag
- * {@link PackageManager#GET_PERMISSIONS} was set.
- */
- public PermissionInfo[] permissions;
-
- /**
- * Array of all {@link android.R.styleable#AndroidManifestUsesPermission
- * &lt;uses-permission&gt;} tags included under &lt;manifest&gt;,
- * or null if there were none. This is only filled in if the flag
- * {@link PackageManager#GET_PERMISSIONS} was set. This list includes
- * all permissions requested, even those that were not granted or known
- * by the system at install time.
- */
- public String[] requestedPermissions;
-
- /**
- * Array of all signatures read from the package file. This is only filled
- * in if the flag {@link PackageManager#GET_SIGNATURES} was set.
- */
- public Signature[] signatures;
-
- /**
- * Application specified preferred configuration
- * {@link android.R.styleable#AndroidManifestUsesConfiguration
- * &lt;uses-configuration&gt;} tags included under &lt;manifest&gt;,
- * or null if there were none. This is only filled in if the flag
- * {@link PackageManager#GET_CONFIGURATIONS} was set.
- */
- public ConfigurationInfo[] configPreferences;
-
- public PackageInfo() {
- }
-
- public String toString() {
- return "PackageInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + packageName + "}";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- dest.writeString(packageName);
- dest.writeInt(versionCode);
- dest.writeString(versionName);
- dest.writeString(sharedUserId);
- dest.writeInt(sharedUserLabel);
- if (applicationInfo != null) {
- dest.writeInt(1);
- applicationInfo.writeToParcel(dest, parcelableFlags);
- } else {
- dest.writeInt(0);
- }
- dest.writeIntArray(gids);
- dest.writeTypedArray(activities, parcelableFlags);
- dest.writeTypedArray(receivers, parcelableFlags);
- dest.writeTypedArray(services, parcelableFlags);
- dest.writeTypedArray(providers, parcelableFlags);
- dest.writeTypedArray(instrumentation, parcelableFlags);
- dest.writeTypedArray(permissions, parcelableFlags);
- dest.writeStringArray(requestedPermissions);
- dest.writeTypedArray(signatures, parcelableFlags);
- dest.writeTypedArray(configPreferences, parcelableFlags);
- }
-
- public static final Parcelable.Creator<PackageInfo> CREATOR
- = new Parcelable.Creator<PackageInfo>() {
- public PackageInfo createFromParcel(Parcel source) {
- return new PackageInfo(source);
- }
-
- public PackageInfo[] newArray(int size) {
- return new PackageInfo[size];
- }
- };
-
- private PackageInfo(Parcel source) {
- packageName = source.readString();
- versionCode = source.readInt();
- versionName = source.readString();
- sharedUserId = source.readString();
- sharedUserLabel = source.readInt();
- int hasApp = source.readInt();
- if (hasApp != 0) {
- applicationInfo = ApplicationInfo.CREATOR.createFromParcel(source);
- }
- gids = source.createIntArray();
- activities = source.createTypedArray(ActivityInfo.CREATOR);
- receivers = source.createTypedArray(ActivityInfo.CREATOR);
- services = source.createTypedArray(ServiceInfo.CREATOR);
- providers = source.createTypedArray(ProviderInfo.CREATOR);
- instrumentation = source.createTypedArray(InstrumentationInfo.CREATOR);
- permissions = source.createTypedArray(PermissionInfo.CREATOR);
- requestedPermissions = source.createStringArray();
- signatures = source.createTypedArray(Signature.CREATOR);
- configPreferences = source.createTypedArray(ConfigurationInfo.CREATOR);
- }
-}
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
deleted file mode 100644
index 46e7ca4..0000000
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ /dev/null
@@ -1,191 +0,0 @@
-package android.content.pm;
-
-import android.content.res.XmlResourceParser;
-
-import android.graphics.drawable.Drawable;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.text.TextUtils;
-import android.util.Printer;
-
-import java.text.Collator;
-import java.util.Comparator;
-
-/**
- * Base class containing information common to all package items held by
- * the package manager. This provides a very common basic set of attributes:
- * a label, icon, and meta-data. This class is not intended
- * to be used by itself; it is simply here to share common definitions
- * between all items returned by the package manager. As such, it does not
- * itself implement Parcelable, but does provide convenience methods to assist
- * in the implementation of Parcelable in subclasses.
- */
-public class PackageItemInfo {
- /**
- * Public name of this item. From the "android:name" attribute.
- */
- public String name;
-
- /**
- * Name of the package that this item is in.
- */
- public String packageName;
-
- /**
- * A string resource identifier (in the package's resources) of this
- * component's label. From the "label" attribute or, if not set, 0.
- */
- public int labelRes;
-
- /**
- * The string provided in the AndroidManifest file, if any. You
- * probably don't want to use this. You probably want
- * {@link PackageManager#getApplicationLabel}
- */
- public CharSequence nonLocalizedLabel;
-
- /**
- * A drawable resource identifier (in the package's resources) of this
- * component's icon. From the "icon" attribute or, if not set, 0.
- */
- public int icon;
-
- /**
- * Additional meta-data associated with this component. This field
- * will only be filled in if you set the
- * {@link PackageManager#GET_META_DATA} flag when requesting the info.
- */
- public Bundle metaData;
-
- public PackageItemInfo() {
- }
-
- public PackageItemInfo(PackageItemInfo orig) {
- name = orig.name;
- packageName = orig.packageName;
- labelRes = orig.labelRes;
- nonLocalizedLabel = orig.nonLocalizedLabel;
- icon = orig.icon;
- metaData = orig.metaData;
- }
-
- /**
- * Retrieve the current textual label associated with this item. This
- * will call back on the given PackageManager to load the label from
- * the application.
- *
- * @param pm A PackageManager from which the label can be loaded; usually
- * the PackageManager from which you originally retrieved this item.
- *
- * @return Returns a CharSequence containing the item's label. If the
- * item does not have a label, its name is returned.
- */
- public CharSequence loadLabel(PackageManager pm) {
- if (nonLocalizedLabel != null) {
- return nonLocalizedLabel;
- }
- if (labelRes != 0) {
- CharSequence label = pm.getText(packageName, labelRes, null);
- if (label != null) {
- return label;
- }
- }
- if(name != null) {
- return name;
- }
- return packageName;
- }
-
- /**
- * Retrieve the current graphical icon associated with this item. This
- * will call back on the given PackageManager to load the icon from
- * the application.
- *
- * @param pm A PackageManager from which the icon can be loaded; usually
- * the PackageManager from which you originally retrieved this item.
- *
- * @return Returns a Drawable containing the item's icon. If the
- * item does not have an icon, the default activity icon is returned.
- */
- public Drawable loadIcon(PackageManager pm) {
- if (icon != 0) {
- Drawable dr = pm.getDrawable(packageName, icon, null);
- if (dr != null) {
- return dr;
- }
- }
- return pm.getDefaultActivityIcon();
- }
-
- /**
- * Load an XML resource attached to the meta-data of this item. This will
- * retrieved the name meta-data entry, and if defined call back on the
- * given PackageManager to load its XML file from the application.
- *
- * @param pm A PackageManager from which the XML can be loaded; usually
- * the PackageManager from which you originally retrieved this item.
- * @param name Name of the meta-date you would like to load.
- *
- * @return Returns an XmlPullParser you can use to parse the XML file
- * assigned as the given meta-data. If the meta-data name is not defined
- * or the XML resource could not be found, null is returned.
- */
- public XmlResourceParser loadXmlMetaData(PackageManager pm, String name) {
- if (metaData != null) {
- int resid = metaData.getInt(name);
- if (resid != 0) {
- return pm.getXml(packageName, resid, null);
- }
- }
- return null;
- }
-
- protected void dumpFront(Printer pw, String prefix) {
- pw.println(prefix + "name=" + name);
- pw.println(prefix + "packageName=" + packageName);
- pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
- + " nonLocalizedLabel=" + nonLocalizedLabel
- + " icon=0x" + Integer.toHexString(icon));
- }
-
- protected void dumpBack(Printer pw, String prefix) {
- // no back here
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- dest.writeString(name);
- dest.writeString(packageName);
- dest.writeInt(labelRes);
- TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags);
- dest.writeInt(icon);
- dest.writeBundle(metaData);
- }
-
- protected PackageItemInfo(Parcel source) {
- name = source.readString();
- packageName = source.readString();
- labelRes = source.readInt();
- nonLocalizedLabel
- = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
- icon = source.readInt();
- metaData = source.readBundle();
- }
-
- public static class DisplayNameComparator
- implements Comparator<PackageItemInfo> {
- public DisplayNameComparator(PackageManager pm) {
- mPM = pm;
- }
-
- public final int compare(PackageItemInfo aa, PackageItemInfo ab) {
- CharSequence sa = aa.loadLabel(mPM);
- if (sa == null) sa = aa.name;
- CharSequence sb = ab.loadLabel(mPM);
- if (sb == null) sb = ab.name;
- return sCollator.compare(sa.toString(), sb.toString());
- }
-
- private final Collator sCollator = Collator.getInstance();
- private PackageManager mPM;
- }
-}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
deleted file mode 100644
index 698f27f..0000000
--- a/core/java/android/content/pm/PackageManager.java
+++ /dev/null
@@ -1,1626 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.util.AndroidException;
-import android.util.DisplayMetrics;
-
-import java.io.File;
-import java.util.List;
-
-/**
- * Class for retrieving various kinds of information related to the application
- * packages that are currently installed on the device.
- *
- * You can find this class through {@link Context#getPackageManager}.
- */
-public abstract class PackageManager {
-
- /**
- * This exception is thrown when a given package, application, or component
- * name can not be found.
- */
- public static class NameNotFoundException extends AndroidException {
- public NameNotFoundException() {
- }
-
- public NameNotFoundException(String name) {
- super(name);
- }
- }
-
- /**
- * {@link PackageInfo} flag: return information about
- * activities in the package in {@link PackageInfo#activities}.
- */
- public static final int GET_ACTIVITIES = 0x00000001;
-
- /**
- * {@link PackageInfo} flag: return information about
- * intent receivers in the package in
- * {@link PackageInfo#receivers}.
- */
- public static final int GET_RECEIVERS = 0x00000002;
-
- /**
- * {@link PackageInfo} flag: return information about
- * services in the package in {@link PackageInfo#services}.
- */
- public static final int GET_SERVICES = 0x00000004;
-
- /**
- * {@link PackageInfo} flag: return information about
- * content providers in the package in
- * {@link PackageInfo#providers}.
- */
- public static final int GET_PROVIDERS = 0x00000008;
-
- /**
- * {@link PackageInfo} flag: return information about
- * instrumentation in the package in
- * {@link PackageInfo#instrumentation}.
- */
- public static final int GET_INSTRUMENTATION = 0x00000010;
-
- /**
- * {@link PackageInfo} flag: return information about the
- * intent filters supported by the activity.
- */
- public static final int GET_INTENT_FILTERS = 0x00000020;
-
- /**
- * {@link PackageInfo} flag: return information about the
- * signatures included in the package.
- */
- public static final int GET_SIGNATURES = 0x00000040;
-
- /**
- * {@link ResolveInfo} flag: return the IntentFilter that
- * was matched for a particular ResolveInfo in
- * {@link ResolveInfo#filter}.
- */
- public static final int GET_RESOLVED_FILTER = 0x00000040;
-
- /**
- * {@link ComponentInfo} flag: return the {@link ComponentInfo#metaData}
- * data {@link android.os.Bundle}s that are associated with a component.
- * This applies for any API returning a ComponentInfo subclass.
- */
- public static final int GET_META_DATA = 0x00000080;
-
- /**
- * {@link PackageInfo} flag: return the
- * {@link PackageInfo#gids group ids} that are associated with an
- * application.
- * This applies for any API returning an PackageInfo class, either
- * directly or nested inside of another.
- */
- public static final int GET_GIDS = 0x00000100;
-
- /**
- * {@link PackageInfo} flag: include disabled components in the returned info.
- */
- public static final int GET_DISABLED_COMPONENTS = 0x00000200;
-
- /**
- * {@link ApplicationInfo} flag: return the
- * {@link ApplicationInfo#sharedLibraryFiles paths to the shared libraries}
- * that are associated with an application.
- * This applies for any API returning an ApplicationInfo class, either
- * directly or nested inside of another.
- */
- public static final int GET_SHARED_LIBRARY_FILES = 0x00000400;
-
- /**
- * {@link ProviderInfo} flag: return the
- * {@link ProviderInfo#uriPermissionPatterns URI permission patterns}
- * that are associated with a content provider.
- * This applies for any API returning an ProviderInfo class, either
- * directly or nested inside of another.
- */
- public static final int GET_URI_PERMISSION_PATTERNS = 0x00000800;
- /**
- * {@link PackageInfo} flag: return information about
- * permissions in the package in
- * {@link PackageInfo#permissions}.
- */
- public static final int GET_PERMISSIONS = 0x00001000;
-
- /**
- * Flag parameter to retrieve all applications(even uninstalled ones) with data directories.
- * This state could have resulted if applications have been deleted with flag
- * DONT_DELETE_DATA
- * with a possibility of being replaced or reinstalled in future
- */
- public static final int GET_UNINSTALLED_PACKAGES = 0x00002000;
-
- /**
- * {@link PackageInfo} flag: return information about
- * hardware preferences
- * {@link PackageInfo#configPreferences}
- */
- public static final int GET_CONFIGURATIONS = 0x00004000;
-
- /**
- * Permission check result: this is returned by {@link #checkPermission}
- * if the permission has been granted to the given package.
- */
- public static final int PERMISSION_GRANTED = 0;
-
- /**
- * Permission check result: this is returned by {@link #checkPermission}
- * if the permission has not been granted to the given package.
- */
- public static final int PERMISSION_DENIED = -1;
-
- /**
- * Signature check result: this is returned by {@link #checkSignatures}
- * if the two packages have a matching signature.
- */
- public static final int SIGNATURE_MATCH = 0;
-
- /**
- * Signature check result: this is returned by {@link #checkSignatures}
- * if neither of the two packages is signed.
- */
- public static final int SIGNATURE_NEITHER_SIGNED = 1;
-
- /**
- * Signature check result: this is returned by {@link #checkSignatures}
- * if the first package is not signed, but the second is.
- */
- public static final int SIGNATURE_FIRST_NOT_SIGNED = -1;
-
- /**
- * Signature check result: this is returned by {@link #checkSignatures}
- * if the second package is not signed, but the first is.
- */
- public static final int SIGNATURE_SECOND_NOT_SIGNED = -2;
-
- /**
- * Signature check result: this is returned by {@link #checkSignatures}
- * if both packages are signed but there is no matching signature.
- */
- public static final int SIGNATURE_NO_MATCH = -3;
-
- /**
- * Signature check result: this is returned by {@link #checkSignatures}
- * if either of the given package names are not valid.
- */
- public static final int SIGNATURE_UNKNOWN_PACKAGE = -4;
-
- /**
- * Resolution and querying flag: if set, only filters that support the
- * {@link android.content.Intent#CATEGORY_DEFAULT} will be considered for
- * matching. This is a synonym for including the CATEGORY_DEFAULT in your
- * supplied Intent.
- */
- public static final int MATCH_DEFAULT_ONLY = 0x00010000;
-
- public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0;
- public static final int COMPONENT_ENABLED_STATE_ENABLED = 1;
- public static final int COMPONENT_ENABLED_STATE_DISABLED = 2;
-
- /**
- * Flag parameter for {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} to
- * indicate that this package should be installed as forward locked, i.e. only the app itself
- * should have access to it's code and non-resource assets.
- */
- public static final int FORWARD_LOCK_PACKAGE = 0x00000001;
-
- /**
- * Flag parameter for {@link #installPackage} to indicate that you want to replace an already
- * installed package, if one exists
- */
- public static final int REPLACE_EXISTING_PACKAGE = 0x00000002;
-
- /**
- * Flag parameter for
- * {@link #setComponentEnabledSetting(android.content.ComponentName, int, int)} to indicate
- * that you don't want to kill the app containing the component. Be careful when you set this
- * since changing component states can make the containing application's behavior unpredictable.
- */
- public static final int DONT_KILL_APP = 0x00000001;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} on success.
- */
- public static final int INSTALL_SUCCEEDED = 1;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package is
- * already installed.
- */
- public static final int INSTALL_FAILED_ALREADY_EXISTS = -1;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package archive
- * file is invalid.
- */
- public static final int INSTALL_FAILED_INVALID_APK = -2;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the URI passed in
- * is invalid.
- */
- public static final int INSTALL_FAILED_INVALID_URI = -3;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if the package manager
- * service found that the device didn't have enough storage space to install the app
- */
- public static final int INSTALL_FAILED_INSUFFICIENT_STORAGE = -4;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if a
- * package is already installed with the same name.
- */
- public static final int INSTALL_FAILED_DUPLICATE_PACKAGE = -5;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
- * the requested shared user does not exist.
- */
- public static final int INSTALL_FAILED_NO_SHARED_USER = -6;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
- * a previously installed package of the same name has a different signature
- * than the new package (and the old package's data was not removed).
- */
- public static final int INSTALL_FAILED_UPDATE_INCOMPATIBLE = -7;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
- * the new package is requested a shared user which is already installed on the
- * device and does not have matching signature.
- */
- public static final int INSTALL_FAILED_SHARED_USER_INCOMPATIBLE = -8;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
- * the new package uses a shared library that is not available.
- */
- public static final int INSTALL_FAILED_MISSING_SHARED_LIBRARY = -9;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
- * the new package uses a shared library that is not available.
- */
- public static final int INSTALL_FAILED_REPLACE_COULDNT_DELETE = -10;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
- * the new package failed while optimizing and validating its dex files,
- * either because there was not enough storage or the validation failed.
- */
- public static final int INSTALL_FAILED_DEXOPT = -11;
-
- /**
- * Installation return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
- * the new package failed because the current SDK version is older than
- * that required by the package.
- */
- public static final int INSTALL_FAILED_OLDER_SDK = -12;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser was given a path that is not a file, or does not end with the expected
- * '.apk' extension.
- */
- public static final int INSTALL_PARSE_FAILED_NOT_APK = -100;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser was unable to retrieve the AndroidManifest.xml file.
- */
- public static final int INSTALL_PARSE_FAILED_BAD_MANIFEST = -101;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser encountered an unexpected exception.
- */
- public static final int INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION = -102;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser did not find any certificates in the .apk.
- */
- public static final int INSTALL_PARSE_FAILED_NO_CERTIFICATES = -103;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser found inconsistent certificates on the files in the .apk.
- */
- public static final int INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES = -104;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser encountered a CertificateEncodingException in one of the
- * files in the .apk.
- */
- public static final int INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING = -105;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser encountered a bad or missing package name in the manifest.
- */
- public static final int INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME = -106;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser encountered a bad shared user id name in the manifest.
- */
- public static final int INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID = -107;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser encountered some structural problem in the manifest.
- */
- public static final int INSTALL_PARSE_FAILED_MANIFEST_MALFORMED = -108;
-
- /**
- * Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
- * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
- * if the parser did not find any actionable tags (instrumentation or application)
- * in the manifest.
- */
- public static final int INSTALL_PARSE_FAILED_MANIFEST_EMPTY = -109;
-
- /**
- * Indicates the state of installation. Used by PackageManager to
- * figure out incomplete installations. Say a package is being installed
- * (the state is set to PKG_INSTALL_INCOMPLETE) and remains so till
- * the package installation is successful or unsuccesful lin which case
- * the PackageManager will no longer maintain state information associated
- * with the package. If some exception(like device freeze or battery being
- * pulled out) occurs during installation of a package, the PackageManager
- * needs this information to clean up the previously failed installation.
- */
- public static final int PKG_INSTALL_INCOMPLETE = 0;
- public static final int PKG_INSTALL_COMPLETE = 1;
-
- /**
- * Flag parameter for {@link #deletePackage} to indicate that you don't want to delete the
- * package's data directory.
- *
- * @hide
- */
- public static final int DONT_DELETE_DATA = 0x00000001;
-
- /**
- * Retrieve overall information about an application package that is
- * installed on the system.
- *
- * <p>Throws {@link NameNotFoundException} if a package with the given
- * name can not be found on the system.
- *
- * @param packageName The full name (i.e. com.google.apps.contacts) of the
- * desired package.
-
- * @param flags Additional option flags. Use any combination of
- * {@link #GET_ACTIVITIES},
- * {@link #GET_GIDS},
- * {@link #GET_CONFIGURATIONS},
- * {@link #GET_INSTRUMENTATION},
- * {@link #GET_PERMISSIONS},
- * {@link #GET_PROVIDERS},
- * {@link #GET_RECEIVERS},
- * {@link #GET_SERVICES},
- * {@link #GET_SIGNATURES},
- * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
- *
- * @return Returns a PackageInfo object containing information about the package.
- * If flag GET_UNINSTALLED_PACKAGES is set and if the package is not
- * found in the list of installed applications, the package information is
- * retrieved from the list of uninstalled applications(which includes
- * installed applications as well as applications
- * with data directory ie applications which had been
- * deleted with DONT_DELTE_DATA flag set).
- *
- * @see #GET_ACTIVITIES
- * @see #GET_GIDS
- * @see #GET_CONFIGURATIONS
- * @see #GET_INSTRUMENTATION
- * @see #GET_PERMISSIONS
- * @see #GET_PROVIDERS
- * @see #GET_RECEIVERS
- * @see #GET_SERVICES
- * @see #GET_SIGNATURES
- * @see #GET_UNINSTALLED_PACKAGES
- *
- */
- public abstract PackageInfo getPackageInfo(String packageName, int flags)
- throws NameNotFoundException;
-
- /**
- * Return an array of all of the secondary group-ids that have been
- * assigned to a package.
- *
- * <p>Throws {@link NameNotFoundException} if a package with the given
- * name can not be found on the system.
- *
- * @param packageName The full name (i.e. com.google.apps.contacts) of the
- * desired package.
- *
- * @return Returns an int array of the assigned gids, or null if there
- * are none.
- */
- public abstract int[] getPackageGids(String packageName)
- throws NameNotFoundException;
-
- /**
- * Retrieve all of the information we know about a particular permission.
- *
- * <p>Throws {@link NameNotFoundException} if a permission with the given
- * name can not be found on the system.
- *
- * @param name The fully qualified name (i.e. com.google.permission.LOGIN)
- * of the permission you are interested in.
- * @param flags Additional option flags. Use {@link #GET_META_DATA} to
- * retrieve any meta-data associated with the permission.
- *
- * @return Returns a {@link PermissionInfo} containing information about the
- * permission.
- */
- public abstract PermissionInfo getPermissionInfo(String name, int flags)
- throws NameNotFoundException;
-
- /**
- * Query for all of the permissions associated with a particular group.
- *
- * <p>Throws {@link NameNotFoundException} if the given group does not
- * exist.
- *
- * @param group The fully qualified name (i.e. com.google.permission.LOGIN)
- * of the permission group you are interested in. Use null to
- * find all of the permissions not associated with a group.
- * @param flags Additional option flags. Use {@link #GET_META_DATA} to
- * retrieve any meta-data associated with the permissions.
- *
- * @return Returns a list of {@link PermissionInfo} containing information
- * about all of the permissions in the given group.
- */
- public abstract List<PermissionInfo> queryPermissionsByGroup(String group,
- int flags) throws NameNotFoundException;
-
- /**
- * Retrieve all of the information we know about a particular group of
- * permissions.
- *
- * <p>Throws {@link NameNotFoundException} if a permission group with the given
- * name can not be found on the system.
- *
- * @param name The fully qualified name (i.e. com.google.permission_group.APPS)
- * of the permission you are interested in.
- * @param flags Additional option flags. Use {@link #GET_META_DATA} to
- * retrieve any meta-data associated with the permission group.
- *
- * @return Returns a {@link PermissionGroupInfo} containing information
- * about the permission.
- */
- public abstract PermissionGroupInfo getPermissionGroupInfo(String name,
- int flags) throws NameNotFoundException;
-
- /**
- * Retrieve all of the known permission groups in the system.
- *
- * @param flags Additional option flags. Use {@link #GET_META_DATA} to
- * retrieve any meta-data associated with the permission group.
- *
- * @return Returns a list of {@link PermissionGroupInfo} containing
- * information about all of the known permission groups.
- */
- public abstract List<PermissionGroupInfo> getAllPermissionGroups(int flags);
-
- /**
- * Retrieve all of the information we know about a particular
- * package/application.
- *
- * <p>Throws {@link NameNotFoundException} if an application with the given
- * package name can not be found on the system.
- *
- * @param packageName The full name (i.e. com.google.apps.contacts) of an
- * application.
- * @param flags Additional option flags. Use any combination of
- * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
- * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
- *
- * @return {@link ApplicationInfo} Returns ApplicationInfo object containing
- * information about the package.
- * If flag GET_UNINSTALLED_PACKAGES is set and if the package is not
- * found in the list of installed applications,
- * the application information is retrieved from the
- * list of uninstalled applications(which includes
- * installed applications as well as applications
- * with data directory ie applications which had been
- * deleted with DONT_DELTE_DATA flag set).
- *
- * @see #GET_META_DATA
- * @see #GET_SHARED_LIBRARY_FILES
- * @see #GET_UNINSTALLED_PACKAGES
- */
- public abstract ApplicationInfo getApplicationInfo(String packageName,
- int flags) throws NameNotFoundException;
-
- /**
- * Retrieve all of the information we know about a particular activity
- * class.
- *
- * <p>Throws {@link NameNotFoundException} if an activity with the given
- * class name can not be found on the system.
- *
- * @param className The full name (i.e.
- * com.google.apps.contacts.ContactsList) of an Activity
- * class.
- * @param flags Additional option flags. Use any combination of
- * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
- * to modify the data (in ApplicationInfo) returned.
- *
- * @return {@link ActivityInfo} containing information about the activity.
- *
- * @see #GET_INTENT_FILTERS
- * @see #GET_META_DATA
- * @see #GET_SHARED_LIBRARY_FILES
- */
- public abstract ActivityInfo getActivityInfo(ComponentName className,
- int flags) throws NameNotFoundException;
-
- /**
- * Retrieve all of the information we know about a particular receiver
- * class.
- *
- * <p>Throws {@link NameNotFoundException} if a receiver with the given
- * class name can not be found on the system.
- *
- * @param className The full name (i.e.
- * com.google.apps.contacts.CalendarAlarm) of a Receiver
- * class.
- * @param flags Additional option flags. Use any combination of
- * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
- * to modify the data returned.
- *
- * @return {@link ActivityInfo} containing information about the receiver.
- *
- * @see #GET_INTENT_FILTERS
- * @see #GET_META_DATA
- * @see #GET_SHARED_LIBRARY_FILES
- */
- public abstract ActivityInfo getReceiverInfo(ComponentName className,
- int flags) throws NameNotFoundException;
-
- /**
- * Retrieve all of the information we know about a particular service
- * class.
- *
- * <p>Throws {@link NameNotFoundException} if a service with the given
- * class name can not be found on the system.
- *
- * @param className The full name (i.e.
- * com.google.apps.media.BackgroundPlayback) of a Service
- * class.
- * @param flags Additional option flags. Use any combination of
- * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
- * to modify the data returned.
- *
- * @return ServiceInfo containing information about the service.
- *
- * @see #GET_META_DATA
- * @see #GET_SHARED_LIBRARY_FILES
- */
- public abstract ServiceInfo getServiceInfo(ComponentName className,
- int flags) throws NameNotFoundException;
-
- /**
- * Return a List of all packages that are installed
- * on the device.
- *
- * @param flags Additional option flags. Use any combination of
- * {@link #GET_ACTIVITIES},
- * {@link #GET_GIDS},
- * {@link #GET_CONFIGURATIONS},
- * {@link #GET_INSTRUMENTATION},
- * {@link #GET_PERMISSIONS},
- * {@link #GET_PROVIDERS},
- * {@link #GET_RECEIVERS},
- * {@link #GET_SERVICES},
- * {@link #GET_SIGNATURES},
- * {@link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
- *
- * @return A List of PackageInfo objects, one for each package that is
- * installed on the device. In the unlikely case of there being no
- * installed packages, an empty list is returned.
- * If flag GET_UNINSTALLED_PACKAGES is set, a list of all
- * applications including those deleted with DONT_DELETE_DATA
- * (partially installed apps with data directory) will be returned.
- *
- * @see #GET_ACTIVITIES
- * @see #GET_GIDS
- * @see #GET_CONFIGURATIONS
- * @see #GET_INSTRUMENTATION
- * @see #GET_PERMISSIONS
- * @see #GET_PROVIDERS
- * @see #GET_RECEIVERS
- * @see #GET_SERVICES
- * @see #GET_SIGNATURES
- * @see #GET_UNINSTALLED_PACKAGES
- *
- */
- public abstract List<PackageInfo> getInstalledPackages(int flags);
-
- /**
- * Check whether a particular package has been granted a particular
- * permission.
- *
- * @param permName The name of the permission you are checking for,
- * @param pkgName The name of the package you are checking against.
- *
- * @return If the package has the permission, PERMISSION_GRANTED is
- * returned. If it does not have the permission, PERMISSION_DENIED
- * is returned.
- *
- * @see #PERMISSION_GRANTED
- * @see #PERMISSION_DENIED
- */
- public abstract int checkPermission(String permName, String pkgName);
-
- /**
- * Add a new dynamic permission to the system. For this to work, your
- * package must have defined a permission tree through the
- * {@link android.R.styleable#AndroidManifestPermissionTree
- * &lt;permission-tree&gt;} tag in its manifest. A package can only add
- * permissions to trees that were defined by either its own package or
- * another with the same user id; a permission is in a tree if it
- * matches the name of the permission tree + ".": for example,
- * "com.foo.bar" is a member of the permission tree "com.foo".
- *
- * <p>It is good to make your permission tree name descriptive, because you
- * are taking possession of that entire set of permission names. Thus, it
- * must be under a domain you control, with a suffix that will not match
- * any normal permissions that may be declared in any applications that
- * are part of that domain.
- *
- * <p>New permissions must be added before
- * any .apks are installed that use those permissions. Permissions you
- * add through this method are remembered across reboots of the device.
- * If the given permission already exists, the info you supply here
- * will be used to update it.
- *
- * @param info Description of the permission to be added.
- *
- * @return Returns true if a new permission was created, false if an
- * existing one was updated.
- *
- * @throws SecurityException if you are not allowed to add the
- * given permission name.
- *
- * @see #removePermission(String)
- */
- public abstract boolean addPermission(PermissionInfo info);
-
- /**
- * Removes a permission that was previously added with
- * {@link #addPermission(PermissionInfo)}. The same ownership rules apply
- * -- you are only allowed to remove permissions that you are allowed
- * to add.
- *
- * @param name The name of the permission to remove.
- *
- * @throws SecurityException if you are not allowed to remove the
- * given permission name.
- *
- * @see #addPermission(PermissionInfo)
- */
- public abstract void removePermission(String name);
-
- /**
- * Compare the signatures of two packages to determine if the same
- * signature appears in both of them. If they do contain the same
- * signature, then they are allowed special privileges when working
- * with each other: they can share the same user-id, run instrumentation
- * against each other, etc.
- *
- * @param pkg1 First package name whose signature will be compared.
- * @param pkg2 Second package name whose signature will be compared.
- * @return Returns an integer indicating whether there is a matching
- * signature: the value is >= 0 if there is a match (or neither package
- * is signed), or < 0 if there is not a match. The match result can be
- * further distinguished with the success (>= 0) constants
- * {@link #SIGNATURE_MATCH}, {@link #SIGNATURE_NEITHER_SIGNED}; or
- * failure (< 0) constants {@link #SIGNATURE_FIRST_NOT_SIGNED},
- * {@link #SIGNATURE_SECOND_NOT_SIGNED}, {@link #SIGNATURE_NO_MATCH},
- * or {@link #SIGNATURE_UNKNOWN_PACKAGE}.
- *
- * @see #SIGNATURE_MATCH
- * @see #SIGNATURE_NEITHER_SIGNED
- * @see #SIGNATURE_FIRST_NOT_SIGNED
- * @see #SIGNATURE_SECOND_NOT_SIGNED
- * @see #SIGNATURE_NO_MATCH
- * @see #SIGNATURE_UNKNOWN_PACKAGE
- */
- public abstract int checkSignatures(String pkg1, String pkg2);
-
- /**
- * Retrieve the names of all packages that are associated with a particular
- * user id. In most cases, this will be a single package name, the package
- * that has been assigned that user id. Where there are multiple packages
- * sharing the same user id through the "sharedUserId" mechanism, all
- * packages with that id will be returned.
- *
- * @param uid The user id for which you would like to retrieve the
- * associated packages.
- *
- * @return Returns an array of one or more packages assigned to the user
- * id, or null if there are no known packages with the given id.
- */
- public abstract String[] getPackagesForUid(int uid);
-
- /**
- * Retrieve the official name associated with a user id. This name is
- * guaranteed to never change, though it is possibly for the underlying
- * user id to be changed. That is, if you are storing information about
- * user ids in persistent storage, you should use the string returned
- * by this function instead of the raw user-id.
- *
- * @param uid The user id for which you would like to retrieve a name.
- * @return Returns a unique name for the given user id, or null if the
- * user id is not currently assigned.
- */
- public abstract String getNameForUid(int uid);
-
- /**
- * Return the user id associated with a shared user name. Multiple
- * applications can specify a shared user name in their manifest and thus
- * end up using a common uid. This might be used for new applications
- * that use an existing shared user name and need to know the uid of the
- * shared user.
- *
- * @param sharedUserName The shared user name whose uid is to be retrieved.
- * @return Returns the uid associated with the shared user, or NameNotFoundException
- * if the shared user name is not being used by any installed packages
- * @hide
- */
- public abstract int getUidForSharedUser(String sharedUserName)
- throws NameNotFoundException;
-
- /**
- * Return a List of all application packages that are installed on the
- * device. If flag GET_UNINSTALLED_PACKAGES has been set, a list of all
- * applications including those deleted with DONT_DELETE_DATA(partially
- * installed apps with data directory) will be returned.
- *
- * @param flags Additional option flags. Use any combination of
- * {@link #GET_META_DATA}, {@link #GET_SHARED_LIBRARY_FILES},
- * {link #GET_UNINSTALLED_PACKAGES} to modify the data returned.
- *
- * @return A List of ApplicationInfo objects, one for each application that
- * is installed on the device. In the unlikely case of there being
- * no installed applications, an empty list is returned.
- * If flag GET_UNINSTALLED_PACKAGES is set, a list of all
- * applications including those deleted with DONT_DELETE_DATA
- * (partially installed apps with data directory) will be returned.
- *
- * @see #GET_META_DATA
- * @see #GET_SHARED_LIBRARY_FILES
- * @see #GET_UNINSTALLED_PACKAGES
- */
- public abstract List<ApplicationInfo> getInstalledApplications(int flags);
-
- /**
- * Get a list of shared libraries that are available on the
- * system.
- *
- * @return An array of shared library names that are
- * available on the system, or null if none are installed.
- *
- */
- public abstract String[] getSystemSharedLibraryNames();
-
- /**
- * Determine the best action to perform for a given Intent. This is how
- * {@link Intent#resolveActivity} finds an activity if a class has not
- * been explicitly specified.
- *
- * @param intent An intent containing all of the desired specification
- * (action, data, type, category, and/or component).
- * @param flags Additional option flags. The most important is
- * MATCH_DEFAULT_ONLY, to limit the resolution to only
- * those activities that support the CATEGORY_DEFAULT.
- *
- * @return Returns a ResolveInfo containing the final activity intent that
- * was determined to be the best action. Returns null if no
- * matching activity was found.
- *
- * @see #MATCH_DEFAULT_ONLY
- * @see #GET_INTENT_FILTERS
- * @see #GET_RESOLVED_FILTER
- */
- public abstract ResolveInfo resolveActivity(Intent intent, int flags);
-
- /**
- * Retrieve all activities that can be performed for the given intent.
- *
- * @param intent The desired intent as per resolveActivity().
- * @param flags Additional option flags. The most important is
- * MATCH_DEFAULT_ONLY, to limit the resolution to only
- * those activities that support the CATEGORY_DEFAULT.
- *
- * @return A List<ResolveInfo> containing one entry for each matching
- * Activity. These are ordered from best to worst match -- that
- * is, the first item in the list is what is returned by
- * resolveActivity(). If there are no matching activities, an empty
- * list is returned.
- *
- * @see #MATCH_DEFAULT_ONLY
- * @see #GET_INTENT_FILTERS
- * @see #GET_RESOLVED_FILTER
- */
- public abstract List<ResolveInfo> queryIntentActivities(Intent intent,
- int flags);
-
- /**
- * Retrieve a set of activities that should be presented to the user as
- * similar options. This is like {@link #queryIntentActivities}, except it
- * also allows you to supply a list of more explicit Intents that you would
- * like to resolve to particular options, and takes care of returning the
- * final ResolveInfo list in a reasonable order, with no duplicates, based
- * on those inputs.
- *
- * @param caller The class name of the activity that is making the
- * request. This activity will never appear in the output
- * list. Can be null.
- * @param specifics An array of Intents that should be resolved to the
- * first specific results. Can be null.
- * @param intent The desired intent as per resolveActivity().
- * @param flags Additional option flags. The most important is
- * MATCH_DEFAULT_ONLY, to limit the resolution to only
- * those activities that support the CATEGORY_DEFAULT.
- *
- * @return A List<ResolveInfo> containing one entry for each matching
- * Activity. These are ordered first by all of the intents resolved
- * in <var>specifics</var> and then any additional activities that
- * can handle <var>intent</var> but did not get included by one of
- * the <var>specifics</var> intents. If there are no matching
- * activities, an empty list is returned.
- *
- * @see #MATCH_DEFAULT_ONLY
- * @see #GET_INTENT_FILTERS
- * @see #GET_RESOLVED_FILTER
- */
- public abstract List<ResolveInfo> queryIntentActivityOptions(
- ComponentName caller, Intent[] specifics, Intent intent, int flags);
-
- /**
- * Retrieve all receivers that can handle a broadcast of the given intent.
- *
- * @param intent The desired intent as per resolveActivity().
- * @param flags Additional option flags. The most important is
- * MATCH_DEFAULT_ONLY, to limit the resolution to only
- * those activities that support the CATEGORY_DEFAULT.
- *
- * @return A List<ResolveInfo> containing one entry for each matching
- * Receiver. These are ordered from first to last in priority. If
- * there are no matching receivers, an empty list is returned.
- *
- * @see #MATCH_DEFAULT_ONLY
- * @see #GET_INTENT_FILTERS
- * @see #GET_RESOLVED_FILTER
- */
- public abstract List<ResolveInfo> queryBroadcastReceivers(Intent intent,
- int flags);
-
- /**
- * Determine the best service to handle for a given Intent.
- *
- * @param intent An intent containing all of the desired specification
- * (action, data, type, category, and/or component).
- * @param flags Additional option flags.
- *
- * @return Returns a ResolveInfo containing the final service intent that
- * was determined to be the best action. Returns null if no
- * matching service was found.
- *
- * @see #GET_INTENT_FILTERS
- * @see #GET_RESOLVED_FILTER
- */
- public abstract ResolveInfo resolveService(Intent intent, int flags);
-
- /**
- * Retrieve all services that can match the given intent.
- *
- * @param intent The desired intent as per resolveService().
- * @param flags Additional option flags.
- *
- * @return A List<ResolveInfo> containing one entry for each matching
- * ServiceInfo. These are ordered from best to worst match -- that
- * is, the first item in the list is what is returned by
- * resolveService(). If there are no matching services, an empty
- * list is returned.
- *
- * @see #GET_INTENT_FILTERS
- * @see #GET_RESOLVED_FILTER
- */
- public abstract List<ResolveInfo> queryIntentServices(Intent intent,
- int flags);
-
- /**
- * Find a single content provider by its base path name.
- *
- * @param name The name of the provider to find.
- * @param flags Additional option flags. Currently should always be 0.
- *
- * @return ContentProviderInfo Information about the provider, if found,
- * else null.
- */
- public abstract ProviderInfo resolveContentProvider(String name,
- int flags);
-
- /**
- * Retrieve content provider information.
- *
- * <p><em>Note: unlike most other methods, an empty result set is indicated
- * by a null return instead of an empty list.</em>
- *
- * @param processName If non-null, limits the returned providers to only
- * those that are hosted by the given process. If null,
- * all content providers are returned.
- * @param uid If <var>processName</var> is non-null, this is the required
- * uid owning the requested content providers.
- * @param flags Additional option flags. Currently should always be 0.
- *
- * @return A List<ContentProviderInfo> containing one entry for each
- * content provider either patching <var>processName</var> or, if
- * <var>processName</var> is null, all known content providers.
- * <em>If there are no matching providers, null is returned.</em>
- */
- public abstract List<ProviderInfo> queryContentProviders(
- String processName, int uid, int flags);
-
- /**
- * Retrieve all of the information we know about a particular
- * instrumentation class.
- *
- * <p>Throws {@link NameNotFoundException} if instrumentation with the
- * given class name can not be found on the system.
- *
- * @param className The full name (i.e.
- * com.google.apps.contacts.InstrumentList) of an
- * Instrumentation class.
- * @param flags Additional option flags. Currently should always be 0.
- *
- * @return InstrumentationInfo containing information about the
- * instrumentation.
- */
- public abstract InstrumentationInfo getInstrumentationInfo(
- ComponentName className, int flags) throws NameNotFoundException;
-
- /**
- * Retrieve information about available instrumentation code. May be used
- * to retrieve either all instrumentation code, or only the code targeting
- * a particular package.
- *
- * @param targetPackage If null, all instrumentation is returned; only the
- * instrumentation targeting this package name is
- * returned.
- * @param flags Additional option flags. Currently should always be 0.
- *
- * @return A List<InstrumentationInfo> containing one entry for each
- * matching available Instrumentation. Returns an empty list if
- * there is no instrumentation available for the given package.
- */
- public abstract List<InstrumentationInfo> queryInstrumentation(
- String targetPackage, int flags);
-
- /**
- * Retrieve an image from a package. This is a low-level API used by
- * the various package manager info structures (such as
- * {@link ComponentInfo} to implement retrieval of their associated
- * icon.
- *
- * @param packageName The name of the package that this icon is coming from.
- * Can not be null.
- * @param resid The resource identifier of the desired image. Can not be 0.
- * @param appInfo Overall information about <var>packageName</var>. This
- * may be null, in which case the application information will be retrieved
- * for you if needed; if you already have this information around, it can
- * be much more efficient to supply it here.
- *
- * @return Returns a Drawable holding the requested image. Returns null if
- * an image could not be found for any reason.
- */
- public abstract Drawable getDrawable(String packageName, int resid,
- ApplicationInfo appInfo);
-
- /**
- * Retrieve the icon associated with an activity. Given the full name of
- * an activity, retrieves the information about it and calls
- * {@link ComponentInfo#loadIcon ComponentInfo.loadIcon()} to return its icon.
- * If the activity can not be found, NameNotFoundException is thrown.
- *
- * @param activityName Name of the activity whose icon is to be retrieved.
- *
- * @return Returns the image of the icon, or the default activity icon if
- * it could not be found. Does not return null.
- * @throws NameNotFoundException Thrown if the resources for the given
- * activity could not be loaded.
- *
- * @see #getActivityIcon(Intent)
- */
- public abstract Drawable getActivityIcon(ComponentName activityName)
- throws NameNotFoundException;
-
- /**
- * Retrieve the icon associated with an Intent. If intent.getClassName() is
- * set, this simply returns the result of
- * getActivityIcon(intent.getClassName()). Otherwise it resolves the intent's
- * component and returns the icon associated with the resolved component.
- * If intent.getClassName() can not be found or the Intent can not be resolved
- * to a component, NameNotFoundException is thrown.
- *
- * @param intent The intent for which you would like to retrieve an icon.
- *
- * @return Returns the image of the icon, or the default activity icon if
- * it could not be found. Does not return null.
- * @throws NameNotFoundException Thrown if the resources for application
- * matching the given intent could not be loaded.
- *
- * @see #getActivityIcon(ComponentName)
- */
- public abstract Drawable getActivityIcon(Intent intent)
- throws NameNotFoundException;
-
- /**
- * Return the generic icon for an activity that is used when no specific
- * icon is defined.
- *
- * @return Drawable Image of the icon.
- */
- public abstract Drawable getDefaultActivityIcon();
-
- /**
- * Retrieve the icon associated with an application. If it has not defined
- * an icon, the default app icon is returned. Does not return null.
- *
- * @param info Information about application being queried.
- *
- * @return Returns the image of the icon, or the default application icon
- * if it could not be found.
- *
- * @see #getApplicationIcon(String)
- */
- public abstract Drawable getApplicationIcon(ApplicationInfo info);
-
- /**
- * Retrieve the icon associated with an application. Given the name of the
- * application's package, retrieves the information about it and calls
- * getApplicationIcon() to return its icon. If the application can not be
- * found, NameNotFoundException is thrown.
- *
- * @param packageName Name of the package whose application icon is to be
- * retrieved.
- *
- * @return Returns the image of the icon, or the default application icon
- * if it could not be found. Does not return null.
- * @throws NameNotFoundException Thrown if the resources for the given
- * application could not be loaded.
- *
- * @see #getApplicationIcon(ApplicationInfo)
- */
- public abstract Drawable getApplicationIcon(String packageName)
- throws NameNotFoundException;
-
- /**
- * Retrieve text from a package. This is a low-level API used by
- * the various package manager info structures (such as
- * {@link ComponentInfo} to implement retrieval of their associated
- * labels and other text.
- *
- * @param packageName The name of the package that this text is coming from.
- * Can not be null.
- * @param resid The resource identifier of the desired text. Can not be 0.
- * @param appInfo Overall information about <var>packageName</var>. This
- * may be null, in which case the application information will be retrieved
- * for you if needed; if you already have this information around, it can
- * be much more efficient to supply it here.
- *
- * @return Returns a CharSequence holding the requested text. Returns null
- * if the text could not be found for any reason.
- */
- public abstract CharSequence getText(String packageName, int resid,
- ApplicationInfo appInfo);
-
- /**
- * Retrieve an XML file from a package. This is a low-level API used to
- * retrieve XML meta data.
- *
- * @param packageName The name of the package that this xml is coming from.
- * Can not be null.
- * @param resid The resource identifier of the desired xml. Can not be 0.
- * @param appInfo Overall information about <var>packageName</var>. This
- * may be null, in which case the application information will be retrieved
- * for you if needed; if you already have this information around, it can
- * be much more efficient to supply it here.
- *
- * @return Returns an XmlPullParser allowing you to parse out the XML
- * data. Returns null if the xml resource could not be found for any
- * reason.
- */
- public abstract XmlResourceParser getXml(String packageName, int resid,
- ApplicationInfo appInfo);
-
- /**
- * Return the label to use for this application.
- *
- * @return Returns the label associated with this application, or null if
- * it could not be found for any reason.
- * @param info The application to get the label of
- */
- public abstract CharSequence getApplicationLabel(ApplicationInfo info);
-
- /**
- * Retrieve the resources associated with an activity. Given the full
- * name of an activity, retrieves the information about it and calls
- * getResources() to return its application's resources. If the activity
- * can not be found, NameNotFoundException is thrown.
- *
- * @param activityName Name of the activity whose resources are to be
- * retrieved.
- *
- * @return Returns the application's Resources.
- * @throws NameNotFoundException Thrown if the resources for the given
- * application could not be loaded.
- *
- * @see #getResourcesForApplication(ApplicationInfo)
- */
- public abstract Resources getResourcesForActivity(ComponentName activityName)
- throws NameNotFoundException;
-
- /**
- * Retrieve the resources for an application. Throws NameNotFoundException
- * if the package is no longer installed.
- *
- * @param app Information about the desired application.
- *
- * @return Returns the application's Resources.
- * @throws NameNotFoundException Thrown if the resources for the given
- * application could not be loaded (most likely because it was uninstalled).
- */
- public abstract Resources getResourcesForApplication(ApplicationInfo app)
- throws NameNotFoundException;
-
- /**
- * Retrieve the resources associated with an application. Given the full
- * package name of an application, retrieves the information about it and
- * calls getResources() to return its application's resources. If the
- * appPackageName can not be found, NameNotFoundException is thrown.
- *
- * @param appPackageName Package name of the application whose resources
- * are to be retrieved.
- *
- * @return Returns the application's Resources.
- * @throws NameNotFoundException Thrown if the resources for the given
- * application could not be loaded.
- *
- * @see #getResourcesForApplication(ApplicationInfo)
- */
- public abstract Resources getResourcesForApplication(String appPackageName)
- throws NameNotFoundException;
-
- /**
- * Retrieve overall information about an application package defined
- * in a package archive file
- *
- * @param archiveFilePath The path to the archive file
- * @param flags Additional option flags. Use any combination of
- * {@link #GET_ACTIVITIES},
- * {@link #GET_GIDS},
- * {@link #GET_CONFIGURATIONS},
- * {@link #GET_INSTRUMENTATION},
- * {@link #GET_PERMISSIONS},
- * {@link #GET_PROVIDERS},
- * {@link #GET_RECEIVERS},
- * {@link #GET_SERVICES},
- * {@link #GET_SIGNATURES}, to modify the data returned.
- *
- * @return Returns the information about the package. Returns
- * null if the package could not be successfully parsed.
- *
- * @see #GET_ACTIVITIES
- * @see #GET_GIDS
- * @see #GET_CONFIGURATIONS
- * @see #GET_INSTRUMENTATION
- * @see #GET_PERMISSIONS
- * @see #GET_PROVIDERS
- * @see #GET_RECEIVERS
- * @see #GET_SERVICES
- * @see #GET_SIGNATURES
- *
- */
- public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) {
- PackageParser packageParser = new PackageParser(archiveFilePath);
- DisplayMetrics metrics = new DisplayMetrics();
- metrics.setToDefaults();
- final File sourceFile = new File(archiveFilePath);
- PackageParser.Package pkg = packageParser.parsePackage(
- sourceFile, archiveFilePath, metrics, 0);
- if (pkg == null) {
- return null;
- }
- return PackageParser.generatePackageInfo(pkg, null, flags);
- }
-
- /**
- * Install a package. Since this may take a little while, the result will
- * be posted back to the given observer. An installation will fail if the calling context
- * lacks the {@link android.Manifest.permission#INSTALL_PACKAGES} permission, if the
- * package named in the package file's manifest is already installed, or if there's no space
- * available on the device.
- *
- * @param packageURI The location of the package file to install. This can be a 'file:' or a
- * 'content:' URI.
- * @param observer An observer callback to get notified when the package installation is
- * complete. {@link IPackageInstallObserver#packageInstalled(String, int)} will be
- * called when that happens. observer may be null to indicate that no callback is desired.
- * @param flags - possible values: {@link #FORWARD_LOCK_PACKAGE},
- * {@link #REPLACE_EXISTING_PACKAGE}
- *
- * @see #installPackage(android.net.Uri)
- */
- public abstract void installPackage(
- Uri packageURI, IPackageInstallObserver observer, int flags);
-
- /**
- * Attempts to delete a package. Since this may take a little while, the result will
- * be posted back to the given observer. A deletion will fail if the calling context
- * lacks the {@link android.Manifest.permission#DELETE_PACKAGES} permission, if the
- * named package cannot be found, or if the named package is a "system package".
- * (TODO: include pointer to documentation on "system packages")
- *
- * @param packageName The name of the package to delete
- * @param observer An observer callback to get notified when the package deletion is
- * complete. {@link android.content.pm.IPackageDeleteObserver#packageDeleted(boolean)} will be
- * called when that happens. observer may be null to indicate that no callback is desired.
- * @param flags - possible values: {@link #DONT_DELETE_DATA}
- *
- * @hide
- */
- public abstract void deletePackage(
- String packageName, IPackageDeleteObserver observer, int flags);
- /**
- * Attempts to clear the user data directory of an application.
- * Since this may take a little while, the result will
- * be posted back to the given observer. A deletion will fail if the
- * named package cannot be found, or if the named package is a "system package".
- *
- * @param packageName The name of the package
- * @param observer An observer callback to get notified when the operation is finished
- * {@link android.content.pm.IPackageDataObserver#onRemoveCompleted(String, boolean)}
- * will be called when that happens. observer may be null to indicate that
- * no callback is desired.
- *
- * @hide
- */
- public abstract void clearApplicationUserData(String packageName,
- IPackageDataObserver observer);
- /**
- * Attempts to delete the cache files associated with an application.
- * Since this may take a little while, the result will
- * be posted back to the given observer. A deletion will fail if the calling context
- * lacks the {@link android.Manifest.permission#DELETE_CACHE_FILES} permission, if the
- * named package cannot be found, or if the named package is a "system package".
- *
- * @param packageName The name of the package to delete
- * @param observer An observer callback to get notified when the cache file deletion
- * is complete.
- * {@link android.content.pm.IPackageDataObserver#onRemoveCompleted(String, boolean)}
- * will be called when that happens. observer may be null to indicate that
- * no callback is desired.
- *
- * @hide
- */
- public abstract void deleteApplicationCacheFiles(String packageName,
- IPackageDataObserver observer);
-
- /**
- * Free storage by deleting LRU sorted list of cache files across
- * all applications. If the currently available free storage
- * on the device is greater than or equal to the requested
- * free storage, no cache files are cleared. If the currently
- * available storage on the device is less than the requested
- * free storage, some or all of the cache files across
- * all applications are deleted (based on last accessed time)
- * to increase the free storage space on the device to
- * the requested value. There is no guarantee that clearing all
- * the cache files from all applications will clear up
- * enough storage to achieve the desired value.
- * @param freeStorageSize The number of bytes of storage to be
- * freed by the system. Say if freeStorageSize is XX,
- * and the current free storage is YY,
- * if XX is less than YY, just return. if not free XX-YY number
- * of bytes if possible.
- * @param observer call back used to notify when
- * the operation is completed
- *
- * @hide
- */
- public abstract void freeStorageAndNotify(long freeStorageSize, IPackageDataObserver observer);
-
- /**
- * Free storage by deleting LRU sorted list of cache files across
- * all applications. If the currently available free storage
- * on the device is greater than or equal to the requested
- * free storage, no cache files are cleared. If the currently
- * available storage on the device is less than the requested
- * free storage, some or all of the cache files across
- * all applications are deleted (based on last accessed time)
- * to increase the free storage space on the device to
- * the requested value. There is no guarantee that clearing all
- * the cache files from all applications will clear up
- * enough storage to achieve the desired value.
- * @param freeStorageSize The number of bytes of storage to be
- * freed by the system. Say if freeStorageSize is XX,
- * and the current free storage is YY,
- * if XX is less than YY, just return. if not free XX-YY number
- * of bytes if possible.
- * @param opFinishedIntent PendingIntent call back used to
- * notify when the operation is completed.May be null
- * to indicate that no call back is desired.
- *
- * @hide
- */
- public abstract void freeStorage(long freeStorageSize, PendingIntent opFinishedIntent);
-
- /**
- * Retrieve the size information for a package.
- * Since this may take a little while, the result will
- * be posted back to the given observer. The calling context
- * should have the {@link android.Manifest.permission#GET_PACKAGE_SIZE} permission.
- *
- * @param packageName The name of the package whose size information is to be retrieved
- * @param observer An observer callback to get notified when the operation
- * is complete.
- * {@link android.content.pm.IPackageStatsObserver#onGetStatsCompleted(PackageStats, boolean)}
- * The observer's callback is invoked with a PackageStats object(containing the
- * code, data and cache sizes of the package) and a boolean value representing
- * the status of the operation. observer may be null to indicate that
- * no callback is desired.
- *
- * @hide
- */
- public abstract void getPackageSizeInfo(String packageName,
- IPackageStatsObserver observer);
-
- /**
- * Install a package.
- *
- * @param packageURI The location of the package file to install
- *
- * @see #installPackage(android.net.Uri, IPackageInstallObserver, int)
- */
- public void installPackage(Uri packageURI) {
- installPackage(packageURI, null, 0);
- }
-
- /**
- * Add a new package to the list of preferred packages. This new package
- * will be added to the front of the list (removed from its current location
- * if already listed), meaning it will now be preferred over all other
- * packages when resolving conflicts.
- *
- * @param packageName The package name of the new package to make preferred.
- */
- public abstract void addPackageToPreferred(String packageName);
-
- /**
- * Remove a package from the list of preferred packages. If it was on
- * the list, it will no longer be preferred over other packages.
- *
- * @param packageName The package name to remove.
- */
- public abstract void removePackageFromPreferred(String packageName);
-
- /**
- * Retrieve the list of all currently configured preferred packages. The
- * first package on the list is the most preferred, the last is the
- * least preferred.
- *
- * @param flags Additional option flags. Use any combination of
- * {@link #GET_ACTIVITIES},
- * {@link #GET_GIDS},
- * {@link #GET_CONFIGURATIONS},
- * {@link #GET_INSTRUMENTATION},
- * {@link #GET_PERMISSIONS},
- * {@link #GET_PROVIDERS},
- * {@link #GET_RECEIVERS},
- * {@link #GET_SERVICES},
- * {@link #GET_SIGNATURES}, to modify the data returned.
- *
- * @return Returns a list of PackageInfo objects describing each
- * preferred application, in order of preference.
- *
- * @see #GET_ACTIVITIES
- * @see #GET_GIDS
- * @see #GET_CONFIGURATIONS
- * @see #GET_INSTRUMENTATION
- * @see #GET_PERMISSIONS
- * @see #GET_PROVIDERS
- * @see #GET_RECEIVERS
- * @see #GET_SERVICES
- * @see #GET_SIGNATURES
- */
- public abstract List<PackageInfo> getPreferredPackages(int flags);
-
- /**
- * Add a new preferred activity mapping to the system. This will be used
- * to automatically select the given activity component when
- * {@link Context#startActivity(Intent) Context.startActivity()} finds
- * multiple matching activities and also matches the given filter.
- *
- * @param filter The set of intents under which this activity will be
- * made preferred.
- * @param match The IntentFilter match category that this preference
- * applies to.
- * @param set The set of activities that the user was picking from when
- * this preference was made.
- * @param activity The component name of the activity that is to be
- * preferred.
- */
- public abstract void addPreferredActivity(IntentFilter filter, int match,
- ComponentName[] set, ComponentName activity);
-
- /**
- * Remove all preferred activity mappings, previously added with
- * {@link #addPreferredActivity}, from the
- * system whose activities are implemented in the given package name.
- *
- * @param packageName The name of the package whose preferred activity
- * mappings are to be removed.
- */
- public abstract void clearPackagePreferredActivities(String packageName);
-
- /**
- * Retrieve all preferred activities, previously added with
- * {@link #addPreferredActivity}, that are
- * currently registered with the system.
- *
- * @param outFilters A list in which to place the filters of all of the
- * preferred activities, or null for none.
- * @param outActivities A list in which to place the component names of
- * all of the preferred activities, or null for none.
- * @param packageName An option package in which you would like to limit
- * the list. If null, all activities will be returned; if non-null, only
- * those activities in the given package are returned.
- *
- * @return Returns the total number of registered preferred activities
- * (the number of distinct IntentFilter records, not the number of unique
- * activity components) that were found.
- */
- public abstract int getPreferredActivities(List<IntentFilter> outFilters,
- List<ComponentName> outActivities, String packageName);
-
- /**
- * Set the enabled setting for a package component (activity, receiver, service, provider).
- * This setting will override any enabled state which may have been set by the component in its
- * manifest.
- *
- * @param componentName The component to enable
- * @param newState The new enabled state for the component. The legal values for this state
- * are:
- * {@link #COMPONENT_ENABLED_STATE_ENABLED},
- * {@link #COMPONENT_ENABLED_STATE_DISABLED}
- * and
- * {@link #COMPONENT_ENABLED_STATE_DEFAULT}
- * The last one removes the setting, thereby restoring the component's state to
- * whatever was set in it's manifest (or enabled, by default).
- * @param flags Optional behavior flags: {@link #DONT_KILL_APP} or 0.
- */
- public abstract void setComponentEnabledSetting(ComponentName componentName,
- int newState, int flags);
-
-
- /**
- * Return the the enabled setting for a package component (activity,
- * receiver, service, provider). This returns the last value set by
- * {@link #setComponentEnabledSetting(ComponentName, int, int)}; in most
- * cases this value will be {@link #COMPONENT_ENABLED_STATE_DEFAULT} since
- * the value originally specified in the manifest has not been modified.
- *
- * @param componentName The component to retrieve.
- * @return Returns the current enabled state for the component. May
- * be one of {@link #COMPONENT_ENABLED_STATE_ENABLED},
- * {@link #COMPONENT_ENABLED_STATE_DISABLED}, or
- * {@link #COMPONENT_ENABLED_STATE_DEFAULT}. The last one means the
- * component's enabled state is based on the original information in
- * the manifest as found in {@link ComponentInfo}.
- */
- public abstract int getComponentEnabledSetting(ComponentName componentName);
-
- /**
- * Set the enabled setting for an application
- * This setting will override any enabled state which may have been set by the application in
- * its manifest. It also overrides the enabled state set in the manifest for any of the
- * application's components. It does not override any enabled state set by
- * {@link #setComponentEnabledSetting} for any of the application's components.
- *
- * @param packageName The package name of the application to enable
- * @param newState The new enabled state for the component. The legal values for this state
- * are:
- * {@link #COMPONENT_ENABLED_STATE_ENABLED},
- * {@link #COMPONENT_ENABLED_STATE_DISABLED}
- * and
- * {@link #COMPONENT_ENABLED_STATE_DEFAULT}
- * The last one removes the setting, thereby restoring the applications's state to
- * whatever was set in its manifest (or enabled, by default).
- * @param flags Optional behavior flags: {@link #DONT_KILL_APP} or 0.
- */
- public abstract void setApplicationEnabledSetting(String packageName,
- int newState, int flags);
-
- /**
- * Return the the enabled setting for an application. This returns
- * the last value set by
- * {@link #setApplicationEnabledSetting(String, int, int)}; in most
- * cases this value will be {@link #COMPONENT_ENABLED_STATE_DEFAULT} since
- * the value originally specified in the manifest has not been modified.
- *
- * @param packageName The component to retrieve.
- * @return Returns the current enabled state for the component. May
- * be one of {@link #COMPONENT_ENABLED_STATE_ENABLED},
- * {@link #COMPONENT_ENABLED_STATE_DISABLED}, or
- * {@link #COMPONENT_ENABLED_STATE_DEFAULT}. The last one means the
- * application's enabled state is based on the original information in
- * the manifest as found in {@link ComponentInfo}.
- */
- public abstract int getApplicationEnabledSetting(String packageName);
-
- /**
- * Return whether the device has been booted into safe mode.
- */
- public abstract boolean isSafeMode();
-}
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
deleted file mode 100644
index 4ae8b08..0000000
--- a/core/java/android/content/pm/PackageParser.java
+++ /dev/null
@@ -1,2352 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.ComponentName;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.AssetManager;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.content.res.XmlResourceParser;
-import android.os.Bundle;
-import android.os.PatternMatcher;
-import android.util.AttributeSet;
-import android.util.Config;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.TypedValue;
-import com.android.internal.util.XmlUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.WeakReference;
-import java.security.cert.Certificate;
-import java.security.cert.CertificateEncodingException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-
-/**
- * Package archive parsing
- *
- * {@hide}
- */
-public class PackageParser {
-
- private String mArchiveSourcePath;
- private String[] mSeparateProcesses;
- private int mSdkVersion;
-
- private int mParseError = PackageManager.INSTALL_SUCCEEDED;
-
- private static final Object mSync = new Object();
- private static WeakReference<byte[]> mReadBuffer;
-
- /** If set to true, we will only allow package files that exactly match
- * the DTD. Otherwise, we try to get as much from the package as we
- * can without failing. This should normally be set to false, to
- * support extensions to the DTD in future versions. */
- private static final boolean RIGID_PARSER = false;
-
- private static final String TAG = "PackageParser";
-
- public PackageParser(String archiveSourcePath) {
- mArchiveSourcePath = archiveSourcePath;
- }
-
- public void setSeparateProcesses(String[] procs) {
- mSeparateProcesses = procs;
- }
-
- public void setSdkVersion(int sdkVersion) {
- mSdkVersion = sdkVersion;
- }
-
- private static final boolean isPackageFilename(String name) {
- return name.endsWith(".apk");
- }
-
- /**
- * Generate and return the {@link PackageInfo} for a parsed package.
- *
- * @param p the parsed package.
- * @param flags indicating which optional information is included.
- */
- public static PackageInfo generatePackageInfo(PackageParser.Package p,
- int gids[], int flags) {
-
- PackageInfo pi = new PackageInfo();
- pi.packageName = p.packageName;
- pi.versionCode = p.mVersionCode;
- pi.versionName = p.mVersionName;
- pi.sharedUserId = p.mSharedUserId;
- pi.sharedUserLabel = p.mSharedUserLabel;
- pi.applicationInfo = p.applicationInfo;
- if ((flags&PackageManager.GET_GIDS) != 0) {
- pi.gids = gids;
- }
- if ((flags&PackageManager.GET_CONFIGURATIONS) != 0) {
- int N = p.configPreferences.size();
- if (N > 0) {
- pi.configPreferences = new ConfigurationInfo[N];
- for (int i=0; i<N; i++) {
- pi.configPreferences[i] = p.configPreferences.get(i);
- }
- }
- }
- if ((flags&PackageManager.GET_ACTIVITIES) != 0) {
- int N = p.activities.size();
- if (N > 0) {
- pi.activities = new ActivityInfo[N];
- for (int i=0; i<N; i++) {
- final Activity activity = p.activities.get(i);
- if (activity.info.enabled
- || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
- pi.activities[i] = generateActivityInfo(p.activities.get(i), flags);
- }
- }
- }
- }
- if ((flags&PackageManager.GET_RECEIVERS) != 0) {
- int N = p.receivers.size();
- if (N > 0) {
- pi.receivers = new ActivityInfo[N];
- for (int i=0; i<N; i++) {
- final Activity activity = p.receivers.get(i);
- if (activity.info.enabled
- || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
- pi.receivers[i] = generateActivityInfo(p.receivers.get(i), flags);
- }
- }
- }
- }
- if ((flags&PackageManager.GET_SERVICES) != 0) {
- int N = p.services.size();
- if (N > 0) {
- pi.services = new ServiceInfo[N];
- for (int i=0; i<N; i++) {
- final Service service = p.services.get(i);
- if (service.info.enabled
- || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
- pi.services[i] = generateServiceInfo(p.services.get(i), flags);
- }
- }
- }
- }
- if ((flags&PackageManager.GET_PROVIDERS) != 0) {
- int N = p.providers.size();
- if (N > 0) {
- pi.providers = new ProviderInfo[N];
- for (int i=0; i<N; i++) {
- final Provider provider = p.providers.get(i);
- if (provider.info.enabled
- || (flags&PackageManager.GET_DISABLED_COMPONENTS) != 0) {
- pi.providers[i] = generateProviderInfo(p.providers.get(i), flags);
- }
- }
- }
- }
- if ((flags&PackageManager.GET_INSTRUMENTATION) != 0) {
- int N = p.instrumentation.size();
- if (N > 0) {
- pi.instrumentation = new InstrumentationInfo[N];
- for (int i=0; i<N; i++) {
- pi.instrumentation[i] = generateInstrumentationInfo(
- p.instrumentation.get(i), flags);
- }
- }
- }
- if ((flags&PackageManager.GET_PERMISSIONS) != 0) {
- int N = p.permissions.size();
- if (N > 0) {
- pi.permissions = new PermissionInfo[N];
- for (int i=0; i<N; i++) {
- pi.permissions[i] = generatePermissionInfo(p.permissions.get(i), flags);
- }
- }
- N = p.requestedPermissions.size();
- if (N > 0) {
- pi.requestedPermissions = new String[N];
- for (int i=0; i<N; i++) {
- pi.requestedPermissions[i] = p.requestedPermissions.get(i);
- }
- }
- }
- if ((flags&PackageManager.GET_SIGNATURES) != 0) {
- int N = p.mSignatures.length;
- if (N > 0) {
- pi.signatures = new Signature[N];
- System.arraycopy(p.mSignatures, 0, pi.signatures, 0, N);
- }
- }
- return pi;
- }
-
- private Certificate[] loadCertificates(JarFile jarFile, JarEntry je,
- byte[] readBuffer) {
- try {
- // We must read the stream for the JarEntry to retrieve
- // its certificates.
- InputStream is = jarFile.getInputStream(je);
- while (is.read(readBuffer, 0, readBuffer.length) != -1) {
- // not using
- }
- is.close();
- return je != null ? je.getCertificates() : null;
- } catch (IOException e) {
- Log.w(TAG, "Exception reading " + je.getName() + " in "
- + jarFile.getName(), e);
- }
- return null;
- }
-
- public final static int PARSE_IS_SYSTEM = 0x0001;
- public final static int PARSE_CHATTY = 0x0002;
- public final static int PARSE_MUST_BE_APK = 0x0004;
- public final static int PARSE_IGNORE_PROCESSES = 0x0008;
-
- public int getParseError() {
- return mParseError;
- }
-
- public Package parsePackage(File sourceFile, String destFileName,
- DisplayMetrics metrics, int flags) {
- mParseError = PackageManager.INSTALL_SUCCEEDED;
-
- mArchiveSourcePath = sourceFile.getPath();
- if (!sourceFile.isFile()) {
- Log.w(TAG, "Skipping dir: " + mArchiveSourcePath);
- mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
- return null;
- }
- if (!isPackageFilename(sourceFile.getName())
- && (flags&PARSE_MUST_BE_APK) != 0) {
- if ((flags&PARSE_IS_SYSTEM) == 0) {
- // We expect to have non-.apk files in the system dir,
- // so don't warn about them.
- Log.w(TAG, "Skipping non-package file: " + mArchiveSourcePath);
- }
- mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
- return null;
- }
-
- if ((flags&PARSE_CHATTY) != 0 && Config.LOGD) Log.d(
- TAG, "Scanning package: " + mArchiveSourcePath);
-
- XmlResourceParser parser = null;
- AssetManager assmgr = null;
- boolean assetError = true;
- try {
- assmgr = new AssetManager();
- if(assmgr.addAssetPath(mArchiveSourcePath) != 0) {
- parser = assmgr.openXmlResourceParser("AndroidManifest.xml");
- assetError = false;
- } else {
- Log.w(TAG, "Failed adding asset path:"+mArchiveSourcePath);
- }
- } catch (Exception e) {
- Log.w(TAG, "Unable to read AndroidManifest.xml of "
- + mArchiveSourcePath, e);
- }
- if(assetError) {
- if (assmgr != null) assmgr.close();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
- return null;
- }
- String[] errorText = new String[1];
- Package pkg = null;
- Exception errorException = null;
- try {
- // XXXX todo: need to figure out correct configuration.
- Resources res = new Resources(assmgr, metrics, null);
- pkg = parsePackage(res, parser, flags, errorText);
- } catch (Exception e) {
- errorException = e;
- mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
- }
-
-
- if (pkg == null) {
- if (errorException != null) {
- Log.w(TAG, mArchiveSourcePath, errorException);
- } else {
- Log.w(TAG, mArchiveSourcePath + " (at "
- + parser.getPositionDescription()
- + "): " + errorText[0]);
- }
- parser.close();
- assmgr.close();
- if (mParseError == PackageManager.INSTALL_SUCCEEDED) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- }
- return null;
- }
-
- parser.close();
- assmgr.close();
-
- pkg.applicationInfo.sourceDir = destFileName;
- pkg.applicationInfo.publicSourceDir = destFileName;
- pkg.mSignatures = null;
-
- return pkg;
- }
-
- public boolean collectCertificates(Package pkg, int flags) {
- pkg.mSignatures = null;
-
- WeakReference<byte[]> readBufferRef;
- byte[] readBuffer = null;
- synchronized (mSync) {
- readBufferRef = mReadBuffer;
- if (readBufferRef != null) {
- mReadBuffer = null;
- readBuffer = readBufferRef.get();
- }
- if (readBuffer == null) {
- readBuffer = new byte[8192];
- readBufferRef = new WeakReference<byte[]>(readBuffer);
- }
- }
-
- try {
- JarFile jarFile = new JarFile(mArchiveSourcePath);
-
- Certificate[] certs = null;
-
- if ((flags&PARSE_IS_SYSTEM) != 0) {
- // If this package comes from the system image, then we
- // can trust it... we'll just use the AndroidManifest.xml
- // to retrieve its signatures, not validating all of the
- // files.
- JarEntry jarEntry = jarFile.getJarEntry("AndroidManifest.xml");
- certs = loadCertificates(jarFile, jarEntry, readBuffer);
- if (certs == null) {
- Log.e(TAG, "Package " + pkg.packageName
- + " has no certificates at entry "
- + jarEntry.getName() + "; ignoring!");
- jarFile.close();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
- return false;
- }
- if (false) {
- Log.i(TAG, "File " + mArchiveSourcePath + ": entry=" + jarEntry
- + " certs=" + (certs != null ? certs.length : 0));
- if (certs != null) {
- final int N = certs.length;
- for (int i=0; i<N; i++) {
- Log.i(TAG, " Public key: "
- + certs[i].getPublicKey().getEncoded()
- + " " + certs[i].getPublicKey());
- }
- }
- }
-
- } else {
- Enumeration entries = jarFile.entries();
- while (entries.hasMoreElements()) {
- JarEntry je = (JarEntry)entries.nextElement();
- if (je.isDirectory()) continue;
- if (je.getName().startsWith("META-INF/")) continue;
- Certificate[] localCerts = loadCertificates(jarFile, je,
- readBuffer);
- if (false) {
- Log.i(TAG, "File " + mArchiveSourcePath + " entry " + je.getName()
- + ": certs=" + certs + " ("
- + (certs != null ? certs.length : 0) + ")");
- }
- if (localCerts == null) {
- Log.e(TAG, "Package " + pkg.packageName
- + " has no certificates at entry "
- + je.getName() + "; ignoring!");
- jarFile.close();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
- return false;
- } else if (certs == null) {
- certs = localCerts;
- } else {
- // Ensure all certificates match.
- for (int i=0; i<certs.length; i++) {
- boolean found = false;
- for (int j=0; j<localCerts.length; j++) {
- if (certs[i] != null &&
- certs[i].equals(localCerts[j])) {
- found = true;
- break;
- }
- }
- if (!found || certs.length != localCerts.length) {
- Log.e(TAG, "Package " + pkg.packageName
- + " has mismatched certificates at entry "
- + je.getName() + "; ignoring!");
- jarFile.close();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
- return false;
- }
- }
- }
- }
- }
- jarFile.close();
-
- synchronized (mSync) {
- mReadBuffer = readBufferRef;
- }
-
- if (certs != null && certs.length > 0) {
- final int N = certs.length;
- pkg.mSignatures = new Signature[certs.length];
- for (int i=0; i<N; i++) {
- pkg.mSignatures[i] = new Signature(
- certs[i].getEncoded());
- }
- } else {
- Log.e(TAG, "Package " + pkg.packageName
- + " has no certificates; ignoring!");
- mParseError = PackageManager.INSTALL_PARSE_FAILED_NO_CERTIFICATES;
- return false;
- }
- } catch (CertificateEncodingException e) {
- Log.w(TAG, "Exception reading " + mArchiveSourcePath, e);
- mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
- return false;
- } catch (IOException e) {
- Log.w(TAG, "Exception reading " + mArchiveSourcePath, e);
- mParseError = PackageManager.INSTALL_PARSE_FAILED_CERTIFICATE_ENCODING;
- return false;
- } catch (RuntimeException e) {
- Log.w(TAG, "Exception reading " + mArchiveSourcePath, e);
- mParseError = PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
- return false;
- }
-
- return true;
- }
-
- public static String parsePackageName(String packageFilePath, int flags) {
- XmlResourceParser parser = null;
- AssetManager assmgr = null;
- try {
- assmgr = new AssetManager();
- int cookie = assmgr.addAssetPath(packageFilePath);
- parser = assmgr.openXmlResourceParser(cookie, "AndroidManifest.xml");
- } catch (Exception e) {
- if (assmgr != null) assmgr.close();
- Log.w(TAG, "Unable to read AndroidManifest.xml of "
- + packageFilePath, e);
- return null;
- }
- AttributeSet attrs = parser;
- String errors[] = new String[1];
- String packageName = null;
- try {
- packageName = parsePackageName(parser, attrs, flags, errors);
- } catch (IOException e) {
- Log.w(TAG, packageFilePath, e);
- } catch (XmlPullParserException e) {
- Log.w(TAG, packageFilePath, e);
- } finally {
- if (parser != null) parser.close();
- if (assmgr != null) assmgr.close();
- }
- if (packageName == null) {
- Log.e(TAG, "parsePackageName error: " + errors[0]);
- return null;
- }
- return packageName;
- }
-
- private static String validateName(String name, boolean requiresSeparator) {
- final int N = name.length();
- boolean hasSep = false;
- boolean front = true;
- for (int i=0; i<N; i++) {
- final char c = name.charAt(i);
- if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
- front = false;
- continue;
- }
- if (!front) {
- if ((c >= '0' && c <= '9') || c == '_') {
- continue;
- }
- }
- if (c == '.') {
- hasSep = true;
- front = true;
- continue;
- }
- return "bad character '" + c + "'";
- }
- return hasSep || !requiresSeparator
- ? null : "must have at least one '.' separator";
- }
-
- private static String parsePackageName(XmlPullParser parser,
- AttributeSet attrs, int flags, String[] outError)
- throws IOException, XmlPullParserException {
-
- int type;
- while ((type=parser.next()) != parser.START_TAG
- && type != parser.END_DOCUMENT) {
- ;
- }
-
- if (type != parser.START_TAG) {
- outError[0] = "No start tag found";
- return null;
- }
- if ((flags&PARSE_CHATTY) != 0 && Config.LOGV) Log.v(
- TAG, "Root element name: '" + parser.getName() + "'");
- if (!parser.getName().equals("manifest")) {
- outError[0] = "No <manifest> tag";
- return null;
- }
- String pkgName = attrs.getAttributeValue(null, "package");
- if (pkgName == null || pkgName.length() == 0) {
- outError[0] = "<manifest> does not specify package";
- return null;
- }
- String nameError = validateName(pkgName, true);
- if (nameError != null && !"android".equals(pkgName)) {
- outError[0] = "<manifest> specifies bad package name \""
- + pkgName + "\": " + nameError;
- return null;
- }
-
- return pkgName.intern();
- }
-
- /**
- * Temporary.
- */
- static public Signature stringToSignature(String str) {
- final int N = str.length();
- byte[] sig = new byte[N];
- for (int i=0; i<N; i++) {
- sig[i] = (byte)str.charAt(i);
- }
- return new Signature(sig);
- }
-
- private Package parsePackage(
- Resources res, XmlResourceParser parser, int flags, String[] outError)
- throws XmlPullParserException, IOException {
- AttributeSet attrs = parser;
-
- String pkgName = parsePackageName(parser, attrs, flags, outError);
- if (pkgName == null) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
- return null;
- }
- int type;
-
- final Package pkg = new Package(pkgName);
- pkg.mSystem = (flags&PARSE_IS_SYSTEM) != 0;
- boolean foundApp = false;
-
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifest);
- pkg.mVersionCode = sa.getInteger(
- com.android.internal.R.styleable.AndroidManifest_versionCode, 0);
- pkg.mVersionName = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifest_versionName);
- if (pkg.mVersionName != null) {
- pkg.mVersionName = pkg.mVersionName.intern();
- }
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifest_sharedUserId);
- if (str != null) {
- String nameError = validateName(str, true);
- if (nameError != null && !"android".equals(pkgName)) {
- outError[0] = "<manifest> specifies bad sharedUserId name \""
- + str + "\": " + nameError;
- mParseError = PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID;
- return null;
- }
- pkg.mSharedUserId = str.intern();
- pkg.mSharedUserLabel = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifest_sharedUserLabel, 0);
- }
- sa.recycle();
-
- final int innerDepth = parser.getDepth();
-
- int outerDepth = parser.getDepth();
- while ((type=parser.next()) != parser.END_DOCUMENT
- && (type != parser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == parser.END_TAG || type == parser.TEXT) {
- continue;
- }
-
- String tagName = parser.getName();
- if (tagName.equals("application")) {
- if (foundApp) {
- if (RIGID_PARSER) {
- outError[0] = "<manifest> has more than one <application>";
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- } else {
- Log.w(TAG, "<manifest> has more than one <application>");
- XmlUtils.skipCurrentTag(parser);
- continue;
- }
- }
-
- foundApp = true;
- if (!parseApplication(pkg, res, parser, attrs, flags, outError)) {
- return null;
- }
- } else if (tagName.equals("permission-group")) {
- if (parsePermissionGroup(pkg, res, parser, attrs, outError) == null) {
- return null;
- }
- } else if (tagName.equals("permission")) {
- if (parsePermission(pkg, res, parser, attrs, outError) == null) {
- return null;
- }
- } else if (tagName.equals("permission-tree")) {
- if (parsePermissionTree(pkg, res, parser, attrs, outError) == null) {
- return null;
- }
- } else if (tagName.equals("uses-permission")) {
- sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestUsesPermission);
-
- String name = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestUsesPermission_name);
-
- sa.recycle();
-
- if (name != null && !pkg.requestedPermissions.contains(name)) {
- pkg.requestedPermissions.add(name);
- }
-
- XmlUtils.skipCurrentTag(parser);
-
- } else if (tagName.equals("uses-configuration")) {
- ConfigurationInfo cPref = new ConfigurationInfo();
- sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestUsesConfiguration);
- cPref.reqTouchScreen = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqTouchScreen,
- Configuration.TOUCHSCREEN_UNDEFINED);
- cPref.reqKeyboardType = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqKeyboardType,
- Configuration.KEYBOARD_UNDEFINED);
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqHardKeyboard,
- false)) {
- cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
- }
- cPref.reqNavigation = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqNavigation,
- Configuration.NAVIGATION_UNDEFINED);
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestUsesConfiguration_reqFiveWayNav,
- false)) {
- cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
- }
- sa.recycle();
- pkg.configPreferences.add(cPref);
-
- XmlUtils.skipCurrentTag(parser);
-
- } else if (tagName.equals("uses-sdk")) {
- if (mSdkVersion > 0) {
- sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestUsesSdk);
-
- int vers = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestUsesSdk_minSdkVersion, 0);
-
- sa.recycle();
-
- if (vers > mSdkVersion) {
- outError[0] = "Requires newer sdk version #" + vers
- + " (current version is #" + mSdkVersion + ")";
- mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK;
- return null;
- }
- }
-
- XmlUtils.skipCurrentTag(parser);
-
- } else if (tagName.equals("instrumentation")) {
- if (parseInstrumentation(pkg, res, parser, attrs, outError) == null) {
- return null;
- }
- } else if (tagName.equals("eat-comment")) {
- // Just skip this tag
- XmlUtils.skipCurrentTag(parser);
- continue;
- } else if (RIGID_PARSER) {
- outError[0] = "Bad element under <manifest>: "
- + parser.getName();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- } else {
- Log.w(TAG, "Bad element under <manifest>: "
- + parser.getName());
- XmlUtils.skipCurrentTag(parser);
- continue;
- }
- }
-
- if (!foundApp && pkg.instrumentation.size() == 0) {
- outError[0] = "<manifest> does not contain an <application> or <instrumentation>";
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY;
- }
-
- if (pkg.usesLibraries.size() > 0) {
- pkg.usesLibraryFiles = new String[pkg.usesLibraries.size()];
- pkg.usesLibraries.toArray(pkg.usesLibraryFiles);
- }
-
- return pkg;
- }
-
- private static String buildClassName(String pkg, CharSequence clsSeq,
- String[] outError) {
- if (clsSeq == null || clsSeq.length() <= 0) {
- outError[0] = "Empty class name in package " + pkg;
- return null;
- }
- String cls = clsSeq.toString();
- char c = cls.charAt(0);
- if (c == '.') {
- return (pkg + cls).intern();
- }
- if (cls.indexOf('.') < 0) {
- StringBuilder b = new StringBuilder(pkg);
- b.append('.');
- b.append(cls);
- return b.toString().intern();
- }
- if (c >= 'a' && c <= 'z') {
- return cls.intern();
- }
- outError[0] = "Bad class name " + cls + " in package " + pkg;
- return null;
- }
-
- private static String buildCompoundName(String pkg,
- CharSequence procSeq, String type, String[] outError) {
- String proc = procSeq.toString();
- char c = proc.charAt(0);
- if (pkg != null && c == ':') {
- if (proc.length() < 2) {
- outError[0] = "Bad " + type + " name " + proc + " in package " + pkg
- + ": must be at least two characters";
- return null;
- }
- String subName = proc.substring(1);
- String nameError = validateName(subName, false);
- if (nameError != null) {
- outError[0] = "Invalid " + type + " name " + proc + " in package "
- + pkg + ": " + nameError;
- return null;
- }
- return (pkg + proc).intern();
- }
- String nameError = validateName(proc, true);
- if (nameError != null && !"system".equals(proc)) {
- outError[0] = "Invalid " + type + " name " + proc + " in package "
- + pkg + ": " + nameError;
- return null;
- }
- return proc.intern();
- }
-
- private static String buildProcessName(String pkg, String defProc,
- CharSequence procSeq, int flags, String[] separateProcesses,
- String[] outError) {
- if ((flags&PARSE_IGNORE_PROCESSES) != 0 && !"system".equals(procSeq)) {
- return defProc != null ? defProc : pkg;
- }
- if (separateProcesses != null) {
- for (int i=separateProcesses.length-1; i>=0; i--) {
- String sp = separateProcesses[i];
- if (sp.equals(pkg) || sp.equals(defProc) || sp.equals(procSeq)) {
- return pkg;
- }
- }
- }
- if (procSeq == null || procSeq.length() <= 0) {
- return defProc;
- }
- return buildCompoundName(pkg, procSeq, "package", outError);
- }
-
- private static String buildTaskAffinityName(String pkg, String defProc,
- CharSequence procSeq, String[] outError) {
- if (procSeq == null) {
- return defProc;
- }
- if (procSeq.length() <= 0) {
- return null;
- }
- return buildCompoundName(pkg, procSeq, "taskAffinity", outError);
- }
-
- private PermissionGroup parsePermissionGroup(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, String[] outError)
- throws XmlPullParserException, IOException {
- PermissionGroup perm = new PermissionGroup(owner);
-
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestPermissionGroup);
-
- if (!parsePackageItemInfo(owner, perm.info, outError,
- "<permission-group>", sa,
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_name,
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_label,
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_icon)) {
- sa.recycle();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- perm.info.descriptionRes = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_description,
- 0);
-
- sa.recycle();
-
- if (!parseAllMetaData(res, parser, attrs, "<permission-group>", perm,
- outError)) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- owner.permissionGroups.add(perm);
-
- return perm;
- }
-
- private Permission parsePermission(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, String[] outError)
- throws XmlPullParserException, IOException {
- Permission perm = new Permission(owner);
-
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestPermission);
-
- if (!parsePackageItemInfo(owner, perm.info, outError,
- "<permission>", sa,
- com.android.internal.R.styleable.AndroidManifestPermission_name,
- com.android.internal.R.styleable.AndroidManifestPermission_label,
- com.android.internal.R.styleable.AndroidManifestPermission_icon)) {
- sa.recycle();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- perm.info.group = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestPermission_permissionGroup);
- if (perm.info.group != null) {
- perm.info.group = perm.info.group.intern();
- }
-
- perm.info.descriptionRes = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestPermission_description,
- 0);
-
- perm.info.protectionLevel = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestPermission_protectionLevel,
- PermissionInfo.PROTECTION_NORMAL);
-
- sa.recycle();
-
- if (perm.info.protectionLevel == -1) {
- outError[0] = "<permission> does not specify protectionLevel";
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- if (!parseAllMetaData(res, parser, attrs, "<permission>", perm,
- outError)) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- owner.permissions.add(perm);
-
- return perm;
- }
-
- private Permission parsePermissionTree(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, String[] outError)
- throws XmlPullParserException, IOException {
- Permission perm = new Permission(owner);
-
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestPermissionTree);
-
- if (!parsePackageItemInfo(owner, perm.info, outError,
- "<permission-tree>", sa,
- com.android.internal.R.styleable.AndroidManifestPermissionTree_name,
- com.android.internal.R.styleable.AndroidManifestPermissionTree_label,
- com.android.internal.R.styleable.AndroidManifestPermissionTree_icon)) {
- sa.recycle();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- sa.recycle();
-
- int index = perm.info.name.indexOf('.');
- if (index > 0) {
- index = perm.info.name.indexOf('.', index+1);
- }
- if (index < 0) {
- outError[0] = "<permission-tree> name has less than three segments: "
- + perm.info.name;
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- perm.info.descriptionRes = 0;
- perm.info.protectionLevel = PermissionInfo.PROTECTION_NORMAL;
- perm.tree = true;
-
- if (!parseAllMetaData(res, parser, attrs, "<permission-tree>", perm,
- outError)) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- owner.permissions.add(perm);
-
- return perm;
- }
-
- private Instrumentation parseInstrumentation(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, String[] outError)
- throws XmlPullParserException, IOException {
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestInstrumentation);
-
- Instrumentation a = new Instrumentation(owner);
-
- if (!parsePackageItemInfo(owner, a.info, outError, "<instrumentation>", sa,
- com.android.internal.R.styleable.AndroidManifestInstrumentation_name,
- com.android.internal.R.styleable.AndroidManifestInstrumentation_label,
- com.android.internal.R.styleable.AndroidManifestInstrumentation_icon)) {
- sa.recycle();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- a.component = new ComponentName(owner.applicationInfo.packageName,
- a.info.name);
-
- String str;
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestInstrumentation_targetPackage);
- a.info.targetPackage = str != null ? str.intern() : null;
-
- a.info.handleProfiling = sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestInstrumentation_handleProfiling,
- false);
-
- a.info.functionalTest = sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestInstrumentation_functionalTest,
- false);
-
- sa.recycle();
-
- if (a.info.targetPackage == null) {
- outError[0] = "<instrumentation> does not specify targetPackage";
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- if (!parseAllMetaData(res, parser, attrs, "<instrumentation>", a,
- outError)) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return null;
- }
-
- owner.instrumentation.add(a);
-
- return a;
- }
-
- private boolean parseApplication(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
- throws XmlPullParserException, IOException {
- final ApplicationInfo ai = owner.applicationInfo;
- final String pkgName = owner.applicationInfo.packageName;
-
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestApplication);
-
- String name = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_name);
- if (name != null) {
- ai.className = buildClassName(pkgName, name, outError);
- if (ai.className == null) {
- sa.recycle();
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return false;
- }
- }
-
- String manageSpaceActivity = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_manageSpaceActivity);
- if (manageSpaceActivity != null) {
- ai.manageSpaceActivityName = buildClassName(pkgName, manageSpaceActivity,
- outError);
- }
-
- TypedValue v = sa.peekValue(
- com.android.internal.R.styleable.AndroidManifestApplication_label);
- if (v != null && (ai.labelRes=v.resourceId) == 0) {
- ai.nonLocalizedLabel = v.coerceToString();
- }
-
- ai.icon = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestApplication_icon, 0);
- ai.theme = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestApplication_theme, 0);
- ai.descriptionRes = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestApplication_description, 0);
-
- if ((flags&PARSE_IS_SYSTEM) != 0) {
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestApplication_persistent,
- false)) {
- ai.flags |= ApplicationInfo.FLAG_PERSISTENT;
- }
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestApplication_debuggable,
- false)) {
- ai.flags |= ApplicationInfo.FLAG_DEBUGGABLE;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestApplication_hasCode,
- true)) {
- ai.flags |= ApplicationInfo.FLAG_HAS_CODE;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestApplication_allowTaskReparenting,
- false)) {
- ai.flags |= ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestApplication_allowClearUserData,
- true)) {
- ai.flags |= ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
- }
-
- String str;
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_permission);
- ai.permission = (str != null && str.length() > 0) ? str.intern() : null;
-
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_taskAffinity);
- ai.taskAffinity = buildTaskAffinityName(ai.packageName, ai.packageName,
- str, outError);
-
- if (outError[0] == null) {
- ai.processName = buildProcessName(ai.packageName, null, sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestApplication_process),
- flags, mSeparateProcesses, outError);
-
- ai.enabled = sa.getBoolean(com.android.internal.R.styleable.AndroidManifestApplication_enabled, true);
- }
-
- sa.recycle();
-
- if (outError[0] != null) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return false;
- }
-
- final int innerDepth = parser.getDepth();
-
- int type;
- while ((type=parser.next()) != parser.END_DOCUMENT
- && (type != parser.END_TAG || parser.getDepth() > innerDepth)) {
- if (type == parser.END_TAG || type == parser.TEXT) {
- continue;
- }
-
- String tagName = parser.getName();
- if (tagName.equals("activity")) {
- Activity a = parseActivity(owner, res, parser, attrs, flags, outError, false);
- if (a == null) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return false;
- }
-
- owner.activities.add(a);
-
- } else if (tagName.equals("receiver")) {
- Activity a = parseActivity(owner, res, parser, attrs, flags, outError, true);
- if (a == null) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return false;
- }
-
- owner.receivers.add(a);
-
- } else if (tagName.equals("service")) {
- Service s = parseService(owner, res, parser, attrs, flags, outError);
- if (s == null) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return false;
- }
-
- owner.services.add(s);
-
- } else if (tagName.equals("provider")) {
- Provider p = parseProvider(owner, res, parser, attrs, flags, outError);
- if (p == null) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return false;
- }
-
- owner.providers.add(p);
-
- } else if (tagName.equals("activity-alias")) {
- Activity a = parseActivityAlias(owner, res, parser, attrs, flags, outError, false);
- if (a == null) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return false;
- }
-
- owner.activities.add(a);
-
- } else if (parser.getName().equals("meta-data")) {
- // note: application meta-data is stored off to the side, so it can
- // remain null in the primary copy (we like to avoid extra copies because
- // it can be large)
- if ((owner.mAppMetaData = parseMetaData(res, parser, attrs, owner.mAppMetaData,
- outError)) == null) {
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return false;
- }
-
- } else if (tagName.equals("uses-library")) {
- sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestUsesLibrary);
-
- String lname = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestUsesLibrary_name);
-
- sa.recycle();
-
- if (lname != null && !owner.usesLibraries.contains(lname)) {
- owner.usesLibraries.add(lname);
- }
-
- XmlUtils.skipCurrentTag(parser);
-
- } else {
- if (!RIGID_PARSER) {
- Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
- Log.w(TAG, "Unknown element under <application>: " + tagName);
- XmlUtils.skipCurrentTag(parser);
- continue;
- } else {
- outError[0] = "Bad element under <application>: " + tagName;
- mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
- return false;
- }
- }
- }
-
- return true;
- }
-
- private boolean parsePackageItemInfo(Package owner, PackageItemInfo outInfo,
- String[] outError, String tag, TypedArray sa,
- int nameRes, int labelRes, int iconRes) {
- String name = sa.getNonResourceString(nameRes);
- if (name == null) {
- outError[0] = tag + " does not specify android:name";
- return false;
- }
-
- outInfo.name
- = buildClassName(owner.applicationInfo.packageName, name, outError);
- if (outInfo.name == null) {
- return false;
- }
-
- int iconVal = sa.getResourceId(iconRes, 0);
- if (iconVal != 0) {
- outInfo.icon = iconVal;
- outInfo.nonLocalizedLabel = null;
- }
-
- TypedValue v = sa.peekValue(labelRes);
- if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
- outInfo.nonLocalizedLabel = v.coerceToString();
- }
-
- outInfo.packageName = owner.packageName;
-
- return true;
- }
-
- private boolean parseComponentInfo(Package owner, int flags,
- ComponentInfo outInfo, String[] outError, String tag, TypedArray sa,
- int nameRes, int labelRes, int iconRes, int processRes,
- int enabledRes) {
- if (!parsePackageItemInfo(owner, outInfo, outError, tag, sa,
- nameRes, labelRes, iconRes)) {
- return false;
- }
-
- if (processRes != 0) {
- outInfo.processName = buildProcessName(owner.applicationInfo.packageName,
- owner.applicationInfo.processName, sa.getNonResourceString(processRes),
- flags, mSeparateProcesses, outError);
- }
- outInfo.enabled = sa.getBoolean(enabledRes, true);
-
- return outError[0] == null;
- }
-
- private Activity parseActivity(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, int flags, String[] outError,
- boolean receiver) throws XmlPullParserException, IOException {
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestActivity);
-
- Activity a = new Activity(owner);
-
- if (!parseComponentInfo(owner, flags, a.info, outError,
- receiver ? "<receiver>" : "<activity>", sa,
- com.android.internal.R.styleable.AndroidManifestActivity_name,
- com.android.internal.R.styleable.AndroidManifestActivity_label,
- com.android.internal.R.styleable.AndroidManifestActivity_icon,
- com.android.internal.R.styleable.AndroidManifestActivity_process,
- com.android.internal.R.styleable.AndroidManifestActivity_enabled)) {
- sa.recycle();
- return null;
- }
-
- final boolean setExported = sa.hasValue(
- com.android.internal.R.styleable.AndroidManifestActivity_exported);
- if (setExported) {
- a.info.exported = sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivity_exported, false);
- }
-
- a.component = new ComponentName(owner.applicationInfo.packageName,
- a.info.name);
-
- a.info.theme = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestActivity_theme, 0);
-
- String str;
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestActivity_permission);
- if (str == null) {
- a.info.permission = owner.applicationInfo.permission;
- } else {
- a.info.permission = str.length() > 0 ? str.toString().intern() : null;
- }
-
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestActivity_taskAffinity);
- a.info.taskAffinity = buildTaskAffinityName(owner.applicationInfo.packageName,
- owner.applicationInfo.taskAffinity, str, outError);
-
- a.info.flags = 0;
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivity_multiprocess,
- false)) {
- a.info.flags |= ActivityInfo.FLAG_MULTIPROCESS;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivity_finishOnTaskLaunch,
- false)) {
- a.info.flags |= ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivity_clearTaskOnLaunch,
- false)) {
- a.info.flags |= ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivity_noHistory,
- false)) {
- a.info.flags |= ActivityInfo.FLAG_NO_HISTORY;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivity_alwaysRetainTaskState,
- false)) {
- a.info.flags |= ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivity_stateNotNeeded,
- false)) {
- a.info.flags |= ActivityInfo.FLAG_STATE_NOT_NEEDED;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivity_excludeFromRecents,
- false)) {
- a.info.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
- }
-
- if (sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivity_allowTaskReparenting,
- (owner.applicationInfo.flags&ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING) != 0)) {
- a.info.flags |= ActivityInfo.FLAG_ALLOW_TASK_REPARENTING;
- }
-
- if (!receiver) {
- a.info.launchMode = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestActivity_launchMode,
- ActivityInfo.LAUNCH_MULTIPLE);
- a.info.screenOrientation = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestActivity_screenOrientation,
- ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
- a.info.configChanges = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestActivity_configChanges,
- 0);
- a.info.softInputMode = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestActivity_windowSoftInputMode,
- 0);
- } else {
- a.info.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
- a.info.configChanges = 0;
- }
-
- sa.recycle();
-
- if (outError[0] != null) {
- return null;
- }
-
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
-
- if (parser.getName().equals("intent-filter")) {
- ActivityIntentInfo intent = new ActivityIntentInfo(a);
- if (!parseIntent(res, parser, attrs, flags, intent, outError, !receiver)) {
- return null;
- }
- if (intent.countActions() == 0) {
- Log.w(TAG, "Intent filter for activity " + intent
- + " defines no actions");
- } else {
- a.intents.add(intent);
- }
- } else if (parser.getName().equals("meta-data")) {
- if ((a.metaData=parseMetaData(res, parser, attrs, a.metaData,
- outError)) == null) {
- return null;
- }
- } else {
- if (!RIGID_PARSER) {
- Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
- if (receiver) {
- Log.w(TAG, "Unknown element under <receiver>: " + parser.getName());
- } else {
- Log.w(TAG, "Unknown element under <activity>: " + parser.getName());
- }
- XmlUtils.skipCurrentTag(parser);
- continue;
- }
- if (receiver) {
- outError[0] = "Bad element under <receiver>: " + parser.getName();
- } else {
- outError[0] = "Bad element under <activity>: " + parser.getName();
- }
- return null;
- }
- }
-
- if (!setExported) {
- a.info.exported = a.intents.size() > 0;
- }
-
- return a;
- }
-
- private Activity parseActivityAlias(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, int flags, String[] outError,
- boolean receiver) throws XmlPullParserException, IOException {
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestActivityAlias);
-
- String targetActivity = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestActivityAlias_targetActivity);
- if (targetActivity == null) {
- outError[0] = "<activity-alias> does not specify android:targetActivity";
- sa.recycle();
- return null;
- }
-
- targetActivity = buildClassName(owner.applicationInfo.packageName,
- targetActivity, outError);
- if (targetActivity == null) {
- sa.recycle();
- return null;
- }
-
- Activity a = new Activity(owner);
- Activity target = null;
-
- final int NA = owner.activities.size();
- for (int i=0; i<NA; i++) {
- Activity t = owner.activities.get(i);
- if (targetActivity.equals(t.info.name)) {
- target = t;
- break;
- }
- }
-
- if (target == null) {
- outError[0] = "<activity-alias> target activity " + targetActivity
- + " not found in manifest";
- sa.recycle();
- return null;
- }
-
- a.info.targetActivity = targetActivity;
-
- a.info.configChanges = target.info.configChanges;
- a.info.flags = target.info.flags;
- a.info.icon = target.info.icon;
- a.info.labelRes = target.info.labelRes;
- a.info.launchMode = target.info.launchMode;
- a.info.nonLocalizedLabel = target.info.nonLocalizedLabel;
- a.info.processName = target.info.processName;
- a.info.screenOrientation = target.info.screenOrientation;
- a.info.taskAffinity = target.info.taskAffinity;
- a.info.theme = target.info.theme;
-
- if (!parseComponentInfo(owner, flags, a.info, outError,
- receiver ? "<receiver>" : "<activity>", sa,
- com.android.internal.R.styleable.AndroidManifestActivityAlias_name,
- com.android.internal.R.styleable.AndroidManifestActivityAlias_label,
- com.android.internal.R.styleable.AndroidManifestActivityAlias_icon,
- 0,
- com.android.internal.R.styleable.AndroidManifestActivityAlias_enabled)) {
- sa.recycle();
- return null;
- }
-
- final boolean setExported = sa.hasValue(
- com.android.internal.R.styleable.AndroidManifestActivityAlias_exported);
- if (setExported) {
- a.info.exported = sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestActivityAlias_exported, false);
- }
-
- a.component = new ComponentName(owner.applicationInfo.packageName,
- a.info.name);
-
- String str;
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestActivityAlias_permission);
- if (str != null) {
- a.info.permission = str.length() > 0 ? str.toString().intern() : null;
- }
-
- sa.recycle();
-
- if (outError[0] != null) {
- return null;
- }
-
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
-
- if (parser.getName().equals("intent-filter")) {
- ActivityIntentInfo intent = new ActivityIntentInfo(a);
- if (!parseIntent(res, parser, attrs, flags, intent, outError, true)) {
- return null;
- }
- if (intent.countActions() == 0) {
- Log.w(TAG, "Intent filter for activity alias " + intent
- + " defines no actions");
- } else {
- a.intents.add(intent);
- }
- } else if (parser.getName().equals("meta-data")) {
- if ((a.metaData=parseMetaData(res, parser, attrs, a.metaData,
- outError)) == null) {
- return null;
- }
- } else {
- if (!RIGID_PARSER) {
- Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
- Log.w(TAG, "Unknown element under <activity-alias>: " + parser.getName());
- XmlUtils.skipCurrentTag(parser);
- continue;
- }
- outError[0] = "Bad element under <activity-alias>: " + parser.getName();
- return null;
- }
- }
-
- if (!setExported) {
- a.info.exported = a.intents.size() > 0;
- }
-
- return a;
- }
-
- private Provider parseProvider(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
- throws XmlPullParserException, IOException {
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestProvider);
-
- Provider p = new Provider(owner);
-
- if (!parseComponentInfo(owner, flags, p.info, outError, "<provider>", sa,
- com.android.internal.R.styleable.AndroidManifestProvider_name,
- com.android.internal.R.styleable.AndroidManifestProvider_label,
- com.android.internal.R.styleable.AndroidManifestProvider_icon,
- com.android.internal.R.styleable.AndroidManifestProvider_process,
- com.android.internal.R.styleable.AndroidManifestProvider_enabled)) {
- sa.recycle();
- return null;
- }
-
- p.info.exported = sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestProvider_exported, true);
-
- p.component = new ComponentName(owner.applicationInfo.packageName,
- p.info.name);
-
- String cpname = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestProvider_authorities);
-
- p.info.isSyncable = sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestProvider_syncable,
- false);
-
- String permission = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestProvider_permission);
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestProvider_readPermission);
- if (str == null) {
- str = permission;
- }
- if (str == null) {
- p.info.readPermission = owner.applicationInfo.permission;
- } else {
- p.info.readPermission =
- str.length() > 0 ? str.toString().intern() : null;
- }
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestProvider_writePermission);
- if (str == null) {
- str = permission;
- }
- if (str == null) {
- p.info.writePermission = owner.applicationInfo.permission;
- } else {
- p.info.writePermission =
- str.length() > 0 ? str.toString().intern() : null;
- }
-
- p.info.grantUriPermissions = sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestProvider_grantUriPermissions,
- false);
-
- p.info.multiprocess = sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestProvider_multiprocess,
- false);
-
- p.info.initOrder = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestProvider_initOrder,
- 0);
-
- sa.recycle();
-
- if (cpname == null) {
- outError[0] = "<provider> does not incude authorities attribute";
- return null;
- }
- p.info.authority = cpname.intern();
-
- if (!parseProviderTags(res, parser, attrs, p, outError)) {
- return null;
- }
-
- return p;
- }
-
- private boolean parseProviderTags(Resources res,
- XmlPullParser parser, AttributeSet attrs,
- Provider outInfo, String[] outError)
- throws XmlPullParserException, IOException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
-
- if (parser.getName().equals("meta-data")) {
- if ((outInfo.metaData=parseMetaData(res, parser, attrs,
- outInfo.metaData, outError)) == null) {
- return false;
- }
- } else if (parser.getName().equals("grant-uri-permission")) {
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestGrantUriPermission);
-
- PatternMatcher pa = null;
-
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestGrantUriPermission_path);
- if (str != null) {
- pa = new PatternMatcher(str, PatternMatcher.PATTERN_LITERAL);
- }
-
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPrefix);
- if (str != null) {
- pa = new PatternMatcher(str, PatternMatcher.PATTERN_PREFIX);
- }
-
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestGrantUriPermission_pathPattern);
- if (str != null) {
- pa = new PatternMatcher(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
- }
-
- sa.recycle();
-
- if (pa != null) {
- if (outInfo.info.uriPermissionPatterns == null) {
- outInfo.info.uriPermissionPatterns = new PatternMatcher[1];
- outInfo.info.uriPermissionPatterns[0] = pa;
- } else {
- final int N = outInfo.info.uriPermissionPatterns.length;
- PatternMatcher[] newp = new PatternMatcher[N+1];
- System.arraycopy(outInfo.info.uriPermissionPatterns, 0, newp, 0, N);
- newp[N] = pa;
- outInfo.info.uriPermissionPatterns = newp;
- }
- outInfo.info.grantUriPermissions = true;
- }
- XmlUtils.skipCurrentTag(parser);
-
- } else {
- if (!RIGID_PARSER) {
- Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
- Log.w(TAG, "Unknown element under <provider>: "
- + parser.getName());
- XmlUtils.skipCurrentTag(parser);
- continue;
- }
- outError[0] = "Bad element under <provider>: "
- + parser.getName();
- return false;
- }
- }
- return true;
- }
-
- private Service parseService(Package owner, Resources res,
- XmlPullParser parser, AttributeSet attrs, int flags, String[] outError)
- throws XmlPullParserException, IOException {
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestService);
-
- Service s = new Service(owner);
-
- if (!parseComponentInfo(owner, flags, s.info, outError, "<service>", sa,
- com.android.internal.R.styleable.AndroidManifestService_name,
- com.android.internal.R.styleable.AndroidManifestService_label,
- com.android.internal.R.styleable.AndroidManifestService_icon,
- com.android.internal.R.styleable.AndroidManifestService_process,
- com.android.internal.R.styleable.AndroidManifestService_enabled)) {
- sa.recycle();
- return null;
- }
-
- final boolean setExported = sa.hasValue(
- com.android.internal.R.styleable.AndroidManifestService_exported);
- if (setExported) {
- s.info.exported = sa.getBoolean(
- com.android.internal.R.styleable.AndroidManifestService_exported, false);
- }
-
- s.component = new ComponentName(owner.applicationInfo.packageName,
- s.info.name);
-
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestService_permission);
- if (str == null) {
- s.info.permission = owner.applicationInfo.permission;
- } else {
- s.info.permission = str.length() > 0 ? str.toString().intern() : null;
- }
-
- sa.recycle();
-
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
-
- if (parser.getName().equals("intent-filter")) {
- ServiceIntentInfo intent = new ServiceIntentInfo(s);
- if (!parseIntent(res, parser, attrs, flags, intent, outError, false)) {
- return null;
- }
-
- s.intents.add(intent);
- } else if (parser.getName().equals("meta-data")) {
- if ((s.metaData=parseMetaData(res, parser, attrs, s.metaData,
- outError)) == null) {
- return null;
- }
- } else {
- if (!RIGID_PARSER) {
- Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
- Log.w(TAG, "Unknown element under <service>: "
- + parser.getName());
- XmlUtils.skipCurrentTag(parser);
- continue;
- }
- outError[0] = "Bad element under <service>: "
- + parser.getName();
- return null;
- }
- }
-
- if (!setExported) {
- s.info.exported = s.intents.size() > 0;
- }
-
- return s;
- }
-
- private boolean parseAllMetaData(Resources res,
- XmlPullParser parser, AttributeSet attrs, String tag,
- Component outInfo, String[] outError)
- throws XmlPullParserException, IOException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
-
- if (parser.getName().equals("meta-data")) {
- if ((outInfo.metaData=parseMetaData(res, parser, attrs,
- outInfo.metaData, outError)) == null) {
- return false;
- }
- } else {
- if (!RIGID_PARSER) {
- Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
- Log.w(TAG, "Unknown element under " + tag + ": "
- + parser.getName());
- XmlUtils.skipCurrentTag(parser);
- continue;
- }
- outError[0] = "Bad element under " + tag + ": "
- + parser.getName();
- return false;
- }
- }
- return true;
- }
-
- private Bundle parseMetaData(Resources res,
- XmlPullParser parser, AttributeSet attrs,
- Bundle data, String[] outError)
- throws XmlPullParserException, IOException {
-
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestMetaData);
-
- if (data == null) {
- data = new Bundle();
- }
-
- String name = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestMetaData_name);
- if (name == null) {
- outError[0] = "<meta-data> requires an android:name attribute";
- sa.recycle();
- return null;
- }
-
- boolean success = true;
-
- TypedValue v = sa.peekValue(
- com.android.internal.R.styleable.AndroidManifestMetaData_resource);
- if (v != null && v.resourceId != 0) {
- //Log.i(TAG, "Meta data ref " + name + ": " + v);
- data.putInt(name, v.resourceId);
- } else {
- v = sa.peekValue(
- com.android.internal.R.styleable.AndroidManifestMetaData_value);
- //Log.i(TAG, "Meta data " + name + ": " + v);
- if (v != null) {
- if (v.type == TypedValue.TYPE_STRING) {
- CharSequence cs = v.coerceToString();
- data.putString(name, cs != null ? cs.toString() : null);
- } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
- data.putBoolean(name, v.data != 0);
- } else if (v.type >= TypedValue.TYPE_FIRST_INT
- && v.type <= TypedValue.TYPE_LAST_INT) {
- data.putInt(name, v.data);
- } else if (v.type == TypedValue.TYPE_FLOAT) {
- data.putFloat(name, v.getFloat());
- } else {
- if (!RIGID_PARSER) {
- Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
- Log.w(TAG, "<meta-data> only supports string, integer, float, color, boolean, and resource reference types");
- } else {
- outError[0] = "<meta-data> only supports string, integer, float, color, boolean, and resource reference types";
- data = null;
- }
- }
- } else {
- outError[0] = "<meta-data> requires an android:value or android:resource attribute";
- data = null;
- }
- }
-
- sa.recycle();
-
- XmlUtils.skipCurrentTag(parser);
-
- return data;
- }
-
- private static final String ANDROID_RESOURCES
- = "http://schemas.android.com/apk/res/android";
-
- private boolean parseIntent(Resources res,
- XmlPullParser parser, AttributeSet attrs, int flags,
- IntentInfo outInfo, String[] outError, boolean isActivity)
- throws XmlPullParserException, IOException {
-
- TypedArray sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestIntentFilter);
-
- int priority = sa.getInt(
- com.android.internal.R.styleable.AndroidManifestIntentFilter_priority, 0);
- if (priority > 0 && isActivity && (flags&PARSE_IS_SYSTEM) == 0) {
- Log.w(TAG, "Activity with priority > 0, forcing to 0 at "
- + parser.getPositionDescription());
- priority = 0;
- }
- outInfo.setPriority(priority);
-
- TypedValue v = sa.peekValue(
- com.android.internal.R.styleable.AndroidManifestIntentFilter_label);
- if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
- outInfo.nonLocalizedLabel = v.coerceToString();
- }
-
- outInfo.icon = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestIntentFilter_icon, 0);
-
- sa.recycle();
-
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != parser.END_DOCUMENT
- && (type != parser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == parser.END_TAG || type == parser.TEXT) {
- continue;
- }
-
- String nodeName = parser.getName();
- if (nodeName.equals("action")) {
- String value = attrs.getAttributeValue(
- ANDROID_RESOURCES, "name");
- if (value == null || value == "") {
- outError[0] = "No value supplied for <android:name>";
- return false;
- }
- XmlUtils.skipCurrentTag(parser);
-
- outInfo.addAction(value);
- } else if (nodeName.equals("category")) {
- String value = attrs.getAttributeValue(
- ANDROID_RESOURCES, "name");
- if (value == null || value == "") {
- outError[0] = "No value supplied for <android:name>";
- return false;
- }
- XmlUtils.skipCurrentTag(parser);
-
- outInfo.addCategory(value);
-
- } else if (nodeName.equals("data")) {
- sa = res.obtainAttributes(attrs,
- com.android.internal.R.styleable.AndroidManifestData);
-
- String str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_mimeType);
- if (str != null) {
- try {
- outInfo.addDataType(str);
- } catch (IntentFilter.MalformedMimeTypeException e) {
- outError[0] = e.toString();
- sa.recycle();
- return false;
- }
- }
-
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_scheme);
- if (str != null) {
- outInfo.addDataScheme(str);
- }
-
- String host = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_host);
- String port = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_port);
- if (host != null) {
- outInfo.addDataAuthority(host, port);
- }
-
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_path);
- if (str != null) {
- outInfo.addDataPath(str, PatternMatcher.PATTERN_LITERAL);
- }
-
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_pathPrefix);
- if (str != null) {
- outInfo.addDataPath(str, PatternMatcher.PATTERN_PREFIX);
- }
-
- str = sa.getNonResourceString(
- com.android.internal.R.styleable.AndroidManifestData_pathPattern);
- if (str != null) {
- outInfo.addDataPath(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
- }
-
- sa.recycle();
- XmlUtils.skipCurrentTag(parser);
- } else if (!RIGID_PARSER) {
- Log.w(TAG, "Problem in package " + mArchiveSourcePath + ":");
- Log.w(TAG, "Unknown element under <intent-filter>: " + parser.getName());
- XmlUtils.skipCurrentTag(parser);
- } else {
- outError[0] = "Bad element under <intent-filter>: " + parser.getName();
- return false;
- }
- }
-
- outInfo.hasDefault = outInfo.hasCategory(Intent.CATEGORY_DEFAULT);
- if (false) {
- String cats = "";
- Iterator<String> it = outInfo.categoriesIterator();
- while (it != null && it.hasNext()) {
- cats += " " + it.next();
- }
- System.out.println("Intent d=" +
- outInfo.hasDefault + ", cat=" + cats);
- }
-
- return true;
- }
-
- public final static class Package {
- public final String packageName;
-
- // For now we only support one application per package.
- public final ApplicationInfo applicationInfo = new ApplicationInfo();
-
- public final ArrayList<Permission> permissions = new ArrayList<Permission>(0);
- public final ArrayList<PermissionGroup> permissionGroups = new ArrayList<PermissionGroup>(0);
- public final ArrayList<Activity> activities = new ArrayList<Activity>(0);
- public final ArrayList<Activity> receivers = new ArrayList<Activity>(0);
- public final ArrayList<Provider> providers = new ArrayList<Provider>(0);
- public final ArrayList<Service> services = new ArrayList<Service>(0);
- public final ArrayList<Instrumentation> instrumentation = new ArrayList<Instrumentation>(0);
-
- public final ArrayList<String> requestedPermissions = new ArrayList<String>();
-
- public final ArrayList<String> usesLibraries = new ArrayList<String>();
- public String[] usesLibraryFiles = null;
-
- // We store the application meta-data independently to avoid multiple unwanted references
- public Bundle mAppMetaData = null;
-
- // If this is a 3rd party app, this is the path of the zip file.
- public String mPath;
-
- // True if this package is part of the system image.
- public boolean mSystem;
-
- // The version code declared for this package.
- public int mVersionCode;
-
- // The version name declared for this package.
- public String mVersionName;
-
- // The shared user id that this package wants to use.
- public String mSharedUserId;
-
- // The shared user label that this package wants to use.
- public int mSharedUserLabel;
-
- // Signatures that were read from the package.
- public Signature mSignatures[];
-
- // For use by package manager service for quick lookup of
- // preferred up order.
- public int mPreferredOrder = 0;
-
- // Additional data supplied by callers.
- public Object mExtras;
-
- /*
- * Applications hardware preferences
- */
- public final ArrayList<ConfigurationInfo> configPreferences =
- new ArrayList<ConfigurationInfo>();
-
- public Package(String _name) {
- packageName = _name;
- applicationInfo.packageName = _name;
- applicationInfo.uid = -1;
- }
-
- public String toString() {
- return "Package{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + packageName + "}";
- }
- }
-
- public static class Component<II extends IntentInfo> {
- public final Package owner;
- public final ArrayList<II> intents = new ArrayList<II>(0);
- public ComponentName component;
- public Bundle metaData;
-
- public Component(Package _owner) {
- owner = _owner;
- }
-
- public Component(Component<II> clone) {
- owner = clone.owner;
- metaData = clone.metaData;
- }
- }
-
- public final static class Permission extends Component<IntentInfo> {
- public final PermissionInfo info;
- public boolean tree;
- public PermissionGroup group;
-
- public Permission(Package _owner) {
- super(_owner);
- info = new PermissionInfo();
- }
-
- public Permission(Package _owner, PermissionInfo _info) {
- super(_owner);
- info = _info;
- }
-
- public String toString() {
- return "Permission{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + info.name + "}";
- }
- }
-
- public final static class PermissionGroup extends Component<IntentInfo> {
- public final PermissionGroupInfo info;
-
- public PermissionGroup(Package _owner) {
- super(_owner);
- info = new PermissionGroupInfo();
- }
-
- public PermissionGroup(Package _owner, PermissionGroupInfo _info) {
- super(_owner);
- info = _info;
- }
-
- public String toString() {
- return "PermissionGroup{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + info.name + "}";
- }
- }
-
- private static boolean copyNeeded(int flags, Package p, Bundle metaData) {
- if ((flags & PackageManager.GET_META_DATA) != 0
- && (metaData != null || p.mAppMetaData != null)) {
- return true;
- }
- if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0
- && p.usesLibraryFiles != null) {
- return true;
- }
- return false;
- }
-
- public static ApplicationInfo generateApplicationInfo(Package p, int flags) {
- if (p == null) return null;
- if (!copyNeeded(flags, p, null)) {
- return p.applicationInfo;
- }
-
- // Make shallow copy so we can store the metadata/libraries safely
- ApplicationInfo ai = new ApplicationInfo(p.applicationInfo);
- if ((flags & PackageManager.GET_META_DATA) != 0) {
- ai.metaData = p.mAppMetaData;
- }
- if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0) {
- ai.sharedLibraryFiles = p.usesLibraryFiles;
- }
- return ai;
- }
-
- public static final PermissionInfo generatePermissionInfo(
- Permission p, int flags) {
- if (p == null) return null;
- if ((flags&PackageManager.GET_META_DATA) == 0) {
- return p.info;
- }
- PermissionInfo pi = new PermissionInfo(p.info);
- pi.metaData = p.metaData;
- return pi;
- }
-
- public static final PermissionGroupInfo generatePermissionGroupInfo(
- PermissionGroup pg, int flags) {
- if (pg == null) return null;
- if ((flags&PackageManager.GET_META_DATA) == 0) {
- return pg.info;
- }
- PermissionGroupInfo pgi = new PermissionGroupInfo(pg.info);
- pgi.metaData = pg.metaData;
- return pgi;
- }
-
- public final static class Activity extends Component<ActivityIntentInfo> {
- public final ActivityInfo info =
- new ActivityInfo();
-
- public Activity(Package _owner) {
- super(_owner);
- info.applicationInfo = owner.applicationInfo;
- }
-
- public String toString() {
- return "Activity{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + component.flattenToString() + "}";
- }
- }
-
- public static final ActivityInfo generateActivityInfo(Activity a,
- int flags) {
- if (a == null) return null;
- if (!copyNeeded(flags, a.owner, a.metaData)) {
- return a.info;
- }
- // Make shallow copies so we can store the metadata safely
- ActivityInfo ai = new ActivityInfo(a.info);
- ai.metaData = a.metaData;
- ai.applicationInfo = generateApplicationInfo(a.owner, flags);
- return ai;
- }
-
- public final static class Service extends Component<ServiceIntentInfo> {
- public final ServiceInfo info =
- new ServiceInfo();
-
- public Service(Package _owner) {
- super(_owner);
- info.applicationInfo = owner.applicationInfo;
- }
-
- public String toString() {
- return "Service{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + component.flattenToString() + "}";
- }
- }
-
- public static final ServiceInfo generateServiceInfo(Service s, int flags) {
- if (s == null) return null;
- if (!copyNeeded(flags, s.owner, s.metaData)) {
- return s.info;
- }
- // Make shallow copies so we can store the metadata safely
- ServiceInfo si = new ServiceInfo(s.info);
- si.metaData = s.metaData;
- si.applicationInfo = generateApplicationInfo(s.owner, flags);
- return si;
- }
-
- public final static class Provider extends Component {
- public final ProviderInfo info;
- public boolean syncable;
-
- public Provider(Package _owner) {
- super(_owner);
- info = new ProviderInfo();
- info.applicationInfo = owner.applicationInfo;
- syncable = false;
- }
-
- public Provider(Provider existingProvider) {
- super(existingProvider);
- this.info = existingProvider.info;
- this.syncable = existingProvider.syncable;
- }
-
- public String toString() {
- return "Provider{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + info.name + "}";
- }
- }
-
- public static final ProviderInfo generateProviderInfo(Provider p,
- int flags) {
- if (p == null) return null;
- if (!copyNeeded(flags, p.owner, p.metaData)
- && ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) != 0
- || p.info.uriPermissionPatterns == null)) {
- return p.info;
- }
- // Make shallow copies so we can store the metadata safely
- ProviderInfo pi = new ProviderInfo(p.info);
- pi.metaData = p.metaData;
- if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) {
- pi.uriPermissionPatterns = null;
- }
- pi.applicationInfo = generateApplicationInfo(p.owner, flags);
- return pi;
- }
-
- public final static class Instrumentation extends Component {
- public final InstrumentationInfo info =
- new InstrumentationInfo();
-
- public Instrumentation(Package _owner) {
- super(_owner);
- }
-
- public String toString() {
- return "Instrumentation{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + component.flattenToString() + "}";
- }
- }
-
- public static final InstrumentationInfo generateInstrumentationInfo(
- Instrumentation i, int flags) {
- if (i == null) return null;
- if ((flags&PackageManager.GET_META_DATA) == 0) {
- return i.info;
- }
- InstrumentationInfo ii = new InstrumentationInfo(i.info);
- ii.metaData = i.metaData;
- return ii;
- }
-
- public static class IntentInfo extends IntentFilter {
- public boolean hasDefault;
- public int labelRes;
- public CharSequence nonLocalizedLabel;
- public int icon;
- }
-
- public final static class ActivityIntentInfo extends IntentInfo {
- public final Activity activity;
-
- public ActivityIntentInfo(Activity _activity) {
- activity = _activity;
- }
-
- public String toString() {
- return "ActivityIntentInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + activity.info.name + "}";
- }
- }
-
- public final static class ServiceIntentInfo extends IntentInfo {
- public final Service service;
-
- public ServiceIntentInfo(Service _service) {
- service = _service;
- }
-
- public String toString() {
- return "ServiceIntentInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + service.info.name + "}";
- }
- }
-}
diff --git a/core/java/android/content/pm/PackageStats.aidl b/core/java/android/content/pm/PackageStats.aidl
deleted file mode 100755
index 8c9786f..0000000
--- a/core/java/android/content/pm/PackageStats.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable PackageStats;
diff --git a/core/java/android/content/pm/PackageStats.java b/core/java/android/content/pm/PackageStats.java
deleted file mode 100755
index 66c6efd..0000000
--- a/core/java/android/content/pm/PackageStats.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-
-/**
- * implementation of PackageStats associated with a
- * application package.
- */
-public class PackageStats implements Parcelable {
- public String packageName;
- public long codeSize;
- public long dataSize;
- public long cacheSize;
-
- public static final Parcelable.Creator<PackageStats> CREATOR
- = new Parcelable.Creator<PackageStats>() {
- public PackageStats createFromParcel(Parcel in) {
- return new PackageStats(in);
- }
-
- public PackageStats[] newArray(int size) {
- return new PackageStats[size];
- }
- };
-
- public String toString() {
- return "PackageStats{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + packageName + "}";
- }
-
- public PackageStats(String pkgName) {
- packageName = pkgName;
- }
-
- public PackageStats(Parcel source) {
- packageName = source.readString();
- codeSize = source.readLong();
- dataSize = source.readLong();
- cacheSize = source.readLong();
- }
-
- public PackageStats(PackageStats pStats) {
- packageName = pStats.packageName;
- codeSize = pStats.codeSize;
- dataSize = pStats.dataSize;
- cacheSize = pStats.cacheSize;
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags){
- dest.writeString(packageName);
- dest.writeLong(codeSize);
- dest.writeLong(dataSize);
- dest.writeLong(cacheSize);
- }
-}
diff --git a/core/java/android/content/pm/PermissionGroupInfo.aidl b/core/java/android/content/pm/PermissionGroupInfo.aidl
deleted file mode 100755
index 9f215f1..0000000
--- a/core/java/android/content/pm/PermissionGroupInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2008, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable PermissionGroupInfo;
diff --git a/core/java/android/content/pm/PermissionGroupInfo.java b/core/java/android/content/pm/PermissionGroupInfo.java
deleted file mode 100644
index 02eb816..0000000
--- a/core/java/android/content/pm/PermissionGroupInfo.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-/**
- * Information you can retrieve about a particular security permission
- * group known to the system. This corresponds to information collected from the
- * AndroidManifest.xml's &lt;permission-group&gt; tags.
- */
-public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
- /**
- * A string resource identifier (in the package's resources) of this
- * permission's description. From the "description" attribute or,
- * if not set, 0.
- */
- public int descriptionRes;
-
- /**
- * The description string provided in the AndroidManifest file, if any. You
- * probably don't want to use this, since it will be null if the description
- * is in a resource. You probably want
- * {@link PermissionInfo#loadDescription} instead.
- */
- public CharSequence nonLocalizedDescription;
-
- public PermissionGroupInfo() {
- }
-
- public PermissionGroupInfo(PermissionGroupInfo orig) {
- super(orig);
- descriptionRes = orig.descriptionRes;
- nonLocalizedDescription = orig.nonLocalizedDescription;
- }
-
- /**
- * Retrieve the textual description of this permission. This
- * will call back on the given PackageManager to load the description from
- * the application.
- *
- * @param pm A PackageManager from which the label can be loaded; usually
- * the PackageManager from which you originally retrieved this item.
- *
- * @return Returns a CharSequence containing the permission's description.
- * If there is no description, null is returned.
- */
- public CharSequence loadDescription(PackageManager pm) {
- if (nonLocalizedDescription != null) {
- return nonLocalizedDescription;
- }
- if (descriptionRes != 0) {
- CharSequence label = pm.getText(packageName, descriptionRes, null);
- if (label != null) {
- return label;
- }
- }
- return null;
- }
-
- public String toString() {
- return "PermissionGroupInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + name + "}";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- super.writeToParcel(dest, parcelableFlags);
- dest.writeInt(descriptionRes);
- TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
- }
-
- public static final Creator<PermissionGroupInfo> CREATOR =
- new Creator<PermissionGroupInfo>() {
- public PermissionGroupInfo createFromParcel(Parcel source) {
- return new PermissionGroupInfo(source);
- }
- public PermissionGroupInfo[] newArray(int size) {
- return new PermissionGroupInfo[size];
- }
- };
-
- private PermissionGroupInfo(Parcel source) {
- super(source);
- descriptionRes = source.readInt();
- nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
- }
-}
diff --git a/core/java/android/content/pm/PermissionInfo.aidl b/core/java/android/content/pm/PermissionInfo.aidl
deleted file mode 100755
index 5a7d4f4..0000000
--- a/core/java/android/content/pm/PermissionInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable PermissionInfo;
diff --git a/core/java/android/content/pm/PermissionInfo.java b/core/java/android/content/pm/PermissionInfo.java
deleted file mode 100644
index 3cc884b..0000000
--- a/core/java/android/content/pm/PermissionInfo.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-/**
- * Information you can retrieve about a particular security permission
- * known to the system. This corresponds to information collected from the
- * AndroidManifest.xml's &lt;permission&gt; tags.
- */
-public class PermissionInfo extends PackageItemInfo implements Parcelable {
- /**
- * A normal application value for {@link #protectionLevel}, corresponding
- * to the <code>normal</code> value of
- * {@link android.R.attr#protectionLevel}.
- */
- public static final int PROTECTION_NORMAL = 0;
-
- /**
- * Dangerous value for {@link #protectionLevel}, corresponding
- * to the <code>dangerous</code> value of
- * {@link android.R.attr#protectionLevel}.
- */
- public static final int PROTECTION_DANGEROUS = 1;
-
- /**
- * System-level value for {@link #protectionLevel}, corresponding
- * to the <code>signature</code> value of
- * {@link android.R.attr#protectionLevel}.
- */
- public static final int PROTECTION_SIGNATURE = 2;
-
- /**
- * System-level value for {@link #protectionLevel}, corresponding
- * to the <code>signatureOrSystem</code> value of
- * {@link android.R.attr#protectionLevel}.
- */
- public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;
-
- /**
- * The group this permission is a part of, as per
- * {@link android.R.attr#permissionGroup}.
- */
- public String group;
-
- /**
- * A string resource identifier (in the package's resources) of this
- * permission's description. From the "description" attribute or,
- * if not set, 0.
- */
- public int descriptionRes;
-
- /**
- * The description string provided in the AndroidManifest file, if any. You
- * probably don't want to use this, since it will be null if the description
- * is in a resource. You probably want
- * {@link PermissionInfo#loadDescription} instead.
- */
- public CharSequence nonLocalizedDescription;
-
- /**
- * The level of access this permission is protecting, as per
- * {@link android.R.attr#protectionLevel}. Values may be
- * {@link #PROTECTION_NORMAL}, {@link #PROTECTION_DANGEROUS}, or
- * {@link #PROTECTION_SIGNATURE}.
- */
- public int protectionLevel;
-
- public PermissionInfo() {
- }
-
- public PermissionInfo(PermissionInfo orig) {
- super(orig);
- group = orig.group;
- descriptionRes = orig.descriptionRes;
- protectionLevel = orig.protectionLevel;
- nonLocalizedDescription = orig.nonLocalizedDescription;
- }
-
- /**
- * Retrieve the textual description of this permission. This
- * will call back on the given PackageManager to load the description from
- * the application.
- *
- * @param pm A PackageManager from which the label can be loaded; usually
- * the PackageManager from which you originally retrieved this item.
- *
- * @return Returns a CharSequence containing the permission's description.
- * If there is no description, null is returned.
- */
- public CharSequence loadDescription(PackageManager pm) {
- if (nonLocalizedDescription != null) {
- return nonLocalizedDescription;
- }
- if (descriptionRes != 0) {
- CharSequence label = pm.getText(packageName, descriptionRes, null);
- if (label != null) {
- return label;
- }
- }
- return null;
- }
-
- public String toString() {
- return "PermissionInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + name + "}";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- super.writeToParcel(dest, parcelableFlags);
- dest.writeString(group);
- dest.writeInt(descriptionRes);
- dest.writeInt(protectionLevel);
- TextUtils.writeToParcel(nonLocalizedDescription, dest, parcelableFlags);
- }
-
- public static final Creator<PermissionInfo> CREATOR =
- new Creator<PermissionInfo>() {
- public PermissionInfo createFromParcel(Parcel source) {
- return new PermissionInfo(source);
- }
- public PermissionInfo[] newArray(int size) {
- return new PermissionInfo[size];
- }
- };
-
- private PermissionInfo(Parcel source) {
- super(source);
- group = source.readString();
- descriptionRes = source.readInt();
- protectionLevel = source.readInt();
- nonLocalizedDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
- }
-}
diff --git a/core/java/android/content/pm/ProviderInfo.aidl b/core/java/android/content/pm/ProviderInfo.aidl
deleted file mode 100755
index 18fbc8a..0000000
--- a/core/java/android/content/pm/ProviderInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable ProviderInfo;
diff --git a/core/java/android/content/pm/ProviderInfo.java b/core/java/android/content/pm/ProviderInfo.java
deleted file mode 100644
index b67ddf6..0000000
--- a/core/java/android/content/pm/ProviderInfo.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.PatternMatcher;
-
-/**
- * Holds information about a specific
- * {@link android.content.ContentProvider content provider}. This is returned by
- * {@link android.content.pm.PackageManager#resolveContentProvider(java.lang.String, int)
- * PackageManager.resolveContentProvider()}.
- */
-public final class ProviderInfo extends ComponentInfo
- implements Parcelable {
- /** The name provider is published under content:// */
- public String authority = null;
-
- /** Optional permission required for read-only access this content
- * provider. */
- public String readPermission = null;
-
- /** Optional permission required for read/write access this content
- * provider. */
- public String writePermission = null;
-
- /** If true, additional permissions to specific Uris in this content
- * provider can be granted, as per the
- * {@link android.R.styleable#AndroidManifestProvider_grantUriPermissions
- * grantUriPermissions} attribute.
- */
- public boolean grantUriPermissions = false;
-
- /**
- * If non-null, these are the patterns that are allowed for granting URI
- * permissions. Any URI that does not match one of these patterns will not
- * allowed to be granted. If null, all URIs are allowed. The
- * {@link PackageManager#GET_URI_PERMISSION_PATTERNS
- * PackageManager.GET_URI_PERMISSION_PATTERNS} flag must be specified for
- * this field to be filled in.
- */
- public PatternMatcher[] uriPermissionPatterns = null;
-
- /** If true, this content provider allows multiple instances of itself
- * to run in different process. If false, a single instances is always
- * run in {@link #processName}. */
- public boolean multiprocess = false;
-
- /** Used to control initialization order of single-process providers
- * running in the same process. Higher goes first. */
- public int initOrder = 0;
-
- /** Whether or not this provider is syncable. */
- public boolean isSyncable = false;
-
- public ProviderInfo() {
- }
-
- public ProviderInfo(ProviderInfo orig) {
- super(orig);
- authority = orig.authority;
- readPermission = orig.readPermission;
- writePermission = orig.writePermission;
- grantUriPermissions = orig.grantUriPermissions;
- uriPermissionPatterns = orig.uriPermissionPatterns;
- multiprocess = orig.multiprocess;
- initOrder = orig.initOrder;
- isSyncable = orig.isSyncable;
- }
-
- public int describeContents() {
- return 0;
- }
-
- @Override public void writeToParcel(Parcel out, int parcelableFlags) {
- super.writeToParcel(out, parcelableFlags);
- out.writeString(authority);
- out.writeString(readPermission);
- out.writeString(writePermission);
- out.writeInt(grantUriPermissions ? 1 : 0);
- out.writeTypedArray(uriPermissionPatterns, parcelableFlags);
- out.writeInt(multiprocess ? 1 : 0);
- out.writeInt(initOrder);
- out.writeInt(isSyncable ? 1 : 0);
- }
-
- public static final Parcelable.Creator<ProviderInfo> CREATOR
- = new Parcelable.Creator<ProviderInfo>() {
- public ProviderInfo createFromParcel(Parcel in) {
- return new ProviderInfo(in);
- }
-
- public ProviderInfo[] newArray(int size) {
- return new ProviderInfo[size];
- }
- };
-
- public String toString() {
- return "ContentProviderInfo{name=" + authority + " className=" + name
- + " isSyncable=" + (isSyncable ? "true" : "false") + "}";
- }
-
- private ProviderInfo(Parcel in) {
- super(in);
- authority = in.readString();
- readPermission = in.readString();
- writePermission = in.readString();
- grantUriPermissions = in.readInt() != 0;
- uriPermissionPatterns = in.createTypedArray(PatternMatcher.CREATOR);
- multiprocess = in.readInt() != 0;
- initOrder = in.readInt();
- isSyncable = in.readInt() != 0;
- }
-}
diff --git a/core/java/android/content/pm/ResolveInfo.aidl b/core/java/android/content/pm/ResolveInfo.aidl
deleted file mode 100755
index b4e7f8b..0000000
--- a/core/java/android/content/pm/ResolveInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable ResolveInfo;
diff --git a/core/java/android/content/pm/ResolveInfo.java b/core/java/android/content/pm/ResolveInfo.java
deleted file mode 100644
index ee49c02..0000000
--- a/core/java/android/content/pm/ResolveInfo.java
+++ /dev/null
@@ -1,280 +0,0 @@
-package android.content.pm;
-
-import android.content.IntentFilter;
-import android.graphics.drawable.Drawable;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-import android.util.Printer;
-
-import java.text.Collator;
-import java.util.Comparator;
-
-/**
- * Information that is returned from resolving an intent
- * against an IntentFilter. This partially corresponds to
- * information collected from the AndroidManifest.xml's
- * &lt;intent&gt; tags.
- */
-public class ResolveInfo implements Parcelable {
- /**
- * The activity that corresponds to this resolution match, if this
- * resolution is for an activity. One and only one of this and
- * serviceInfo must be non-null.
- */
- public ActivityInfo activityInfo;
-
- /**
- * The service that corresponds to this resolution match, if this
- * resolution is for a service. One and only one of this and
- * activityInfo must be non-null.
- */
- public ServiceInfo serviceInfo;
-
- /**
- * The IntentFilter that was matched for this ResolveInfo.
- */
- public IntentFilter filter;
-
- /**
- * The declared priority of this match. Comes from the "priority"
- * attribute or, if not set, defaults to 0. Higher values are a higher
- * priority.
- */
- public int priority;
-
- /**
- * Order of result according to the user's preference. If the user
- * has not set a preference for this result, the value is 0; higher
- * values are a higher priority.
- */
- public int preferredOrder;
-
- /**
- * The system's evaluation of how well the activity matches the
- * IntentFilter. This is a match constant, a combination of
- * {@link IntentFilter#MATCH_CATEGORY_MASK IntentFilter.MATCH_CATEGORY_MASK}
- * and {@link IntentFilter#MATCH_ADJUSTMENT_MASK IntentFiler.MATCH_ADJUSTMENT_MASK}.
- */
- public int match;
-
- /**
- * Only set when returned by
- * {@link PackageManager#queryIntentActivityOptions}, this tells you
- * which of the given specific intents this result came from. 0 is the
- * first in the list, < 0 means it came from the generic Intent query.
- */
- public int specificIndex = -1;
-
- /**
- * This filter has specified the Intent.CATEGORY_DEFAULT, meaning it
- * would like to be considered a default action that the user can
- * perform on this data.
- */
- public boolean isDefault;
-
- /**
- * A string resource identifier (in the package's resources) of this
- * match's label. From the "label" attribute or, if not set, 0.
- */
- public int labelRes;
-
- /**
- * The actual string retrieve from <var>labelRes</var> or null if none
- * was provided.
- */
- public CharSequence nonLocalizedLabel;
-
- /**
- * A drawable resource identifier (in the package's resources) of this
- * match's icon. From the "icon" attribute or, if not set, 0.
- */
- public int icon;
-
- /**
- * Retrieve the current textual label associated with this resolution. This
- * will call back on the given PackageManager to load the label from
- * the application.
- *
- * @param pm A PackageManager from which the label can be loaded; usually
- * the PackageManager from which you originally retrieved this item.
- *
- * @return Returns a CharSequence containing the resolutions's label. If the
- * item does not have a label, its name is returned.
- */
- public CharSequence loadLabel(PackageManager pm) {
- if (nonLocalizedLabel != null) {
- return nonLocalizedLabel;
- }
- ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
- ApplicationInfo ai = ci.applicationInfo;
- CharSequence label;
- if (labelRes != 0) {
- label = pm.getText(ci.packageName, labelRes, ai);
- if (label != null) {
- return label;
- }
- }
- return ci.loadLabel(pm);
- }
-
- /**
- * Retrieve the current graphical icon associated with this resolution. This
- * will call back on the given PackageManager to load the icon from
- * the application.
- *
- * @param pm A PackageManager from which the icon can be loaded; usually
- * the PackageManager from which you originally retrieved this item.
- *
- * @return Returns a Drawable containing the resolution's icon. If the
- * item does not have an icon, the default activity icon is returned.
- */
- public Drawable loadIcon(PackageManager pm) {
- ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
- ApplicationInfo ai = ci.applicationInfo;
- Drawable dr;
- if (icon != 0) {
- dr = pm.getDrawable(ci.packageName, icon, ai);
- if (dr != null) {
- return dr;
- }
- }
- return ci.loadIcon(pm);
- }
-
- /**
- * Return the icon resource identifier to use for this match. If the
- * match defines an icon, that is used; else if the activity defines
- * an icon, that is used; else, the application icon is used.
- *
- * @return The icon associated with this match.
- */
- public final int getIconResource() {
- if (icon != 0) return icon;
- if (activityInfo != null) return activityInfo.getIconResource();
- if (serviceInfo != null) return serviceInfo.getIconResource();
- return 0;
- }
-
- public void dump(Printer pw, String prefix) {
- if (filter != null) {
- pw.println(prefix + "Filter:");
- filter.dump(pw, prefix + " ");
- } else {
- pw.println(prefix + "Filter: null");
- }
- pw.println(prefix + "priority=" + priority
- + " preferredOrder=" + preferredOrder
- + " match=0x" + Integer.toHexString(match)
- + " specificIndex=" + specificIndex
- + " isDefault=" + isDefault);
- pw.println(prefix + "labelRes=0x" + Integer.toHexString(labelRes)
- + " nonLocalizedLabel=" + nonLocalizedLabel
- + " icon=0x" + Integer.toHexString(icon));
- if (activityInfo != null) {
- pw.println(prefix + "ActivityInfo:");
- activityInfo.dump(pw, prefix + " ");
- } else if (serviceInfo != null) {
- pw.println(prefix + "ServiceInfo:");
- // TODO
- //serviceInfo.dump(pw, prefix + " ");
- }
- }
-
- public ResolveInfo() {
- }
-
- public String toString() {
- ComponentInfo ci = activityInfo != null ? activityInfo : serviceInfo;
- return "ResolveInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + ci.name + " p=" + priority + " o="
- + preferredOrder + " m=0x" + Integer.toHexString(match) + "}";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- if (activityInfo != null) {
- dest.writeInt(1);
- activityInfo.writeToParcel(dest, parcelableFlags);
- } else if (serviceInfo != null) {
- dest.writeInt(2);
- serviceInfo.writeToParcel(dest, parcelableFlags);
- } else {
- dest.writeInt(0);
- }
- if (filter != null) {
- dest.writeInt(1);
- filter.writeToParcel(dest, parcelableFlags);
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(priority);
- dest.writeInt(preferredOrder);
- dest.writeInt(match);
- dest.writeInt(specificIndex);
- dest.writeInt(labelRes);
- TextUtils.writeToParcel(nonLocalizedLabel, dest, parcelableFlags);
- dest.writeInt(icon);
- }
-
- public static final Creator<ResolveInfo> CREATOR
- = new Creator<ResolveInfo>() {
- public ResolveInfo createFromParcel(Parcel source) {
- return new ResolveInfo(source);
- }
- public ResolveInfo[] newArray(int size) {
- return new ResolveInfo[size];
- }
- };
-
- private ResolveInfo(Parcel source) {
- switch (source.readInt()) {
- case 1:
- activityInfo = ActivityInfo.CREATOR.createFromParcel(source);
- serviceInfo = null;
- break;
- case 2:
- serviceInfo = ServiceInfo.CREATOR.createFromParcel(source);
- activityInfo = null;
- break;
- default:
- activityInfo = null;
- serviceInfo = null;
- break;
- }
- if (source.readInt() != 0) {
- filter = IntentFilter.CREATOR.createFromParcel(source);
- }
- priority = source.readInt();
- preferredOrder = source.readInt();
- match = source.readInt();
- specificIndex = source.readInt();
- labelRes = source.readInt();
- nonLocalizedLabel
- = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
- icon = source.readInt();
- }
-
- public static class DisplayNameComparator
- implements Comparator<ResolveInfo> {
- public DisplayNameComparator(PackageManager pm) {
- mPM = pm;
- }
-
- public final int compare(ResolveInfo a, ResolveInfo b) {
- CharSequence sa = a.loadLabel(mPM);
- if (sa == null) sa = a.activityInfo.name;
- CharSequence sb = b.loadLabel(mPM);
- if (sb == null) sb = b.activityInfo.name;
-
- return sCollator.compare(sa.toString(), sb.toString());
- }
-
- private final Collator sCollator = Collator.getInstance();
- private PackageManager mPM;
- }
-}
diff --git a/core/java/android/content/pm/ServiceInfo.aidl b/core/java/android/content/pm/ServiceInfo.aidl
deleted file mode 100755
index 5ddae1a..0000000
--- a/core/java/android/content/pm/ServiceInfo.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable ServiceInfo;
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
deleted file mode 100644
index b60650c..0000000
--- a/core/java/android/content/pm/ServiceInfo.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package android.content.pm;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Information you can retrieve about a particular application
- * service. This corresponds to information collected from the
- * AndroidManifest.xml's &lt;service&gt; tags.
- */
-public class ServiceInfo extends ComponentInfo
- implements Parcelable {
- /**
- * Optional name of a permission required to be able to access this
- * Service. From the "permission" attribute.
- */
- public String permission;
-
- public ServiceInfo() {
- }
-
- public ServiceInfo(ServiceInfo orig) {
- super(orig);
- permission = orig.permission;
- }
-
- public String toString() {
- return "ServiceInfo{"
- + Integer.toHexString(System.identityHashCode(this))
- + " " + name + "}";
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- super.writeToParcel(dest, parcelableFlags);
- dest.writeString(permission);
- }
-
- public static final Creator<ServiceInfo> CREATOR =
- new Creator<ServiceInfo>() {
- public ServiceInfo createFromParcel(Parcel source) {
- return new ServiceInfo(source);
- }
- public ServiceInfo[] newArray(int size) {
- return new ServiceInfo[size];
- }
- };
-
- private ServiceInfo(Parcel source) {
- super(source);
- permission = source.readString();
- }
-}
diff --git a/core/java/android/content/pm/Signature.aidl b/core/java/android/content/pm/Signature.aidl
deleted file mode 100755
index 3a0d775..0000000
--- a/core/java/android/content/pm/Signature.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.pm;
-
-parcelable Signature;
diff --git a/core/java/android/content/pm/Signature.java b/core/java/android/content/pm/Signature.java
deleted file mode 100644
index 1bb3857..0000000
--- a/core/java/android/content/pm/Signature.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.pm;
-
-import android.content.ComponentName;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Arrays;
-
-/**
- * Opaque, immutable representation of a signature associated with an
- * application package.
- */
-public class Signature implements Parcelable {
- private final byte[] mSignature;
- private int mHashCode;
- private boolean mHaveHashCode;
- private String mString;
-
- /**
- * Create Signature from an existing raw byte array.
- */
- public Signature(byte[] signature) {
- mSignature = signature.clone();
- }
-
- /**
- * Create Signature from a text representation previously returned by
- * {@link #toChars} or {@link #toCharsString()}.
- */
- public Signature(String text) {
- final int N = text.length()/2;
- byte[] sig = new byte[N];
- for (int i=0; i<N; i++) {
- char c = text.charAt(i*2);
- byte b = (byte)(
- (c >= 'a' ? (c - 'a' + 10) : (c - '0'))<<4);
- c = text.charAt(i*2 + 1);
- b |= (byte)(c >= 'a' ? (c - 'a' + 10) : (c - '0'));
- sig[i] = b;
- }
- mSignature = sig;
- }
-
- /**
- * Encode the Signature as ASCII text.
- */
- public char[] toChars() {
- return toChars(null, null);
- }
-
- /**
- * Encode the Signature as ASCII text in to an existing array.
- *
- * @param existingArray Existing char array or null.
- * @param outLen Output parameter for the number of characters written in
- * to the array.
- * @return Returns either <var>existingArray</var> if it was large enough
- * to hold the ASCII representation, or a newly created char[] array if
- * needed.
- */
- public char[] toChars(char[] existingArray, int[] outLen) {
- byte[] sig = mSignature;
- final int N = sig.length;
- final int N2 = N*2;
- char[] text = existingArray == null || N2 > existingArray.length
- ? new char[N2] : existingArray;
- for (int j=0; j<N; j++) {
- byte v = sig[j];
- int d = (v>>4)&0xf;
- text[j*2] = (char)(d >= 10 ? ('a' + d - 10) : ('0' + d));
- d = v&0xf;
- text[j*2+1] = (char)(d >= 10 ? ('a' + d - 10) : ('0' + d));
- }
- if (outLen != null) outLen[0] = N;
- return text;
- }
-
- /**
- * Return the result of {@link #toChars()} as a String. This result is
- * cached so future calls will return the same String.
- */
- public String toCharsString() {
- if (mString != null) return mString;
- String str = new String(toChars());
- mString = str;
- return mString;
- }
-
- /**
- * @return the contents of this signature as a byte array.
- */
- public byte[] toByteArray() {
- byte[] bytes = new byte[mSignature.length];
- System.arraycopy(mSignature, 0, bytes, 0, mSignature.length);
- return bytes;
- }
-
- @Override
- public boolean equals(Object obj) {
- try {
- if (obj != null) {
- Signature other = (Signature)obj;
- return Arrays.equals(mSignature, other.mSignature);
- }
- } catch (ClassCastException e) {
- }
- return false;
- }
-
- @Override
- public int hashCode() {
- if (mHaveHashCode) {
- return mHashCode;
- }
- mHashCode = Arrays.hashCode(mSignature);
- mHaveHashCode = true;
- return mHashCode;
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int parcelableFlags) {
- dest.writeByteArray(mSignature);
- }
-
- public static final Parcelable.Creator<Signature> CREATOR
- = new Parcelable.Creator<Signature>() {
- public Signature createFromParcel(Parcel source) {
- return new Signature(source);
- }
-
- public Signature[] newArray(int size) {
- return new Signature[size];
- }
- };
-
- private Signature(Parcel source) {
- mSignature = source.createByteArray();
- }
-}
diff --git a/core/java/android/content/pm/package.html b/core/java/android/content/pm/package.html
deleted file mode 100644
index 766b7dd..0000000
--- a/core/java/android/content/pm/package.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<HTML>
-<BODY>
-Contains classes for accessing information about an
-application package, including information about its activities,
-permissions, services, signatures, and providers.
-</BODY>
-</HTML> \ No newline at end of file
diff --git a/core/java/android/content/res/AssetFileDescriptor.java b/core/java/android/content/res/AssetFileDescriptor.java
deleted file mode 100644
index 4a073f7..0000000
--- a/core/java/android/content/res/AssetFileDescriptor.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import android.os.ParcelFileDescriptor;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-/**
- * File descriptor of an entry in the AssetManager. This provides your own
- * 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 {
- private final ParcelFileDescriptor mFd;
- private final long mStartOffset;
- private final long mLength;
-
- /**
- * Create a new AssetFileDescriptor from the given values.
- */
- public AssetFileDescriptor(ParcelFileDescriptor fd, long startOffset,
- long length) {
- mFd = fd;
- mStartOffset = startOffset;
- mLength = length;
- }
-
- /**
- * The AssetFileDescriptor contains its own ParcelFileDescriptor, which
- * in addition to the normal FileDescriptor object also allows you to close
- * the descriptor when you are done with it.
- */
- public ParcelFileDescriptor getParcelFileDescriptor() {
- return mFd;
- }
-
- /**
- * Returns the FileDescriptor that can be used to read the data in the
- * file.
- */
- public FileDescriptor getFileDescriptor() {
- return mFd.getFileDescriptor();
- }
-
- /**
- * Returns the byte offset where this asset entry's data starts.
- */
- public long getStartOffset() {
- return mStartOffset;
- }
-
- /**
- * Returns the total number of bytes of this asset entry's data.
- */
- public long getLength() {
- return mLength;
- }
-
- /**
- * Convenience for calling <code>getParcelFileDescriptor().close()</code>.
- */
- public void close() throws IOException {
- mFd.close();
- }
-}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
deleted file mode 100644
index fadcb35..0000000
--- a/core/java/android/content/res/AssetManager.java
+++ /dev/null
@@ -1,697 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import android.os.ParcelFileDescriptor;
-import android.util.Config;
-import android.util.Log;
-import android.util.TypedValue;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-
-/**
- * Provides access to an application's raw asset files; see {@link Resources}
- * for the way most applications will want to retrieve their resource data.
- * This class presents a lower-level API that allows you to open and read raw
- * files that have been bundled with the application as a simple stream of
- * bytes.
- */
-public final class AssetManager {
- /* modes used when opening an asset */
-
- /**
- * Mode for {@link #open(String, int)}: no specific information about how
- * data will be accessed.
- */
- public static final int ACCESS_UNKNOWN = 0;
- /**
- * Mode for {@link #open(String, int)}: Read chunks, and seek forward and
- * backward.
- */
- public static final int ACCESS_RANDOM = 1;
- /**
- * Mode for {@link #open(String, int)}: Read sequentially, with an
- * occasional forward seek.
- */
- public static final int ACCESS_STREAMING = 2;
- /**
- * Mode for {@link #open(String, int)}: Attempt to load contents into
- * memory, for fast small reads.
- */
- public static final int ACCESS_BUFFER = 3;
-
- private static final String TAG = "AssetManager";
- private static final boolean localLOGV = Config.LOGV || false;
-
- private static final Object mSync = new Object();
- private static final TypedValue mValue = new TypedValue();
- private static final long[] mOffsets = new long[2];
- private static AssetManager mSystem = null;
-
- // For communication with native code.
- private int mObject;
-
- private StringBlock mStringBlocks[] = null;
-
- private int mNumRefs = 1;
- private boolean mOpen = true;
- private String mAssetDir;
- private String mAppName;
-
- /**
- * Create a new AssetManager containing only the basic system assets.
- * Applications will not generally use this method, instead retrieving the
- * appropriate asset manager with {@link Resources#getAssets}. Not for
- * use by applications.
- * {@hide}
- */
- public AssetManager() {
- synchronized (mSync) {
- init();
- if (localLOGV) Log.v(TAG, "New asset manager: " + this);
- ensureSystemAssets();
- }
- }
-
- private static void ensureSystemAssets() {
- synchronized (mSync) {
- if (mSystem == null) {
- AssetManager system = new AssetManager(true);
- system.makeStringBlocks(false);
- mSystem = system;
- }
- }
- }
-
- private AssetManager(boolean isSystem) {
- init();
- if (localLOGV) Log.v(TAG, "New asset manager: " + this);
- }
-
- /**
- * Return a global shared asset manager that provides access to only
- * system assets (no application assets).
- * {@hide}
- */
- public static AssetManager getSystem() {
- ensureSystemAssets();
- return mSystem;
- }
-
- /**
- * Close this asset manager.
- */
- public void close() {
- synchronized(mSync) {
- //System.out.println("Release: num=" + mNumRefs
- // + ", released=" + mReleased);
- if (mOpen) {
- mOpen = false;
- decRefsLocked();
- }
- }
- }
-
- /**
- * Retrieve the string value associated with a particular resource
- * identifier for the current configuration / skin.
- */
- /*package*/ final CharSequence getResourceText(int ident) {
- synchronized (mSync) {
- TypedValue tmpValue = mValue;
- int block = loadResourceValue(ident, tmpValue, true);
- if (block >= 0) {
- if (tmpValue.type == TypedValue.TYPE_STRING) {
- return mStringBlocks[block].get(tmpValue.data);
- }
- return tmpValue.coerceToString();
- }
- }
- return null;
- }
-
- /**
- * Retrieve the string value associated with a particular resource
- * identifier for the current configuration / skin.
- */
- /*package*/ final CharSequence getResourceBagText(int ident, int bagEntryId) {
- synchronized (mSync) {
- TypedValue tmpValue = mValue;
- int block = loadResourceBagValue(ident, bagEntryId, tmpValue, true);
- if (block >= 0) {
- if (tmpValue.type == TypedValue.TYPE_STRING) {
- return mStringBlocks[block].get(tmpValue.data);
- }
- return tmpValue.coerceToString();
- }
- }
- return null;
- }
-
- /**
- * Retrieve the string array associated with a particular resource
- * identifier.
- * @param id Resource id of the string array
- */
- /*package*/ final String[] getResourceStringArray(final int id) {
- String[] retArray = getArrayStringResource(id);
- return retArray;
- }
-
-
- /*package*/ final boolean getResourceValue(int ident,
- TypedValue outValue,
- boolean resolveRefs)
- {
- int block = loadResourceValue(ident, outValue, resolveRefs);
- if (block >= 0) {
- if (outValue.type != TypedValue.TYPE_STRING) {
- return true;
- }
- outValue.string = mStringBlocks[block].get(outValue.data);
- return true;
- }
- return false;
- }
-
- /**
- * Retrieve the text array associated with a particular resource
- * identifier.
- * @param id Resource id of the string array
- */
- /*package*/ final CharSequence[] getResourceTextArray(final int id) {
- int[] rawInfoArray = getArrayStringInfo(id);
- int rawInfoArrayLen = rawInfoArray.length;
- final int infoArrayLen = rawInfoArrayLen / 2;
- int block;
- int index;
- CharSequence[] retArray = new CharSequence[infoArrayLen];
- for (int i = 0, j = 0; i < rawInfoArrayLen; i = i + 2, j++) {
- block = rawInfoArray[i];
- index = rawInfoArray[i + 1];
- retArray[j] = index >= 0 ? mStringBlocks[block].get(index) : null;
- }
- return retArray;
- }
-
- /*package*/ final boolean getThemeValue(int theme, int ident,
- TypedValue outValue, boolean resolveRefs) {
- int block = loadThemeAttributeValue(theme, ident, outValue, resolveRefs);
- if (block >= 0) {
- if (outValue.type != TypedValue.TYPE_STRING) {
- return true;
- }
- StringBlock[] blocks = mStringBlocks;
- if (blocks == null) {
- ensureStringBlocks();
- }
- outValue.string = blocks[block].get(outValue.data);
- return true;
- }
- return false;
- }
-
- /*package*/ final void ensureStringBlocks() {
- if (mStringBlocks == null) {
- synchronized (mSync) {
- if (mStringBlocks == null) {
- makeStringBlocks(true);
- }
- }
- }
- }
-
- private final void makeStringBlocks(boolean copyFromSystem) {
- final int sysNum = copyFromSystem ? mSystem.mStringBlocks.length : 0;
- final int num = getStringBlockCount();
- mStringBlocks = new StringBlock[num];
- if (localLOGV) Log.v(TAG, "Making string blocks for " + this
- + ": " + num);
- for (int i=0; i<num; i++) {
- if (i < sysNum) {
- mStringBlocks[i] = mSystem.mStringBlocks[i];
- } else {
- mStringBlocks[i] = new StringBlock(getNativeStringBlock(i), true);
- }
- }
- }
-
- /*package*/ final CharSequence getPooledString(int block, int id) {
- //System.out.println("Get pooled: block=" + block
- // + ", id=#" + Integer.toHexString(id)
- // + ", blocks=" + mStringBlocks);
- return mStringBlocks[block-1].get(id);
- }
-
- /**
- * Open an asset using ACCESS_STREAMING mode. This provides access to
- * files that have been bundled with an application as assets -- that is,
- * files placed in to the "assets" directory.
- *
- * @param fileName The name of the asset to open. This name can be
- * hierarchical.
- *
- * @see #open(String, int)
- * @see #list
- */
- public final InputStream open(String fileName) throws IOException {
- return open(fileName, ACCESS_STREAMING);
- }
-
- /**
- * Open an asset using an explicit access mode, returning an InputStream to
- * read its contents. This provides access to files that have been bundled
- * with an application as assets -- that is, files placed in to the
- * "assets" directory.
- *
- * @param fileName The name of the asset to open. This name can be
- * hierarchical.
- * @param accessMode Desired access mode for retrieving the data.
- *
- * @see #ACCESS_UNKNOWN
- * @see #ACCESS_STREAMING
- * @see #ACCESS_RANDOM
- * @see #ACCESS_BUFFER
- * @see #open(String)
- * @see #list
- */
- public final InputStream open(String fileName, int accessMode)
- throws IOException {
- synchronized (mSync) {
- if (!mOpen) {
- throw new RuntimeException("Assetmanager has been closed");
- }
- int asset = openAsset(fileName, accessMode);
- if (asset != 0) {
- mNumRefs++;
- return new AssetInputStream(asset);
- }
- }
- throw new FileNotFoundException("Asset file: " + fileName);
- }
-
- public final AssetFileDescriptor openFd(String fileName)
- throws IOException {
- synchronized (mSync) {
- if (!mOpen) {
- throw new RuntimeException("Assetmanager has been closed");
- }
- ParcelFileDescriptor pfd = openAssetFd(fileName, mOffsets);
- if (pfd != null) {
- return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
- }
- }
- throw new FileNotFoundException("Asset file: " + fileName);
- }
-
- /**
- * Return a String array of all the assets at the given path.
- *
- * @param path A relative path within the assets, i.e., "docs/home.html".
- *
- * @return String[] Array of strings, one for each asset. These file
- * names are relative to 'path'. You can open the file by
- * concatenating 'path' and a name in the returned string (via
- * File) and passing that to open().
- *
- * @see #open
- */
- public native final String[] list(String path)
- throws IOException;
-
- /**
- * {@hide}
- * Open a non-asset file as an asset using ACCESS_STREAMING mode. This
- * provides direct access to all of the files included in an application
- * package (not only its assets). Applications should not normally use
- * this.
- *
- * @see #open(String)
- */
- public final InputStream openNonAsset(String fileName) throws IOException {
- return openNonAsset(0, fileName, ACCESS_STREAMING);
- }
-
- /**
- * {@hide}
- * Open a non-asset file as an asset using a specific access mode. This
- * provides direct access to all of the files included in an application
- * package (not only its assets). Applications should not normally use
- * this.
- *
- * @see #open(String, int)
- */
- public final InputStream openNonAsset(String fileName, int accessMode)
- throws IOException {
- return openNonAsset(0, fileName, accessMode);
- }
-
- /**
- * {@hide}
- * Open a non-asset in a specified package. Not for use by applications.
- *
- * @param cookie Identifier of the package to be opened.
- * @param fileName Name of the asset to retrieve.
- */
- public final InputStream openNonAsset(int cookie, String fileName)
- throws IOException {
- return openNonAsset(cookie, fileName, ACCESS_STREAMING);
- }
-
- /**
- * {@hide}
- * Open a non-asset in a specified package. Not for use by applications.
- *
- * @param cookie Identifier of the package to be opened.
- * @param fileName Name of the asset to retrieve.
- * @param accessMode Desired access mode for retrieving the data.
- */
- public final InputStream openNonAsset(int cookie, String fileName, int accessMode)
- throws IOException {
- synchronized (mSync) {
- if (!mOpen) {
- throw new RuntimeException("Assetmanager has been closed");
- }
- int asset = openNonAssetNative(cookie, fileName, accessMode);
- if (asset != 0) {
- mNumRefs++;
- return new AssetInputStream(asset);
- }
- }
- throw new FileNotFoundException("Asset absolute file: " + fileName);
- }
-
- public final AssetFileDescriptor openNonAssetFd(String fileName)
- throws IOException {
- return openNonAssetFd(0, fileName);
- }
-
- public final AssetFileDescriptor openNonAssetFd(int cookie,
- String fileName) throws IOException {
- synchronized (mSync) {
- if (!mOpen) {
- throw new RuntimeException("Assetmanager has been closed");
- }
- ParcelFileDescriptor pfd = openNonAssetFdNative(cookie,
- fileName, mOffsets);
- if (pfd != null) {
- return new AssetFileDescriptor(pfd, mOffsets[0], mOffsets[1]);
- }
- }
- throw new FileNotFoundException("Asset absolute file: " + fileName);
- }
-
- /**
- * Retrieve a parser for a compiled XML file.
- *
- * @param fileName The name of the file to retrieve.
- */
- public final XmlResourceParser openXmlResourceParser(String fileName)
- throws IOException {
- return openXmlResourceParser(0, fileName);
- }
-
- /**
- * Retrieve a parser for a compiled XML file.
- *
- * @param cookie Identifier of the package to be opened.
- * @param fileName The name of the file to retrieve.
- */
- public final XmlResourceParser openXmlResourceParser(int cookie,
- String fileName) throws IOException {
- XmlBlock block = openXmlBlockAsset(cookie, fileName);
- XmlResourceParser rp = block.newParser();
- block.close();
- return rp;
- }
-
- /**
- * {@hide}
- * Retrieve a non-asset as a compiled XML file. Not for use by
- * applications.
- *
- * @param fileName The name of the file to retrieve.
- */
- /*package*/ final XmlBlock openXmlBlockAsset(String fileName)
- throws IOException {
- return openXmlBlockAsset(0, fileName);
- }
-
- /**
- * {@hide}
- * Retrieve a non-asset as a compiled XML file. Not for use by
- * applications.
- *
- * @param cookie Identifier of the package to be opened.
- * @param fileName Name of the asset to retrieve.
- */
- /*package*/ final XmlBlock openXmlBlockAsset(int cookie, String fileName)
- throws IOException {
- synchronized (mSync) {
- if (!mOpen) {
- throw new RuntimeException("Assetmanager has been closed");
- }
- int xmlBlock = openXmlAssetNative(cookie, fileName);
- if (xmlBlock != 0) {
- mNumRefs++;
- return new XmlBlock(this, xmlBlock);
- }
- }
- throw new FileNotFoundException("Asset XML file: " + fileName);
- }
-
- /*package*/ void xmlBlockGone() {
- synchronized (mSync) {
- decRefsLocked();
- }
- }
-
- /*package*/ final int createTheme() {
- synchronized (mSync) {
- if (!mOpen) {
- throw new RuntimeException("Assetmanager has been closed");
- }
- mNumRefs++;
- return newTheme();
- }
- }
-
- /*package*/ final void releaseTheme(int theme) {
- synchronized (mSync) {
- deleteTheme(theme);
- decRefsLocked();
- }
- }
-
- protected void finalize() throws Throwable {
- destroy();
- }
-
- public final class AssetInputStream extends InputStream {
- public final int getAssetInt() {
- return mAsset;
- }
- private AssetInputStream(int asset)
- {
- mAsset = asset;
- mLength = getAssetLength(asset);
- }
- public final int read() throws IOException {
- return readAssetChar(mAsset);
- }
- public final boolean markSupported() {
- return true;
- }
- public final int available() throws IOException {
- long len = getAssetRemainingLength(mAsset);
- return len > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)len;
- }
- public final void close() throws IOException {
- synchronized (AssetManager.mSync) {
- if (mAsset != 0) {
- destroyAsset(mAsset);
- mAsset = 0;
- decRefsLocked();
- }
- }
- }
- public final void mark(int readlimit) {
- mMarkPos = seekAsset(mAsset, 0, 0);
- }
- public final void reset() throws IOException {
- seekAsset(mAsset, mMarkPos, -1);
- }
- public final int read(byte[] b) throws IOException {
- return readAsset(mAsset, b, 0, b.length);
- }
- public final int read(byte[] b, int off, int len) throws IOException {
- return readAsset(mAsset, b, off, len);
- }
- public final long skip(long n) throws IOException {
- long pos = seekAsset(mAsset, 0, 0);
- if ((pos+n) > mLength) {
- n = mLength-pos;
- }
- if (n > 0) {
- seekAsset(mAsset, n, 0);
- }
- return n;
- }
-
- protected void finalize() throws Throwable
- {
- close();
- }
-
- private int mAsset;
- private long mLength;
- private long mMarkPos;
- }
-
- /**
- * Add an additional set of assets to the asset manager. This can be
- * either a directory or ZIP file. Not for use by applications. A
- * zero return value indicates failure.
- * {@hide}
- */
- public native final int addAssetPath(String path);
-
- /**
- * Determine whether the state in this asset manager is up-to-date with
- * the files on the filesystem. If false is returned, you need to
- * instantiate a new AssetManager class to see the new data.
- * {@hide}
- */
- public native final boolean isUpToDate();
-
- /**
- * Change the locale being used by this asset manager. Not for use by
- * applications.
- * {@hide}
- */
- public native final void setLocale(String locale);
-
- /**
- * Get the locales that this asset manager contains data for.
- */
- public native final String[] getLocales();
-
- /**
- * Change the configuation used when retrieving resources. Not for use by
- * applications.
- * {@hide}
- */
- public native final void setConfiguration(int mcc, int mnc, String locale,
- int orientation, int touchscreen, int density, int keyboard,
- int keyboardHidden, int navigation, int screenWidth, int screenHeight,
- int majorVersion);
-
- /**
- * Retrieve the resource identifier for the given resource name.
- */
- /*package*/ native final int getResourceIdentifier(String type,
- String name,
- String defPackage);
-
- /*package*/ native final String getResourceName(int resid);
- /*package*/ native final String getResourcePackageName(int resid);
- /*package*/ native final String getResourceTypeName(int resid);
- /*package*/ native final String getResourceEntryName(int resid);
-
- private native final int openAsset(String fileName, int accessMode);
- private final native ParcelFileDescriptor openAssetFd(String fileName,
- long[] outOffsets) throws IOException;
- private native final int openNonAssetNative(int cookie, String fileName,
- int accessMode);
- private native ParcelFileDescriptor openNonAssetFdNative(int cookie,
- String fileName, long[] outOffsets) throws IOException;
- private native final void destroyAsset(int asset);
- private native final int readAssetChar(int asset);
- private native final int readAsset(int asset, byte[] b, int off, int len);
- private native final long seekAsset(int asset, long offset, int whence);
- private native final long getAssetLength(int asset);
- private native final long getAssetRemainingLength(int asset);
-
- /** Returns true if the resource was found, filling in mRetStringBlock and
- * mRetData. */
- private native final int loadResourceValue(int ident, TypedValue outValue,
- boolean resolve);
- /** Returns true if the resource was found, filling in mRetStringBlock and
- * mRetData. */
- private native final int loadResourceBagValue(int ident, int bagEntryId, TypedValue outValue,
- boolean resolve);
- /*package*/ static final int STYLE_NUM_ENTRIES = 5;
- /*package*/ static final int STYLE_TYPE = 0;
- /*package*/ static final int STYLE_DATA = 1;
- /*package*/ static final int STYLE_ASSET_COOKIE = 2;
- /*package*/ static final int STYLE_RESOURCE_ID = 3;
- /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4;
- /*package*/ native static final boolean applyStyle(int theme,
- int defStyleAttr, int defStyleRes, int xmlParser,
- int[] inAttrs, int[] outValues, int[] outIndices);
- /*package*/ native final boolean retrieveAttributes(
- int xmlParser, int[] inAttrs, int[] outValues, int[] outIndices);
- /*package*/ native final int getArraySize(int resource);
- /*package*/ native final int retrieveArray(int resource, int[] outValues);
- private native final int getStringBlockCount();
- private native final int getNativeStringBlock(int block);
-
- /**
- * {@hide}
- */
- public native final String getCookieName(int cookie);
-
- /**
- * {@hide}
- */
- public native static final int getGlobalAssetCount();
-
- /**
- * {@hide}
- */
- public native static final int getGlobalAssetManagerCount();
-
- private native final int newTheme();
- private native final void deleteTheme(int theme);
- /*package*/ native static final void applyThemeStyle(int theme, int styleRes, boolean force);
- /*package*/ native static final void copyTheme(int dest, int source);
- /*package*/ native static final int loadThemeAttributeValue(int theme, int ident,
- TypedValue outValue,
- boolean resolve);
- /*package*/ native static final void dumpTheme(int theme, int priority, String tag, String prefix);
-
- private native final int openXmlAssetNative(int cookie, String fileName);
-
- private native final String[] getArrayStringResource(int arrayRes);
- private native final int[] getArrayStringInfo(int arrayRes);
- /*package*/ native final int[] getArrayIntResource(int arrayRes);
-
- private native final void init();
- private native final void destroy();
-
- private final void decRefsLocked() {
- mNumRefs--;
- //System.out.println("Dec streams: mNumRefs=" + mNumRefs
- // + " mReleased=" + mReleased);
- if (mNumRefs == 0) {
- destroy();
- }
- }
-}
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
deleted file mode 100644
index 17cb687..0000000
--- a/core/java/android/content/res/ColorStateList.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import com.google.android.collect.Lists;
-
-import com.android.internal.util.ArrayUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.util.AttributeSet;
-import android.util.SparseArray;
-import android.util.StateSet;
-import android.util.Xml;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.util.Arrays;
-
-/**
- *
- * Lets you map {@link android.view.View} state sets to colors.
- *
- * {@link android.content.res.ColorStateList}s are created from XML resource files defined in the
- * "color" subdirectory directory of an application's resource directory. The XML file contains
- * a single "selector" element with a number of "item" elements inside. For example:
- *
- * <pre>
- * &lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
- * &lt;item android:state_focused="true" android:color="@color/testcolor1"/&gt;
- * &lt;item android:state_pressed="true" android:state_enabled="false" android:color="@color/testcolor2" /&gt;
- * &lt;item android:state_enabled="false" android:colore="@color/testcolor3" /&gt;
- * &lt;item android:state_active="true" android:color="@color/testcolor4" /&gt;
- * &lt;item android:color="@color/testcolor5"/&gt;
- * &lt;/selector&gt;
- * </pre>
- *
- * This defines a set of state spec / color pairs where each state spec specifies a set of
- * states that a view must either be in or not be in and the color specifies the color associated
- * with that spec. The list of state specs will be processed in order of the items in the XML file.
- * An item with no state spec is considered to match any set of states and is generally useful as
- * a final item to be used as a default. Note that if you have such an item before any other items
- * in the list then any subsequent items will end up being ignored.
- */
-public class ColorStateList implements Parcelable {
-
- private int[][] mStateSpecs; // must be parallel to mColors
- private int[] mColors; // must be parallel to mStateSpecs
- private int mDefaultColor = 0xffff0000;
-
- private static final int[][] EMPTY = new int[][] { new int[0] };
- private static final SparseArray<WeakReference<ColorStateList>> sCache =
- new SparseArray<WeakReference<ColorStateList>>();
-
- private ColorStateList() { }
-
- /**
- * Creates a ColorStateList that returns the specified mapping from
- * states to colors.
- */
- public ColorStateList(int[][] states, int[] colors) {
- mStateSpecs = states;
- mColors = colors;
-
- if (states.length > 0) {
- mDefaultColor = colors[0];
-
- for (int i = 0; i < states.length; i++) {
- if (states[i].length == 0) {
- mDefaultColor = colors[i];
- }
- }
- }
- }
-
- /**
- * Creates or retrieves a ColorStateList that always returns a single color.
- */
- public static ColorStateList valueOf(int color) {
- // TODO: should we collect these eventually?
- synchronized (sCache) {
- WeakReference<ColorStateList> ref = sCache.get(color);
- ColorStateList csl = ref != null ? ref.get() : null;
-
- if (csl != null) {
- return csl;
- }
-
- csl = new ColorStateList(EMPTY, new int[] { color });
- sCache.put(color, new WeakReference<ColorStateList>(csl));
- return csl;
- }
- }
-
- /**
- * Create a ColorStateList from an XML document, given a set of {@link Resources}.
- */
- public static ColorStateList createFromXml(Resources r, XmlPullParser parser)
- throws XmlPullParserException, IOException {
- AttributeSet attrs = Xml.asAttributeSet(parser);
-
- int type;
- while ((type=parser.next()) != XmlPullParser.START_TAG
- && type != XmlPullParser.END_DOCUMENT) {
- }
-
- if (type != XmlPullParser.START_TAG) {
- throw new XmlPullParserException("No start tag found");
- }
-
- 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 {
- ColorStateList colorStateList;
-
- final String name = parser.getName();
-
- if (name.equals("selector")) {
- colorStateList = new ColorStateList();
- } else {
- throw new XmlPullParserException(
- parser.getPositionDescription() + ": invalid drawable tag "
- + name);
- }
-
- colorStateList.inflate(r, parser, attrs);
- return colorStateList;
- }
-
- /**
- * Creates a new ColorStateList that has the same states and
- * colors as this one but where each color has the specified alpha value
- * (0-255).
- */
- public ColorStateList withAlpha(int alpha) {
- int[] colors = new int[mColors.length];
-
- int len = colors.length;
- for (int i = 0; i < len; i++) {
- colors[i] = (mColors[i] & 0xFFFFFF) | (alpha << 24);
- }
-
- return new ColorStateList(mStateSpecs, colors);
- }
-
- /**
- * Fill in this object based on the contents of an XML "selector" element.
- */
- private void inflate(Resources r, XmlPullParser parser, AttributeSet attrs)
- throws XmlPullParserException, IOException {
-
- int type;
-
- final int innerDepth = parser.getDepth()+1;
- int depth;
-
- int listAllocated = 20;
- int listSize = 0;
- int[] colorList = new int[listAllocated];
- int[][] stateSpecList = new int[listAllocated][];
-
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && ((depth=parser.getDepth()) >= innerDepth
- || type != XmlPullParser.END_TAG)) {
- if (type != XmlPullParser.START_TAG) {
- continue;
- }
-
- if (depth > innerDepth || !parser.getName().equals("item")) {
- continue;
- }
-
- int colorRes = 0;
- int color = 0xffff0000;
- boolean haveColor = false;
-
- int i;
- int j = 0;
- final int numAttrs = attrs.getAttributeCount();
- int[] stateSpec = new int[numAttrs];
- for (i = 0; i < numAttrs; i++) {
- final int stateResId = attrs.getAttributeNameResource(i);
- if (stateResId == 0) break;
- if (stateResId == com.android.internal.R.attr.color) {
- colorRes = attrs.getAttributeResourceValue(i, 0);
-
- if (colorRes == 0) {
- color = attrs.getAttributeIntValue(i, color);
- haveColor = true;
- }
- } else {
- stateSpec[j++] = attrs.getAttributeBooleanValue(i, false)
- ? stateResId
- : -stateResId;
- }
- }
- stateSpec = StateSet.trimStateSet(stateSpec, j);
-
- if (colorRes != 0) {
- color = r.getColor(colorRes);
- } else if (!haveColor) {
- throw new XmlPullParserException(
- parser.getPositionDescription()
- + ": <item> tag requires a 'android:color' attribute.");
- }
-
- if (listSize == 0 || stateSpec.length == 0) {
- mDefaultColor = color;
- }
-
- if (listSize + 1 >= listAllocated) {
- listAllocated = ArrayUtils.idealIntArraySize(listSize + 1);
-
- int[] ncolor = new int[listAllocated];
- System.arraycopy(colorList, 0, ncolor, 0, listSize);
-
- int[][] nstate = new int[listAllocated][];
- System.arraycopy(stateSpecList, 0, nstate, 0, listSize);
-
- colorList = ncolor;
- stateSpecList = nstate;
- }
-
- colorList[listSize] = color;
- stateSpecList[listSize] = stateSpec;
- listSize++;
- }
-
- mColors = new int[listSize];
- mStateSpecs = new int[listSize][];
- System.arraycopy(colorList, 0, mColors, 0, listSize);
- System.arraycopy(stateSpecList, 0, mStateSpecs, 0, listSize);
- }
-
- public boolean isStateful() {
- return mStateSpecs.length > 1;
- }
-
- /**
- * Return the color associated with the given set of {@link android.view.View} states.
- *
- * @param stateSet an array of {@link android.view.View} states
- * @param defaultColor the color to return if there's not state spec in this
- * {@link ColorStateList} that matches the stateSet.
- *
- * @return the color associated with that set of states in this {@link ColorStateList}.
- */
- public int getColorForState(int[] stateSet, int defaultColor) {
- final int setLength = mStateSpecs.length;
- for (int i = 0; i < setLength; i++) {
- int[] stateSpec = mStateSpecs[i];
- if (StateSet.stateSetMatches(stateSpec, stateSet)) {
- return mColors[i];
- }
- }
- return defaultColor;
- }
-
- /**
- * Return the default color in this {@link ColorStateList}.
- *
- * @return the default color in this {@link ColorStateList}.
- */
- public int getDefaultColor() {
- return mDefaultColor;
- }
-
- public String toString() {
- return "ColorStateList{" +
- "mStateSpecs=" + Arrays.deepToString(mStateSpecs) +
- "mColors=" + Arrays.toString(mColors) +
- "mDefaultColor=" + mDefaultColor + '}';
- }
-
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- final int N = mStateSpecs.length;
- dest.writeInt(N);
- for (int i=0; i<N; i++) {
- dest.writeIntArray(mStateSpecs[i]);
- }
- dest.writeArray(mStateSpecs);
- dest.writeIntArray(mColors);
- }
-
- public static final Parcelable.Creator<ColorStateList> CREATOR =
- new Parcelable.Creator<ColorStateList>() {
- public ColorStateList[] newArray(int size) {
- return new ColorStateList[size];
- }
-
- public ColorStateList createFromParcel(Parcel source) {
- final int N = source.readInt();
- int[][] stateSpecs = new int[N][];
- for (int i=0; i<N; i++) {
- stateSpecs[i] = source.createIntArray();
- }
- int[] colors = source.createIntArray();
- return new ColorStateList(stateSpecs, colors);
- }
- };
-}
diff --git a/core/java/android/content/res/Configuration.aidl b/core/java/android/content/res/Configuration.aidl
deleted file mode 100755
index bb7f2dd..0000000
--- a/core/java/android/content/res/Configuration.aidl
+++ /dev/null
@@ -1,21 +0,0 @@
-/* //device/java/android/android/view/WindowManager.aidl
-**
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.content.res;
-
-parcelable Configuration;
-
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
deleted file mode 100644
index 7e4b7ac..0000000
--- a/core/java/android/content/res/Configuration.java
+++ /dev/null
@@ -1,436 +0,0 @@
-package android.content.res;
-
-import android.content.pm.ActivityInfo;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import java.util.Locale;
-
-/**
- * This class describes all device configuration information that can
- * impact the resources the application retrieves. This includes both
- * user-specified configuration options (locale and scaling) as well
- * as dynamic device configuration (various types of input devices).
- */
-public final class Configuration implements Parcelable, Comparable<Configuration> {
- /**
- * Current user preference for the scaling factor for fonts, relative
- * to the base density scaling.
- */
- public float fontScale;
-
- /**
- * IMSI MCC (Mobile Country Code). 0 if undefined.
- */
- public int mcc;
-
- /**
- * IMSI MNC (Mobile Network Code). 0 if undefined.
- */
- public int mnc;
-
- /**
- * Current user preference for the locale.
- */
- public Locale locale;
-
- /**
- * Locale should persist on setting
- * @hide pending API council approval
- */
- public boolean userSetLocale;
-
- public static final int TOUCHSCREEN_UNDEFINED = 0;
- public static final int TOUCHSCREEN_NOTOUCH = 1;
- public static final int TOUCHSCREEN_STYLUS = 2;
- public static final int TOUCHSCREEN_FINGER = 3;
-
- /**
- * The kind of touch screen attached to the device.
- * One of: {@link #TOUCHSCREEN_NOTOUCH}, {@link #TOUCHSCREEN_STYLUS},
- * {@link #TOUCHSCREEN_FINGER}.
- */
- public int touchscreen;
-
- public static final int KEYBOARD_UNDEFINED = 0;
- public static final int KEYBOARD_NOKEYS = 1;
- public static final int KEYBOARD_QWERTY = 2;
- public static final int KEYBOARD_12KEY = 3;
-
- /**
- * The kind of keyboard attached to the device.
- * One of: {@link #KEYBOARD_QWERTY}, {@link #KEYBOARD_12KEY}.
- */
- public int keyboard;
-
- public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
- public static final int KEYBOARDHIDDEN_NO = 1;
- public static final int KEYBOARDHIDDEN_YES = 2;
- /** Constant matching actual resource implementation. {@hide} */
- public static final int KEYBOARDHIDDEN_SOFT = 3;
-
- /**
- * A flag indicating whether any keyboard is available. Unlike
- * {@link #hardKeyboardHidden}, this also takes into account a soft
- * keyboard, so if the hard keyboard is hidden but there is soft
- * keyboard available, it will be set to NO. Value is one of:
- * {@link #KEYBOARDHIDDEN_NO}, {@link #KEYBOARDHIDDEN_YES}.
- */
- public int keyboardHidden;
-
- public static final int HARDKEYBOARDHIDDEN_UNDEFINED = 0;
- public static final int HARDKEYBOARDHIDDEN_NO = 1;
- public static final int HARDKEYBOARDHIDDEN_YES = 2;
-
- /**
- * A flag indicating whether the hard keyboard has been hidden. This will
- * be set on a device with a mechanism to hide the keyboard from the
- * user, when that mechanism is closed. One of:
- * {@link #HARDKEYBOARDHIDDEN_NO}, {@link #HARDKEYBOARDHIDDEN_YES}.
- */
- public int hardKeyboardHidden;
-
- public static final int NAVIGATION_UNDEFINED = 0;
- public static final int NAVIGATION_NONAV = 1;
- public static final int NAVIGATION_DPAD = 2;
- public static final int NAVIGATION_TRACKBALL = 3;
- public static final int NAVIGATION_WHEEL = 4;
-
- /**
- * The kind of navigation method available on the device.
- * One of: {@link #NAVIGATION_DPAD}, {@link #NAVIGATION_TRACKBALL},
- * {@link #NAVIGATION_WHEEL}.
- */
- public int navigation;
-
- public static final int ORIENTATION_UNDEFINED = 0;
- public static final int ORIENTATION_PORTRAIT = 1;
- public static final int ORIENTATION_LANDSCAPE = 2;
- public static final int ORIENTATION_SQUARE = 3;
-
- /**
- * Overall orientation of the screen. May be one of
- * {@link #ORIENTATION_LANDSCAPE}, {@link #ORIENTATION_PORTRAIT},
- * or {@link #ORIENTATION_SQUARE}.
- */
- public int orientation;
-
- /**
- * Construct an invalid Configuration. You must call {@link #setToDefaults}
- * for this object to be valid. {@more}
- */
- public Configuration() {
- setToDefaults();
- }
-
- /**
- * Makes a deep copy suitable for modification.
- */
- public Configuration(Configuration o) {
- fontScale = o.fontScale;
- mcc = o.mcc;
- mnc = o.mnc;
- if (o.locale != null) {
- locale = (Locale) o.locale.clone();
- }
- userSetLocale = o.userSetLocale;
- touchscreen = o.touchscreen;
- keyboard = o.keyboard;
- keyboardHidden = o.keyboardHidden;
- hardKeyboardHidden = o.hardKeyboardHidden;
- navigation = o.navigation;
- orientation = o.orientation;
- }
-
- public String toString() {
- return "{ scale=" + fontScale + " imsi=" + mcc + "/" + mnc
- + " locale=" + locale
- + " touch=" + touchscreen + " key=" + keyboard + "/"
- + keyboardHidden + "/" + hardKeyboardHidden
- + " nav=" + navigation + " orien=" + orientation + " }";
- }
-
- /**
- * Set this object to the system defaults.
- */
- public void setToDefaults() {
- fontScale = 1;
- mcc = mnc = 0;
- locale = Locale.getDefault();
- userSetLocale = false;
- touchscreen = TOUCHSCREEN_UNDEFINED;
- keyboard = KEYBOARD_UNDEFINED;
- keyboardHidden = KEYBOARDHIDDEN_UNDEFINED;
- hardKeyboardHidden = HARDKEYBOARDHIDDEN_UNDEFINED;
- navigation = NAVIGATION_UNDEFINED;
- orientation = ORIENTATION_UNDEFINED;
- }
-
- /** {@hide} */
- @Deprecated public void makeDefault() {
- setToDefaults();
- }
-
- /**
- * Copy the fields from delta into this Configuration object, keeping
- * track of which ones have changed. Any undefined fields in
- * <var>delta</var> are ignored and not copied in to the current
- * Configuration.
- * @return Returns a bit mask of the changed fields, as per
- * {@link #diff}.
- */
- public int updateFrom(Configuration delta) {
- int changed = 0;
- if (delta.fontScale > 0 && fontScale != delta.fontScale) {
- changed |= ActivityInfo.CONFIG_FONT_SCALE;
- fontScale = delta.fontScale;
- }
- if (delta.mcc != 0 && mcc != delta.mcc) {
- changed |= ActivityInfo.CONFIG_MCC;
- mcc = delta.mcc;
- }
- if (delta.mnc != 0 && mnc != delta.mnc) {
- changed |= ActivityInfo.CONFIG_MNC;
- mnc = delta.mnc;
- }
- if (delta.locale != null
- && (locale == null || !locale.equals(delta.locale))) {
- changed |= ActivityInfo.CONFIG_LOCALE;
- locale = delta.locale != null
- ? (Locale) delta.locale.clone() : null;
- }
- if (delta.userSetLocale && (!userSetLocale || ((changed & ActivityInfo.CONFIG_LOCALE) != 0)))
- {
- userSetLocale = true;
- changed |= ActivityInfo.CONFIG_LOCALE;
- }
- if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
- && touchscreen != delta.touchscreen) {
- changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
- touchscreen = delta.touchscreen;
- }
- if (delta.keyboard != KEYBOARD_UNDEFINED
- && keyboard != delta.keyboard) {
- changed |= ActivityInfo.CONFIG_KEYBOARD;
- keyboard = delta.keyboard;
- }
- if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED
- && keyboardHidden != delta.keyboardHidden) {
- changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
- keyboardHidden = delta.keyboardHidden;
- }
- if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED
- && hardKeyboardHidden != delta.hardKeyboardHidden) {
- changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
- hardKeyboardHidden = delta.hardKeyboardHidden;
- }
- if (delta.navigation != NAVIGATION_UNDEFINED
- && navigation != delta.navigation) {
- changed |= ActivityInfo.CONFIG_NAVIGATION;
- navigation = delta.navigation;
- }
- if (delta.orientation != ORIENTATION_UNDEFINED
- && orientation != delta.orientation) {
- changed |= ActivityInfo.CONFIG_ORIENTATION;
- orientation = delta.orientation;
- }
-
- return changed;
- }
-
- /**
- * Return a bit mask of the differences between this Configuration
- * object and the given one. Does not change the values of either. Any
- * undefined fields in <var>delta</var> are ignored.
- * @return Returns a bit mask indicating which configuration
- * values has changed, containing any combination of
- * {@link android.content.pm.ActivityInfo#CONFIG_FONT_SCALE
- * PackageManager.ActivityInfo.CONFIG_FONT_SCALE},
- * {@link android.content.pm.ActivityInfo#CONFIG_MCC
- * PackageManager.ActivityInfo.CONFIG_MCC},
- * {@link android.content.pm.ActivityInfo#CONFIG_MNC
- * PackageManager.ActivityInfo.CONFIG_MNC},
- * {@link android.content.pm.ActivityInfo#CONFIG_LOCALE
- * PackageManager.ActivityInfo.CONFIG_LOCALE},
- * {@link android.content.pm.ActivityInfo#CONFIG_TOUCHSCREEN
- * PackageManager.ActivityInfo.CONFIG_TOUCHSCREEN},
- * {@link android.content.pm.ActivityInfo#CONFIG_KEYBOARD
- * PackageManager.ActivityInfo.CONFIG_KEYBOARD},
- * {@link android.content.pm.ActivityInfo#CONFIG_NAVIGATION
- * PackageManager.ActivityInfo.CONFIG_NAVIGATION}, or
- * {@link android.content.pm.ActivityInfo#CONFIG_ORIENTATION
- * PackageManager.ActivityInfo.CONFIG_ORIENTATION}.
- */
- public int diff(Configuration delta) {
- int changed = 0;
- if (delta.fontScale > 0 && fontScale != delta.fontScale) {
- changed |= ActivityInfo.CONFIG_FONT_SCALE;
- }
- if (delta.mcc != 0 && mcc != delta.mcc) {
- changed |= ActivityInfo.CONFIG_MCC;
- }
- if (delta.mnc != 0 && mnc != delta.mnc) {
- changed |= ActivityInfo.CONFIG_MNC;
- }
- if (delta.locale != null
- && (locale == null || !locale.equals(delta.locale))) {
- changed |= ActivityInfo.CONFIG_LOCALE;
- }
- if (delta.touchscreen != TOUCHSCREEN_UNDEFINED
- && touchscreen != delta.touchscreen) {
- changed |= ActivityInfo.CONFIG_TOUCHSCREEN;
- }
- if (delta.keyboard != KEYBOARD_UNDEFINED
- && keyboard != delta.keyboard) {
- changed |= ActivityInfo.CONFIG_KEYBOARD;
- }
- if (delta.keyboardHidden != KEYBOARDHIDDEN_UNDEFINED
- && keyboardHidden != delta.keyboardHidden) {
- changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
- }
- if (delta.hardKeyboardHidden != HARDKEYBOARDHIDDEN_UNDEFINED
- && hardKeyboardHidden != delta.hardKeyboardHidden) {
- changed |= ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
- }
- if (delta.navigation != NAVIGATION_UNDEFINED
- && navigation != delta.navigation) {
- changed |= ActivityInfo.CONFIG_NAVIGATION;
- }
- if (delta.orientation != ORIENTATION_UNDEFINED
- && orientation != delta.orientation) {
- changed |= ActivityInfo.CONFIG_ORIENTATION;
- }
-
- return changed;
- }
-
- /**
- * Determine if a new resource needs to be loaded from the bit set of
- * configuration changes returned by {@link #updateFrom(Configuration)}.
- *
- * @param configChanges The mask of changes configurations as returned by
- * {@link #updateFrom(Configuration)}.
- * @param interestingChanges The configuration changes that the resource
- * can handled, as given in {@link android.util.TypedValue#changingConfigurations}.
- *
- * @return Return true if the resource needs to be loaded, else false.
- */
- public static boolean needNewResources(int configChanges, int interestingChanges) {
- return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0;
- }
-
- /**
- * Parcelable methods
- */
- public int describeContents() {
- return 0;
- }
-
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeFloat(fontScale);
- dest.writeInt(mcc);
- dest.writeInt(mnc);
- if (locale == null) {
- dest.writeInt(0);
- } else {
- dest.writeInt(1);
- dest.writeString(locale.getLanguage());
- dest.writeString(locale.getCountry());
- dest.writeString(locale.getVariant());
- }
- if(userSetLocale) {
- dest.writeInt(1);
- } else {
- dest.writeInt(0);
- }
- dest.writeInt(touchscreen);
- dest.writeInt(keyboard);
- dest.writeInt(keyboardHidden);
- dest.writeInt(hardKeyboardHidden);
- dest.writeInt(navigation);
- dest.writeInt(orientation);
- }
-
- public static final Parcelable.Creator<Configuration> CREATOR
- = new Parcelable.Creator<Configuration>() {
- public Configuration createFromParcel(Parcel source) {
- return new Configuration(source);
- }
-
- public Configuration[] newArray(int size) {
- return new Configuration[size];
- }
- };
-
- /**
- * Construct this Configuration object, reading from the Parcel.
- */
- private Configuration(Parcel source) {
- fontScale = source.readFloat();
- mcc = source.readInt();
- mnc = source.readInt();
- if (source.readInt() != 0) {
- locale = new Locale(source.readString(), source.readString(),
- source.readString());
- }
- userSetLocale = (source.readInt()==1);
- touchscreen = source.readInt();
- keyboard = source.readInt();
- keyboardHidden = source.readInt();
- hardKeyboardHidden = source.readInt();
- navigation = source.readInt();
- orientation = source.readInt();
- }
-
- public int compareTo(Configuration that) {
- int n;
- float a = this.fontScale;
- float b = that.fontScale;
- if (a < b) return -1;
- if (a > b) return 1;
- n = this.mcc - that.mcc;
- if (n != 0) return n;
- n = this.mnc - that.mnc;
- if (n != 0) return n;
- n = this.locale.getLanguage().compareTo(that.locale.getLanguage());
- if (n != 0) return n;
- n = this.locale.getCountry().compareTo(that.locale.getCountry());
- if (n != 0) return n;
- n = this.locale.getVariant().compareTo(that.locale.getVariant());
- if (n != 0) return n;
- n = this.touchscreen - that.touchscreen;
- if (n != 0) return n;
- n = this.keyboard - that.keyboard;
- if (n != 0) return n;
- n = this.keyboardHidden - that.keyboardHidden;
- if (n != 0) return n;
- n = this.hardKeyboardHidden - that.hardKeyboardHidden;
- if (n != 0) return n;
- n = this.navigation - that.navigation;
- if (n != 0) return n;
- n = this.orientation - that.orientation;
- //if (n != 0) return n;
- return n;
- }
-
- public boolean equals(Configuration that) {
- if (that == null) return false;
- if (that == this) return true;
- return this.compareTo(that) == 0;
- }
-
- public boolean equals(Object that) {
- try {
- return equals((Configuration)that);
- } catch (ClassCastException e) {
- }
- return false;
- }
-
- public int hashCode() {
- return ((int)this.fontScale) + this.mcc + this.mnc
- + this.locale.hashCode() + this.touchscreen
- + this.keyboard + this.keyboardHidden + this.hardKeyboardHidden
- + this.navigation + this.orientation;
- }
-}
diff --git a/core/java/android/content/res/PluralRules.java b/core/java/android/content/res/PluralRules.java
deleted file mode 100644
index 2dce3c1..0000000
--- a/core/java/android/content/res/PluralRules.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import java.util.Locale;
-
-/*
- * Yuck-o. This is not the right way to implement this. When the ICU PluralRules
- * object has been integrated to android, we should switch to that. For now, yuck-o.
- */
-
-abstract class PluralRules {
-
- static final int QUANTITY_OTHER = 0x0000;
- static final int QUANTITY_ZERO = 0x0001;
- static final int QUANTITY_ONE = 0x0002;
- static final int QUANTITY_TWO = 0x0004;
- static final int QUANTITY_FEW = 0x0008;
- static final int QUANTITY_MANY = 0x0010;
-
- static final int ID_OTHER = 0x01000004;
-
- abstract int quantityForNumber(int n);
-
- final int attrForNumber(int n) {
- return PluralRules.attrForQuantity(quantityForNumber(n));
- }
-
- static final int attrForQuantity(int quantity) {
- // see include/utils/ResourceTypes.h
- switch (quantity) {
- case QUANTITY_ZERO: return 0x01000005;
- case QUANTITY_ONE: return 0x01000006;
- case QUANTITY_TWO: return 0x01000007;
- case QUANTITY_FEW: return 0x01000008;
- case QUANTITY_MANY: return 0x01000009;
- default: return ID_OTHER;
- }
- }
-
- static final String stringForQuantity(int quantity) {
- switch (quantity) {
- case QUANTITY_ZERO:
- return "zero";
- case QUANTITY_ONE:
- return "one";
- case QUANTITY_TWO:
- return "two";
- case QUANTITY_FEW:
- return "few";
- case QUANTITY_MANY:
- return "many";
- default:
- return "other";
- }
- }
-
- static final PluralRules ruleForLocale(Locale locale) {
- String lang = locale.getLanguage();
- if ("cs".equals(lang)) {
- if (cs == null) cs = new cs();
- return cs;
- }
- else {
- if (en == null) en = new en();
- return en;
- }
- }
-
- private static PluralRules cs;
- private static class cs extends PluralRules {
- int quantityForNumber(int n) {
- if (n == 1) {
- return QUANTITY_ONE;
- }
- else if (n >= 2 && n <= 4) {
- return QUANTITY_FEW;
- }
- else {
- return QUANTITY_OTHER;
- }
- }
- }
-
- private static PluralRules en;
- private static class en extends PluralRules {
- int quantityForNumber(int n) {
- if (n == 1) {
- return QUANTITY_ONE;
- }
- else {
- return QUANTITY_OTHER;
- }
- }
- }
-}
-
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
deleted file mode 100644
index 5a0daea..0000000
--- a/core/java/android/content/res/Resources.java
+++ /dev/null
@@ -1,1850 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.graphics.Movie;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.ColorDrawable;
-import android.os.Bundle;
-import android.os.SystemProperties;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.SparseArray;
-import android.util.TypedValue;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.ref.WeakReference;
-
-/**
- * Class for accessing an application's resources. This sits on top of the
- * asset manager of the application (accessible through getAssets()) and
- * provides a higher-level API for getting typed data from the assets.
- */
-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 int sSdkVersion = SystemProperties.getInt(
- "ro.build.version.sdk", 0);
- private static final Object mSync = new Object();
- private static Resources mSystem = null;
-
- // Information about preloaded resources. Note that they are not
- // protected by a lock, because while preloading in zygote we are all
- // single-threaded, and after that these are immutable.
- private static final SparseArray<Drawable.ConstantState> mPreloadedDrawables
- = new SparseArray<Drawable.ConstantState>();
- private static boolean mPreloaded;
-
- /*package*/ final TypedValue mTmpValue = new TypedValue();
-
- // These are protected by the mTmpValue lock.
- private final SparseArray<WeakReference<Drawable.ConstantState> > mDrawableCache
- = new SparseArray<WeakReference<Drawable.ConstantState> >();
- private final SparseArray<WeakReference<ColorStateList> > mColorStateListCache
- = new SparseArray<WeakReference<ColorStateList> >();
- private boolean mPreloading;
-
- /*package*/ TypedArray mCachedStyledAttributes = null;
-
- private int mLastCachedXmlBlockIndex = -1;
- private final int[] mCachedXmlBlockIds = { 0, 0, 0, 0 };
- private final XmlBlock[] mCachedXmlBlocks = new XmlBlock[4];
-
- /*package*/ final AssetManager mAssets;
- 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.
- */
- public static class NotFoundException extends RuntimeException {
- public NotFoundException() {
- }
-
- public NotFoundException(String name) {
- super(name);
- }
- };
-
- /**
- * Create a new Resources object on top of an existing set of assets in an
- * AssetManager.
- *
- * @param assets Previously created AssetManager.
- * @param metrics Current display metrics to consider when
- * selecting/computing resource values.
- * @param config Desired device configuration to consider when
- * selecting/computing resource values (optional).
- */
- public Resources(AssetManager assets, DisplayMetrics metrics,
- Configuration config) {
- mAssets = assets;
- mConfiguration.setToDefaults();
- mMetrics.setToDefaults();
- updateConfiguration(config, metrics);
- assets.ensureStringBlocks();
- }
-
- /**
- * Return a global shared Resources object that provides access to only
- * system resources (no application resources), and is not configured for
- * the current screen (can not use dimension units, does not change based
- * on orientation, etc).
- */
- public static Resources getSystem() {
- synchronized (mSync) {
- Resources ret = mSystem;
- if (ret == null) {
- ret = new Resources();
- mSystem = ret;
- }
-
- return ret;
- }
- }
-
- /**
- * Return the string value associated with a particular resource ID. The
- * returned object will be a String if this is a plain string; it will be
- * some other type of CharSequence if it is styled.
- * {@more}
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return CharSequence The string data associated with the resource, plus
- * possibly styled text information.
- */
- public CharSequence getText(int id) throws NotFoundException {
- CharSequence res = mAssets.getResourceText(id);
- if (res != null) {
- return res;
- }
- throw new NotFoundException("String resource ID #0x"
- + Integer.toHexString(id));
- }
-
- /**
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return CharSequence The string data associated with the resource, plus
- * possibly styled text information.
- */
- public CharSequence getQuantityText(int id, int quantity) throws NotFoundException {
- PluralRules rule = getPluralRule();
- CharSequence res = mAssets.getResourceBagText(id, rule.attrForNumber(quantity));
- if (res != null) {
- return res;
- }
- res = mAssets.getResourceBagText(id, PluralRules.ID_OTHER);
- if (res != null) {
- return res;
- }
- throw new NotFoundException("Plural resource ID #0x" + Integer.toHexString(id)
- + " quantity=" + quantity
- + " item=" + PluralRules.stringForQuantity(rule.quantityForNumber(quantity)));
- }
-
- private PluralRules getPluralRule() {
- synchronized (mSync) {
- if (mPluralRule == null) {
- mPluralRule = PluralRules.ruleForLocale(mConfiguration.locale);
- }
- return mPluralRule;
- }
- }
-
- /**
- * Return the string value associated with a particular resource ID. It
- * will be stripped of any styled text information.
- * {@more}
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return String The string data associated with the resource,
- * stripped of styled text information.
- */
- public String getString(int id) throws NotFoundException {
- CharSequence res = getText(id);
- if (res != null) {
- return res.toString();
- }
- throw new NotFoundException("String resource ID #0x"
- + Integer.toHexString(id));
- }
-
-
- /**
- * Return the string value associated with a particular resource ID,
- * substituting the format arguments as defined in {@link java.util.Formatter}
- * and {@link java.lang.String#format}. It will be stripped of any styled text
- * information.
- * {@more}
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @param formatArgs The format arguments that will be used for substitution.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return String The string data associated with the resource,
- * stripped of styled text information.
- */
- public String getString(int id, Object... formatArgs) throws NotFoundException {
- String raw = getString(id);
- return String.format(mConfiguration.locale, raw, formatArgs);
- }
-
- /**
- * Return the string value associated with a particular resource ID for a particular
- * numerical quantity, substituting the format arguments as defined in
- * {@link java.util.Formatter} and {@link java.lang.String#format}. It will be
- * stripped of any styled text information.
- * {@more}
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- * @param quantity The number used to get the correct string for the current language's
- * plural rules.
- * @param formatArgs The format arguments that will be used for substitution.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return String The string data associated with the resource,
- * stripped of styled text information.
- */
- public String getQuantityString(int id, int quantity, Object... formatArgs)
- throws NotFoundException {
- String raw = getQuantityText(id, quantity).toString();
- return String.format(mConfiguration.locale, raw, formatArgs);
- }
-
- /**
- * Return the string value associated with a particular resource ID for a particular
- * numerical quantity.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- * @param quantity The number used to get the correct string for the current language's
- * plural rules.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return String The string data associated with the resource,
- * stripped of styled text information.
- */
- public String getQuantityString(int id, int quantity) throws NotFoundException {
- return getQuantityText(id, quantity).toString();
- }
-
- /**
- * Return the string value associated with a particular resource ID. The
- * returned object will be a String if this is a plain string; it will be
- * some other type of CharSequence if it is styled.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @param def The default CharSequence to return.
- *
- * @return CharSequence The string data associated with the resource, plus
- * possibly styled text information, or def if id is 0 or not found.
- */
- public CharSequence getText(int id, CharSequence def) {
- CharSequence res = id != 0 ? mAssets.getResourceText(id) : null;
- return res != null ? res : def;
- }
-
- /**
- * Return the styled text array associated with a particular resource ID.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return The styled text array associated with the resource.
- */
- public CharSequence[] getTextArray(int id) throws NotFoundException {
- CharSequence[] res = mAssets.getResourceTextArray(id);
- if (res != null) {
- return res;
- }
- throw new NotFoundException("Text array resource ID #0x"
- + Integer.toHexString(id));
- }
-
- /**
- * Return the string array associated with a particular resource ID.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return The string array associated with the resource.
- */
- public String[] getStringArray(int id) throws NotFoundException {
- String[] res = mAssets.getResourceStringArray(id);
- if (res != null) {
- return res;
- }
- throw new NotFoundException("String array resource ID #0x"
- + Integer.toHexString(id));
- }
-
- /**
- * Return the int array associated with a particular resource ID.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return The int array associated with the resource.
- */
- public int[] getIntArray(int id) throws NotFoundException {
- int[] res = mAssets.getArrayIntResource(id);
- if (res != null) {
- return res;
- }
- throw new NotFoundException("Int array resource ID #0x"
- + Integer.toHexString(id));
- }
-
- /**
- * Return an array of heterogeneous values.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return Returns a TypedArray holding an array of the array values.
- * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
- * when done with it.
- */
- public TypedArray obtainTypedArray(int id) throws NotFoundException {
- int len = mAssets.getArraySize(id);
- if (len < 0) {
- throw new NotFoundException("Array resource ID #0x"
- + Integer.toHexString(id));
- }
-
- TypedArray array = getCachedStyledAttributes(len);
- array.mLength = mAssets.retrieveArray(id, array.mData);
- array.mIndices[0] = 0;
-
- return array;
- }
-
- /**
- * Retrieve a dimensional for a particular resource ID. Unit
- * conversions are based on the current {@link DisplayMetrics} associated
- * with the resources.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @return Resource dimension value multiplied by the appropriate
- * metric.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @see #getDimensionPixelOffset
- * @see #getDimensionPixelSize
- */
- public float getDimension(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- if (value.type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimension(value.data, mMetrics);
- }
- throw new NotFoundException(
- "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
- + Integer.toHexString(value.type) + " is not valid");
- }
- }
-
- /**
- * Retrieve a dimensional for a particular resource ID for use
- * as an offset in raw pixels. This is the same as
- * {@link #getDimension}, except the returned value is converted to
- * integer pixels for you. An offset conversion involves simply
- * truncating the base value to an integer.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @return Resource dimension value multiplied by the appropriate
- * metric and truncated to integer pixels.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @see #getDimension
- * @see #getDimensionPixelSize
- */
- public int getDimensionPixelOffset(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- if (value.type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelOffset(
- value.data, mMetrics);
- }
- throw new NotFoundException(
- "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
- + Integer.toHexString(value.type) + " is not valid");
- }
- }
-
- /**
- * Retrieve a dimensional for a particular resource ID for use
- * as a size in raw pixels. This is the same as
- * {@link #getDimension}, except the returned value is converted to
- * integer pixels for use as a size. A size conversion involves
- * rounding the base value, and ensuring that a non-zero base value
- * is at least one pixel in size.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @return Resource dimension value multiplied by the appropriate
- * metric and truncated to integer pixels.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @see #getDimension
- * @see #getDimensionPixelOffset
- */
- public int getDimensionPixelSize(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- if (value.type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelSize(
- value.data, mMetrics);
- }
- throw new NotFoundException(
- "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
- + Integer.toHexString(value.type) + " is not valid");
- }
- }
-
- /**
- * Retrieve a fractional unit for a particular resource ID.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- * @param base The base value of this fraction. In other words, a
- * standard fraction is multiplied by this value.
- * @param pbase The parent base value of this fraction. In other
- * words, a parent fraction (nn%p) is multiplied by this
- * value.
- *
- * @return Attribute fractional value multiplied by the appropriate
- * base value.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- */
- public float getFraction(int id, int base, int pbase) {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- if (value.type == TypedValue.TYPE_FRACTION) {
- return TypedValue.complexToFraction(value.data, base, pbase);
- }
- throw new NotFoundException(
- "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
- + Integer.toHexString(value.type) + " is not valid");
- }
- }
-
- /**
- * Return a drawable object associated with a particular resource ID.
- * Various types of objects will be returned depending on the underlying
- * resource -- for example, a solid color, PNG image, scalable image, etc.
- * The Drawable API hides these implementation details.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return Drawable An object that can be used to draw this resource.
- */
- public Drawable getDrawable(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- return loadDrawable(value, id);
- }
- }
-
- /**
- * Return a movie object associated with the particular resource ID.
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- */
- public Movie getMovie(int id) throws NotFoundException {
- InputStream is = openRawResource(id);
- Movie movie = Movie.decodeStream(is);
- try {
- is.close();
- }
- catch (java.io.IOException e) {
- // don't care, since the return value is valid
- }
- return movie;
- }
-
- /**
- * Return a color integer associated with a particular resource ID.
- * If the resource holds a complex
- * {@link android.content.res.ColorStateList}, then the default color from
- * the set is returned.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return Returns a single color value in the form 0xAARRGGBB.
- */
- public int getColor(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- if (value.type >= TypedValue.TYPE_FIRST_INT
- && value.type <= TypedValue.TYPE_LAST_INT) {
- return value.data;
- } else if (value.type == TypedValue.TYPE_STRING) {
- ColorStateList csl = loadColorStateList(mTmpValue, id);
- return csl.getDefaultColor();
- }
- throw new NotFoundException(
- "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
- + Integer.toHexString(value.type) + " is not valid");
- }
- }
-
- /**
- * Return a color state list associated with a particular resource ID. The
- * resource may contain either a single raw color value, or a complex
- * {@link android.content.res.ColorStateList} holding multiple possible colors.
- *
- * @param id The desired resource identifier of a {@link ColorStateList},
- * as generated by the aapt tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return Returns a ColorStateList object containing either a single
- * solid color or multiple colors that can be selected based on a state.
- */
- public ColorStateList getColorStateList(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- return loadColorStateList(value, id);
- }
- }
-
- /**
- * Return a boolean associated with a particular resource ID. This can be
- * used with any integral resource value, and will return true if it is
- * non-zero.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return Returns the boolean value contained in the resource.
- */
- public boolean getBoolean(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- if (value.type >= TypedValue.TYPE_FIRST_INT
- && value.type <= TypedValue.TYPE_LAST_INT) {
- return value.data != 0;
- }
- throw new NotFoundException(
- "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
- + Integer.toHexString(value.type) + " is not valid");
- }
- }
-
- /**
- * Return an integer associated with a particular resource ID.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return Returns the integer value contained in the resource.
- */
- public int getInteger(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- if (value.type >= TypedValue.TYPE_FIRST_INT
- && value.type <= TypedValue.TYPE_LAST_INT) {
- return value.data;
- }
- throw new NotFoundException(
- "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
- + Integer.toHexString(value.type) + " is not valid");
- }
- }
-
- /**
- * Return an XmlResourceParser through which you can read a view layout
- * description for the given resource ID. This parser has limited
- * functionality -- in particular, you can't change its input, and only
- * the high-level events are available.
- *
- * <p>This function is really a simple wrapper for calling
- * {@link #getXml} with a layout resource.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return A new parser object through which you can read
- * the XML data.
- *
- * @see #getXml
- */
- public XmlResourceParser getLayout(int id) throws NotFoundException {
- return loadXmlResourceParser(id, "layout");
- }
-
- /**
- * Return an XmlResourceParser through which you can read an animation
- * description for the given resource ID. This parser has limited
- * functionality -- in particular, you can't change its input, and only
- * the high-level events are available.
- *
- * <p>This function is really a simple wrapper for calling
- * {@link #getXml} with an animation resource.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return A new parser object through which you can read
- * the XML data.
- *
- * @see #getXml
- */
- public XmlResourceParser getAnimation(int id) throws NotFoundException {
- return loadXmlResourceParser(id, "anim");
- }
-
- /**
- * Return an XmlResourceParser through which you can read a generic XML
- * resource for the given resource ID.
- *
- * <p>The XmlPullParser implementation returned here has some limited
- * functionality. In particular, you can't change its input, and only
- * high-level parsing events are available (since the document was
- * pre-parsed for you at build time, which involved merging text and
- * stripping comments).
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return A new parser object through which you can read
- * the XML data.
- *
- * @see android.util.AttributeSet
- */
- public XmlResourceParser getXml(int id) throws NotFoundException {
- return loadXmlResourceParser(id, "xml");
- }
-
- /**
- * Open a data stream for reading a raw resource. This can only be used
- * with resources whose value is the name of an asset files -- that is, it can be
- * used to open drawable, sound, and raw resources; it will fail on string
- * and color resources.
- *
- * @param id The resource identifier to open, as generated by the appt
- * tool.
- *
- * @return InputStream Access to the resource data.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- */
- public InputStream openRawResource(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- return openRawResource(id, mTmpValue);
- }
- }
-
- /**
- * Open a data stream for reading a raw resource. This can only be used
- * with resources whose value is the name of an asset files -- that is, it can be
- * used to open drawable, sound, and raw resources; it will fail on string
- * and color resources.
- *
- * @param id The resource identifier to open, as generated by the appt tool.
- * @param value The TypedValue object to hold the resource information.
- *
- * @return InputStream Access to the resource data.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @hide Pending API council approval
- */
- public InputStream openRawResource(int id, TypedValue value) throws NotFoundException {
- getValue(id, value, true);
-
- try {
- return mAssets.openNonAsset(value.assetCookie, value.string.toString(),
- AssetManager.ACCESS_STREAMING);
- } catch (Exception e) {
- NotFoundException rnf = new NotFoundException("File " + value.string.toString() +
- " from drawable resource ID #0x" + Integer.toHexString(id));
- rnf.initCause(e);
- throw rnf;
- }
- }
-
- /**
- * Open a file descriptor for reading a raw resource. This can only be used
- * with resources whose value is the name of an asset files -- that is, it can be
- * used to open drawable, sound, and raw resources; it will fail on string
- * and color resources.
- *
- * <p>This function only works for resources that are stored in the package
- * as uncompressed data, which typically includes things like mp3 files
- * and png images.
- *
- * @param id The resource identifier to open, as generated by the appt
- * tool.
- *
- * @return AssetFileDescriptor A new file descriptor you can use to read
- * the resource. This includes the file descriptor itself, as well as the
- * offset and length of data where the resource appears in the file. A
- * null is returned if the file exists but is compressed.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- */
- public AssetFileDescriptor openRawResourceFd(int id) throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
-
- try {
- return mAssets.openNonAssetFd(
- value.assetCookie, value.string.toString());
- } catch (Exception e) {
- NotFoundException rnf = new NotFoundException(
- "File " + value.string.toString()
- + " from drawable resource ID #0x"
- + Integer.toHexString(id));
- rnf.initCause(e);
- throw rnf;
- }
-
- }
- }
-
- /**
- * Return the raw data associated with a particular resource ID.
- *
- * @param id The desired resource identifier, as generated by the aapt
- * tool. This integer encodes the package, type, and resource
- * entry. The value 0 is an invalid identifier.
- * @param outValue Object in which to place the resource data.
- * @param resolveRefs If true, a resource that is a reference to another
- * resource will be followed so that you receive the
- * actual final resource data. If false, the TypedValue
- * will be filled in with the reference itself.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- */
- public void getValue(int id, TypedValue outValue, boolean resolveRefs)
- throws NotFoundException {
- boolean found = mAssets.getResourceValue(id, outValue, resolveRefs);
- if (found) {
- return;
- }
- throw new NotFoundException("Resource ID #0x"
- + Integer.toHexString(id));
- }
-
- /**
- * Return the raw data associated with a particular resource ID.
- * See getIdentifier() for information on how names are mapped to resource
- * IDs, and getString(int) for information on how string resources are
- * retrieved.
- *
- * <p>Note: use of this function is discouraged. It is much more
- * efficient to retrieve resources by identifier than by name.
- *
- * @param name The name of the desired resource. This is passed to
- * getIdentifier() with a default type of "string".
- * @param outValue Object in which to place the resource data.
- * @param resolveRefs If true, a resource that is a reference to another
- * resource will be followed so that you receive the
- * actual final resource data. If false, the TypedValue
- * will be filled in with the reference itself.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- */
- public void getValue(String name, TypedValue outValue, boolean resolveRefs)
- throws NotFoundException {
- int id = getIdentifier(name, "string", null);
- if (id != 0) {
- getValue(id, outValue, resolveRefs);
- return;
- }
- throw new NotFoundException("String resource name " + name);
- }
-
- /**
- * This class holds the current attribute values for a particular theme.
- * In other words, a Theme is a set of values for resource attributes;
- * these are used in conjunction with {@link TypedArray}
- * to resolve the final value for an attribute.
- *
- * <p>The Theme's attributes come into play in two ways: (1) a styled
- * attribute can explicit reference a value in the theme through the
- * "?themeAttribute" syntax; (2) if no value has been defined for a
- * particular styled attribute, as a last resort we will try to find that
- * attribute's value in the Theme.
- *
- * <p>You will normally use the {@link #obtainStyledAttributes} APIs to
- * retrieve XML attributes with style and theme information applied.
- */
- public final class Theme {
- /**
- * Place new attribute values into the theme. The style resource
- * specified by <var>resid</var> will be retrieved from this Theme's
- * resources, its values placed into the Theme object.
- *
- * <p>The semantics of this function depends on the <var>force</var>
- * argument: If false, only values that are not already defined in
- * the theme will be copied from the system resource; otherwise, if
- * any of the style's attributes are already defined in the theme, the
- * current values in the theme will be overwritten.
- *
- * @param resid The resource ID of a style resource from which to
- * obtain attribute values.
- * @param force If true, values in the style resource will always be
- * used in the theme; otherwise, they will only be used
- * if not already defined in the theme.
- */
- public void applyStyle(int resid, boolean force) {
- AssetManager.applyThemeStyle(mTheme, resid, force);
- }
-
- /**
- * Set this theme to hold the same contents as the theme
- * <var>other</var>. If both of these themes are from the same
- * Resources object, they will be identical after this function
- * returns. If they are from different Resources, only the resources
- * they have in common will be set in this theme.
- *
- * @param other The existing Theme to copy from.
- */
- public void setTo(Theme other) {
- AssetManager.copyTheme(mTheme, other.mTheme);
- }
-
- /**
- * Return a StyledAttributes holding the values defined by
- * <var>Theme</var> which are listed in <var>attrs</var>.
- *
- * <p>Be sure to call StyledAttributes.recycle() when you are done with
- * the array.
- *
- * @param attrs The desired attributes.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return Returns a TypedArray holding an array of the attribute values.
- * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
- * when done with it.
- *
- * @see Resources#obtainAttributes
- * @see #obtainStyledAttributes(int, int[])
- * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
- */
- public TypedArray obtainStyledAttributes(int[] attrs) {
- int len = attrs.length;
- TypedArray array = getCachedStyledAttributes(len);
- array.mRsrcs = attrs;
- AssetManager.applyStyle(mTheme, 0, 0, 0, attrs,
- array.mData, array.mIndices);
- return array;
- }
-
- /**
- * Return a StyledAttributes holding the values defined by the style
- * resource <var>resid</var> which are listed in <var>attrs</var>.
- *
- * <p>Be sure to call StyledAttributes.recycle() when you are done with
- * the array.
- *
- * @param resid The desired style resource.
- * @param attrs The desired attributes in the style.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @return Returns a TypedArray holding an array of the attribute values.
- * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
- * when done with it.
- *
- * @see Resources#obtainAttributes
- * @see #obtainStyledAttributes(int[])
- * @see #obtainStyledAttributes(AttributeSet, int[], int, int)
- */
- public TypedArray obtainStyledAttributes(int resid, int[] attrs)
- throws NotFoundException {
- int len = attrs.length;
- TypedArray array = getCachedStyledAttributes(len);
- array.mRsrcs = attrs;
-
- AssetManager.applyStyle(mTheme, 0, resid, 0, attrs,
- array.mData, array.mIndices);
- if (false) {
- int[] data = array.mData;
-
- System.out.println("**********************************************************");
- System.out.println("**********************************************************");
- System.out.println("**********************************************************");
- System.out.println("Attributes:");
- String s = " Attrs:";
- int i;
- for (i=0; i<attrs.length; i++) {
- s = s + " 0x" + Integer.toHexString(attrs[i]);
- }
- System.out.println(s);
- s = " Found:";
- TypedValue value = new TypedValue();
- for (i=0; i<attrs.length; i++) {
- int d = i*AssetManager.STYLE_NUM_ENTRIES;
- value.type = data[d+AssetManager.STYLE_TYPE];
- value.data = data[d+AssetManager.STYLE_DATA];
- value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE];
- value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID];
- s = s + " 0x" + Integer.toHexString(attrs[i])
- + "=" + value;
- }
- System.out.println(s);
- }
- return array;
- }
-
- /**
- * Return a StyledAttributes holding the attribute values in
- * <var>set</var>
- * that are listed in <var>attrs</var>. In addition, if the given
- * AttributeSet specifies a style class (through the "style" attribute),
- * that style will be applied on top of the base attributes it defines.
- *
- * <p>Be sure to call StyledAttributes.recycle() when you are done with
- * the array.
- *
- * <p>When determining the final value of a particular attribute, there
- * are four inputs that come into play:</p>
- *
- * <ol>
- * <li> Any attribute values in the given AttributeSet.
- * <li> The style resource specified in the AttributeSet (named
- * "style").
- * <li> The default style specified by <var>defStyleAttr</var> and
- * <var>defStyleRes</var>
- * <li> The base values in this theme.
- * </ol>
- *
- * <p>Each of these inputs is considered in-order, with the first listed
- * taking precedence over the following ones. In other words, if in the
- * AttributeSet you have supplied <code>&lt;Button
- * textColor="#ff000000"&gt;</code>, then the button's text will
- * <em>always</em> be black, regardless of what is specified in any of
- * the styles.
- *
- * @param set The base set of attribute values. May be null.
- * @param attrs The desired attributes to be retrieved.
- * @param defStyleAttr An attribute in the current theme that contains a
- * reference to a style resource that supplies
- * defaults values for the StyledAttributes. Can be
- * 0 to not look for defaults.
- * @param defStyleRes A resource identifier of a style resource that
- * supplies default values for the StyledAttributes,
- * used only if defStyleAttr is 0 or can not be found
- * in the theme. Can be 0 to not look for defaults.
- *
- * @return Returns a TypedArray holding an array of the attribute values.
- * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
- * when done with it.
- *
- * @see Resources#obtainAttributes
- * @see #obtainStyledAttributes(int[])
- * @see #obtainStyledAttributes(int, int[])
- */
- public TypedArray obtainStyledAttributes(AttributeSet set,
- int[] attrs, int defStyleAttr, int defStyleRes) {
- int len = attrs.length;
- TypedArray array = getCachedStyledAttributes(len);
-
- // XXX note that for now we only work with compiled XML files.
- // To support generic XML files we will need to manually parse
- // out the attributes from the XML file (applying type information
- // contained in the resources and such).
- XmlBlock.Parser parser = (XmlBlock.Parser)set;
- AssetManager.applyStyle(
- mTheme, defStyleAttr, defStyleRes,
- parser != null ? parser.mParseState : 0, attrs,
- array.mData, array.mIndices);
-
- array.mRsrcs = attrs;
- array.mXml = parser;
-
- if (false) {
- int[] data = array.mData;
-
- System.out.println("Attributes:");
- String s = " Attrs:";
- int i;
- for (i=0; i<set.getAttributeCount(); i++) {
- s = s + " " + set.getAttributeName(i);
- int id = set.getAttributeNameResource(i);
- if (id != 0) {
- s = s + "(0x" + Integer.toHexString(id) + ")";
- }
- s = s + "=" + set.getAttributeValue(i);
- }
- System.out.println(s);
- s = " Found:";
- TypedValue value = new TypedValue();
- for (i=0; i<attrs.length; i++) {
- int d = i*AssetManager.STYLE_NUM_ENTRIES;
- value.type = data[d+AssetManager.STYLE_TYPE];
- value.data = data[d+AssetManager.STYLE_DATA];
- value.assetCookie = data[d+AssetManager.STYLE_ASSET_COOKIE];
- value.resourceId = data[d+AssetManager.STYLE_RESOURCE_ID];
- s = s + " 0x" + Integer.toHexString(attrs[i])
- + "=" + value;
- }
- System.out.println(s);
- }
-
- return array;
- }
-
- /**
- * Retrieve the value of an attribute in the Theme. The contents of
- * <var>outValue</var> are ultimately filled in by
- * {@link Resources#getValue}.
- *
- * @param resid The resource identifier of the desired theme
- * attribute.
- * @param outValue Filled in with the ultimate resource value supplied
- * by the attribute.
- * @param resolveRefs If true, resource references will be walked; if
- * false, <var>outValue</var> may be a
- * TYPE_REFERENCE. In either case, it will never
- * be a TYPE_ATTRIBUTE.
- *
- * @return boolean Returns true if the attribute was found and
- * <var>outValue</var> is valid, else false.
- */
- public boolean resolveAttribute(int resid, TypedValue outValue,
- boolean resolveRefs) {
- boolean got = mAssets.getThemeValue(mTheme, resid, outValue, resolveRefs);
- if (false) {
- System.out.println(
- "resolveAttribute #" + Integer.toHexString(resid)
- + " got=" + got + ", type=0x" + Integer.toHexString(outValue.type)
- + ", data=0x" + Integer.toHexString(outValue.data));
- }
- return got;
- }
-
- /**
- * Print contents of this theme out to the log. For debugging only.
- *
- * @param priority The log priority to use.
- * @param tag The log tag to use.
- * @param prefix Text to prefix each line printed.
- */
- public void dump(int priority, String tag, String prefix) {
- AssetManager.dumpTheme(mTheme, priority, tag, prefix);
- }
-
- protected void finalize() throws Throwable {
- super.finalize();
- mAssets.releaseTheme(mTheme);
- }
-
- /*package*/ Theme() {
- mAssets = Resources.this.mAssets;
- mTheme = mAssets.createTheme();
- }
-
- private final AssetManager mAssets;
- private final int mTheme;
- }
-
- /**
- * Generate a new Theme object for this set of Resources. It initially
- * starts out empty.
- *
- * @return Theme The newly created Theme container.
- */
- public final Theme newTheme() {
- return new Theme();
- }
-
- /**
- * Retrieve a set of basic attribute values from an AttributeSet, not
- * performing styling of them using a theme and/or style resources.
- *
- * @param set The current attribute values to retrieve.
- * @param attrs The specific attributes to be retrieved.
- * @return Returns a TypedArray holding an array of the attribute values.
- * Be sure to call {@link TypedArray#recycle() TypedArray.recycle()}
- * when done with it.
- *
- * @see Theme#obtainStyledAttributes(AttributeSet, int[], int, int)
- */
- public TypedArray obtainAttributes(AttributeSet set, int[] attrs) {
- int len = attrs.length;
- TypedArray array = getCachedStyledAttributes(len);
-
- // XXX note that for now we only work with compiled XML files.
- // To support generic XML files we will need to manually parse
- // out the attributes from the XML file (applying type information
- // contained in the resources and such).
- XmlBlock.Parser parser = (XmlBlock.Parser)set;
- mAssets.retrieveAttributes(parser.mParseState, attrs,
- array.mData, array.mIndices);
-
- array.mRsrcs = attrs;
- array.mXml = parser;
-
- return array;
- }
-
- /**
- * Store the newly updated configuration.
- */
- public void updateConfiguration(Configuration config,
- DisplayMetrics metrics) {
- synchronized (mTmpValue) {
- int configChanges = 0xfffffff;
- if (config != null) {
- configChanges = mConfiguration.updateFrom(config);
- }
- if (metrics != null) {
- mMetrics.setTo(metrics);
- }
- mMetrics.scaledDensity = mMetrics.density * mConfiguration.fontScale;
- String locale = null;
- if (mConfiguration.locale != null) {
- locale = mConfiguration.locale.getLanguage();
- if (mConfiguration.locale.getCountry() != null) {
- locale += "-" + mConfiguration.locale.getCountry();
- }
- }
- int width, height;
- if (mMetrics.widthPixels >= mMetrics.heightPixels) {
- width = mMetrics.widthPixels;
- height = mMetrics.heightPixels;
- } else {
- width = mMetrics.heightPixels;
- height = mMetrics.widthPixels;
- }
- int keyboardHidden = mConfiguration.keyboardHidden;
- if (keyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO
- && mConfiguration.hardKeyboardHidden
- == Configuration.HARDKEYBOARDHIDDEN_YES) {
- keyboardHidden = Configuration.KEYBOARDHIDDEN_SOFT;
- }
- mAssets.setConfiguration(mConfiguration.mcc, mConfiguration.mnc,
- locale, mConfiguration.orientation,
- mConfiguration.touchscreen,
- (int)(mMetrics.density*160), mConfiguration.keyboard,
- keyboardHidden, mConfiguration.navigation, width, height,
- sSdkVersion);
- int N = mDrawableCache.size();
- if (DEBUG_CONFIG) {
- Log.d(TAG, "Cleaning up drawables config changes: 0x"
- + Integer.toHexString(configChanges));
- }
- for (int i=0; i<N; i++) {
- WeakReference<Drawable.ConstantState> ref = mDrawableCache.valueAt(i);
- if (ref != null) {
- Drawable.ConstantState cs = ref.get();
- if (cs != null) {
- if (Configuration.needNewResources(
- configChanges, cs.getChangingConfigurations())) {
- if (DEBUG_CONFIG) {
- Log.d(TAG, "FLUSHING #0x"
- + Integer.toHexString(mDrawableCache.keyAt(i))
- + " / " + cs + " with changes: 0x"
- + Integer.toHexString(cs.getChangingConfigurations()));
- }
- mDrawableCache.setValueAt(i, null);
- } else if (DEBUG_CONFIG) {
- Log.d(TAG, "(Keeping #0x"
- + Integer.toHexString(mDrawableCache.keyAt(i))
- + " / " + cs + " with changes: 0x"
- + Integer.toHexString(cs.getChangingConfigurations())
- + ")");
- }
- }
- }
- }
- mDrawableCache.clear();
- mColorStateListCache.clear();
- flushLayoutCache();
- }
- synchronized (mSync) {
- if (mPluralRule != null) {
- mPluralRule = PluralRules.ruleForLocale(config.locale);
- }
- }
- }
-
- /**
- * Update the system resources configuration if they have previously
- * been initialized.
- *
- * @hide
- */
- public static void updateSystemConfiguration(Configuration config, DisplayMetrics metrics) {
- if (mSystem != null) {
- mSystem.updateConfiguration(config, metrics);
- //Log.i(TAG, "Updated system resources " + mSystem
- // + ": " + mSystem.getConfiguration());
- }
- }
-
- /**
- * Return the current display metrics that are in effect for this resource
- * object. The returned object should be treated as read-only.
- *
- * @return The resource's current display metrics.
- */
- public DisplayMetrics getDisplayMetrics() {
- return mMetrics;
- }
-
- /**
- * Return the current configuration that is in effect for this resource
- * object. The returned object should be treated as read-only.
- *
- * @return The resource's current configuration.
- */
- public Configuration getConfiguration() {
- return mConfiguration;
- }
-
- /**
- * Return a resource identifier for the given resource name. A fully
- * qualified resource name is of the form "package:type/entry". The first
- * two components (package and type) are optional if defType and
- * defPackage, respectively, are specified here.
- *
- * <p>Note: use of this function is discouraged. It is much more
- * efficient to retrieve resources by identifier than by name.
- *
- * @param name The name of the desired resource.
- * @param defType Optional default resource type to find, if "type/" is
- * not included in the name. Can be null to require an
- * explicit type.
- * @param defPackage Optional default package to find, if "package:" is
- * not included in the name. Can be null to require an
- * explicit package.
- *
- * @return int The associated resource identifier. Returns 0 if no such
- * resource was found. (0 is not a valid resource ID.)
- */
- public int getIdentifier(String name, String defType, String defPackage) {
- try {
- return Integer.parseInt(name);
- } catch (Exception e) {
- }
- return mAssets.getResourceIdentifier(name, defType, defPackage);
- }
-
- /**
- * Return the full name for a given resource identifier. This name is
- * a single string of the form "package:type/entry".
- *
- * @param resid The resource identifier whose name is to be retrieved.
- *
- * @return A string holding the name of the resource.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @see #getResourcePackageName
- * @see #getResourceTypeName
- * @see #getResourceEntryName
- */
- public String getResourceName(int resid) throws NotFoundException {
- String str = mAssets.getResourceName(resid);
- if (str != null) return str;
- throw new NotFoundException("Unable to find resource ID #0x"
- + Integer.toHexString(resid));
- }
-
- /**
- * Return the package name for a given resource identifier.
- *
- * @param resid The resource identifier whose package name is to be
- * retrieved.
- *
- * @return A string holding the package name of the resource.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @see #getResourceName
- */
- public String getResourcePackageName(int resid) throws NotFoundException {
- String str = mAssets.getResourcePackageName(resid);
- if (str != null) return str;
- throw new NotFoundException("Unable to find resource ID #0x"
- + Integer.toHexString(resid));
- }
-
- /**
- * Return the type name for a given resource identifier.
- *
- * @param resid The resource identifier whose type name is to be
- * retrieved.
- *
- * @return A string holding the type name of the resource.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @see #getResourceName
- */
- public String getResourceTypeName(int resid) throws NotFoundException {
- String str = mAssets.getResourceTypeName(resid);
- if (str != null) return str;
- throw new NotFoundException("Unable to find resource ID #0x"
- + Integer.toHexString(resid));
- }
-
- /**
- * Return the entry name for a given resource identifier.
- *
- * @param resid The resource identifier whose entry name is to be
- * retrieved.
- *
- * @return A string holding the entry name of the resource.
- *
- * @throws NotFoundException Throws NotFoundException if the given ID does not exist.
- *
- * @see #getResourceName
- */
- public String getResourceEntryName(int resid) throws NotFoundException {
- String str = mAssets.getResourceEntryName(resid);
- if (str != null) return str;
- throw new NotFoundException("Unable to find resource ID #0x"
- + Integer.toHexString(resid));
- }
-
- /**
- * Parse a series of {@link android.R.styleable#Extra &lt;extra&gt;} tags from
- * an XML file. You call this when you are at the parent tag of the
- * extra tags, and it return once all of the child tags have been parsed.
- * This will call {@link #parseBundleExtra} for each extra tag encountered.
- *
- * @param parser The parser from which to retrieve the extras.
- * @param outBundle A Bundle in which to place all parsed extras.
- * @throws XmlPullParserException
- * @throws IOException
- */
- public void parseBundleExtras(XmlResourceParser parser, Bundle outBundle)
- throws XmlPullParserException, IOException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
-
- String nodeName = parser.getName();
- if (nodeName.equals("extra")) {
- parseBundleExtra("extra", parser, outBundle);
- XmlUtils.skipCurrentTag(parser);
-
- } else {
- XmlUtils.skipCurrentTag(parser);
- }
- }
- }
-
- /**
- * Parse a name/value pair out of an XML tag holding that data. The
- * AttributeSet must be holding the data defined by
- * {@link android.R.styleable#Extra}. The following value types are supported:
- * <ul>
- * <li> {@link TypedValue#TYPE_STRING}:
- * {@link Bundle#putCharSequence Bundle.putCharSequence()}
- * <li> {@link TypedValue#TYPE_INT_BOOLEAN}:
- * {@link Bundle#putCharSequence Bundle.putBoolean()}
- * <li> {@link TypedValue#TYPE_FIRST_INT}-{@link TypedValue#TYPE_LAST_INT}:
- * {@link Bundle#putCharSequence Bundle.putBoolean()}
- * <li> {@link TypedValue#TYPE_FLOAT}:
- * {@link Bundle#putCharSequence Bundle.putFloat()}
- * </ul>
- *
- * @param tagName The name of the tag these attributes come from; this is
- * only used for reporting error messages.
- * @param attrs The attributes from which to retrieve the name/value pair.
- * @param outBundle The Bundle in which to place the parsed value.
- * @throws XmlPullParserException If the attributes are not valid.
- */
- public void parseBundleExtra(String tagName, AttributeSet attrs,
- Bundle outBundle) throws XmlPullParserException {
- TypedArray sa = obtainAttributes(attrs,
- com.android.internal.R.styleable.Extra);
-
- String name = sa.getString(
- com.android.internal.R.styleable.Extra_name);
- if (name == null) {
- sa.recycle();
- throw new XmlPullParserException("<" + tagName
- + "> requires an android:name attribute at "
- + attrs.getPositionDescription());
- }
-
- TypedValue v = sa.peekValue(
- com.android.internal.R.styleable.Extra_value);
- if (v != null) {
- if (v.type == TypedValue.TYPE_STRING) {
- CharSequence cs = v.coerceToString();
- outBundle.putCharSequence(name, cs);
- } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
- outBundle.putBoolean(name, v.data != 0);
- } else if (v.type >= TypedValue.TYPE_FIRST_INT
- && v.type <= TypedValue.TYPE_LAST_INT) {
- outBundle.putInt(name, v.data);
- } else if (v.type == TypedValue.TYPE_FLOAT) {
- outBundle.putFloat(name, v.getFloat());
- } else {
- sa.recycle();
- throw new XmlPullParserException("<" + tagName
- + "> only supports string, integer, float, color, and boolean at "
- + attrs.getPositionDescription());
- }
- } else {
- sa.recycle();
- throw new XmlPullParserException("<" + tagName
- + "> requires an android:value or android:resource attribute at "
- + attrs.getPositionDescription());
- }
-
- sa.recycle();
- }
-
- /**
- * Retrieve underlying AssetManager storage for these resources.
- */
- public final AssetManager getAssets() {
- return mAssets;
- }
-
- /**
- * Call this to remove all cached loaded layout resources from the
- * Resources object. Only intended for use with performance testing
- * tools.
- */
- public final void flushLayoutCache() {
- synchronized (mCachedXmlBlockIds) {
- // First see if this block is in our cache.
- final int num = mCachedXmlBlockIds.length;
- for (int i=0; i<num; i++) {
- mCachedXmlBlockIds[i] = -0;
- XmlBlock oldBlock = mCachedXmlBlocks[i];
- if (oldBlock != null) {
- oldBlock.close();
- }
- mCachedXmlBlocks[i] = null;
- }
- }
- }
-
- /**
- * Start preloading of resource data using this Resources object. Only
- * for use by the zygote process for loading common system resources.
- * {@hide}
- */
- public final void startPreloading() {
- synchronized (mSync) {
- if (mPreloaded) {
- throw new IllegalStateException("Resources already preloaded");
- }
- mPreloaded = true;
- mPreloading = true;
- }
- }
-
- /**
- * Called by zygote when it is done preloading resources, to change back
- * to normal Resources operation.
- */
- public final void finishPreloading() {
- if (mPreloading) {
- mPreloading = false;
- flushLayoutCache();
- }
- }
-
- /*package*/ Drawable loadDrawable(TypedValue value, int id)
- throws NotFoundException {
- 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;
- Drawable dr = getCachedDrawable(key);
- //System.out.println("Cached drawable @ #" +
- // Integer.toHexString(key.intValue()) + ": " + dr);
- if (dr != null) {
- return dr;
- }
-
- Drawable.ConstantState cs = mPreloadedDrawables.get(key);
- if (cs != null) {
- dr = cs.newDrawable();
-
- } else {
- 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;
- }
-
- } 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;
- }
- }
- }
-
- if (dr != null) {
- dr.setChangingConfigurations(value.changingConfigurations);
- cs = dr.getConstantState();
- if (cs != null) {
- if (mPreloading) {
- mPreloadedDrawables.put(key, cs);
- }
- synchronized (mTmpValue) {
- //Log.i(TAG, "Saving cached drawable @ #" +
- // Integer.toHexString(key.intValue())
- // + " in " + this + ": " + cs);
- mDrawableCache.put(
- key, new WeakReference<Drawable.ConstantState>(cs));
- }
- }
- }
-
- return dr;
- }
-
- private final Drawable getCachedDrawable(int key) {
- synchronized (mTmpValue) {
- WeakReference<Drawable.ConstantState> wr = mDrawableCache.get(key);
- if (wr != null) { // we have the key
- Drawable.ConstantState entry = wr.get();
- if (entry != null) {
- //Log.i(TAG, "Returning cached drawable @ #" +
- // Integer.toHexString(((Integer)key).intValue())
- // + " in " + this + ": " + entry);
- return entry.newDrawable();
- }
- else { // our entry has been purged
- mDrawableCache.delete(key);
- }
- }
- }
- return null;
- }
-
- /*package*/ ColorStateList loadColorStateList(TypedValue value, int id)
- throws NotFoundException {
- 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 = getCachedColorStateList(key);
- if (csl != null) {
- return csl;
- }
-
- if (value.string == null) {
- throw new NotFoundException(
- "Resource is not a ColorStateList (color or path): " + value);
- }
-
- String file = value.string.toString();
-
- if (file.endsWith(".xml")) {
- try {
- XmlResourceParser rp = loadXmlResourceParser(
- file, id, value.assetCookie, "colorstatelist");
- csl = ColorStateList.createFromXml(this, rp);
- rp.close();
- } catch (Exception e) {
- NotFoundException rnf = new NotFoundException(
- "File " + file + " from color state list resource ID #0x"
- + Integer.toHexString(id));
- rnf.initCause(e);
- throw rnf;
- }
- } else {
- throw new NotFoundException(
- "File " + file + " from drawable resource ID #0x"
- + Integer.toHexString(id) + ": .xml extension required");
- }
-
- if (csl != null) {
- synchronized (mTmpValue) {
- //Log.i(TAG, "Saving cached color state list @ #" +
- // Integer.toHexString(key.intValue())
- // + " in " + this + ": " + csl);
- mColorStateListCache.put(
- key, new WeakReference<ColorStateList>(csl));
- }
- }
-
- return csl;
- }
-
- private ColorStateList getCachedColorStateList(int key) {
- synchronized (mTmpValue) {
- WeakReference<ColorStateList> wr = mColorStateListCache.get(key);
- if (wr != null) { // we have the key
- ColorStateList entry = wr.get();
- if (entry != null) {
- //Log.i(TAG, "Returning cached color state list @ #" +
- // Integer.toHexString(((Integer)key).intValue())
- // + " in " + this + ": " + entry);
- return entry;
- }
- else { // our entry has been purged
- mColorStateListCache.delete(key);
- }
- }
- }
- return null;
- }
-
- /*package*/ XmlResourceParser loadXmlResourceParser(int id, String type)
- throws NotFoundException {
- synchronized (mTmpValue) {
- TypedValue value = mTmpValue;
- getValue(id, value, true);
- if (value.type == TypedValue.TYPE_STRING) {
- return loadXmlResourceParser(value.string.toString(), id,
- value.assetCookie, type);
- }
- throw new NotFoundException(
- "Resource ID #0x" + Integer.toHexString(id) + " type #0x"
- + Integer.toHexString(value.type) + " is not valid");
- }
- }
-
- /*package*/ XmlResourceParser loadXmlResourceParser(String file, int id,
- int assetCookie, String type) throws NotFoundException {
- if (id != 0) {
- try {
- // These may be compiled...
- synchronized (mCachedXmlBlockIds) {
- // First see if this block is in our cache.
- final int num = mCachedXmlBlockIds.length;
- for (int i=0; i<num; i++) {
- if (mCachedXmlBlockIds[i] == id) {
- //System.out.println("**** REUSING XML BLOCK! id="
- // + id + ", index=" + i);
- return mCachedXmlBlocks[i].newParser();
- }
- }
-
- // Not in the cache, create a new block and put it at
- // the next slot in the cache.
- XmlBlock block = mAssets.openXmlBlockAsset(
- assetCookie, file);
- if (block != null) {
- int pos = mLastCachedXmlBlockIndex+1;
- if (pos >= num) pos = 0;
- mLastCachedXmlBlockIndex = pos;
- XmlBlock oldBlock = mCachedXmlBlocks[pos];
- if (oldBlock != null) {
- oldBlock.close();
- }
- mCachedXmlBlockIds[pos] = id;
- mCachedXmlBlocks[pos] = block;
- //System.out.println("**** CACHING NEW XML BLOCK! id="
- // + id + ", index=" + pos);
- return block.newParser();
- }
- }
- } catch (Exception e) {
- NotFoundException rnf = new NotFoundException(
- "File " + file + " from xml type " + type + " resource ID #0x"
- + Integer.toHexString(id));
- rnf.initCause(e);
- throw rnf;
- }
- }
-
- throw new NotFoundException(
- "File " + file + " from xml type " + type + " resource ID #0x"
- + Integer.toHexString(id));
- }
-
- private TypedArray getCachedStyledAttributes(int len) {
- synchronized (mTmpValue) {
- TypedArray attrs = mCachedStyledAttributes;
- if (attrs != null) {
- mCachedStyledAttributes = null;
-
- attrs.mLength = len;
- int fullLen = len * AssetManager.STYLE_NUM_ENTRIES;
- if (attrs.mData.length >= fullLen) {
- return attrs;
- }
- attrs.mData = new int[fullLen];
- attrs.mIndices = new int[1+len];
- return attrs;
- }
- return new TypedArray(this,
- new int[len*AssetManager.STYLE_NUM_ENTRIES],
- new int[1+len], len);
- }
- }
-
- private Resources() {
- mAssets = AssetManager.getSystem();
- // NOTE: Intentionally leaving this uninitialized (all values set
- // to zero), so that anyone who tries to do something that requires
- // metrics will get a very wrong value.
- mConfiguration.setToDefaults();
- mMetrics.setToDefaults();
- updateConfiguration(null, null);
- mAssets.ensureStringBlocks();
- }
-}
-
diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java
deleted file mode 100644
index 3df7708..0000000
--- a/core/java/android/content/res/StringBlock.java
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import android.text.*;
-import android.text.style.*;
-import android.util.Config;
-import android.util.Log;
-import android.util.SparseArray;
-import android.graphics.Paint;
-import android.graphics.Rect;
-import android.graphics.Typeface;
-import com.android.internal.util.XmlUtils;
-
-/**
- * Conveniences for retrieving data out of a compiled string resource.
- *
- * {@hide}
- */
-final class StringBlock {
- private static final String TAG = "AssetManager";
- private static final boolean localLOGV = Config.LOGV || false;
-
- private final int mNative;
- private final boolean mUseSparse;
- private final boolean mOwnsNative;
- private CharSequence[] mStrings;
- private SparseArray<CharSequence> mSparseStrings;
- StyleIDs mStyleIDs = null;
-
- public StringBlock(byte[] data, boolean useSparse) {
- mNative = nativeCreate(data, 0, data.length);
- mUseSparse = useSparse;
- mOwnsNative = true;
- if (localLOGV) Log.v(TAG, "Created string block " + this
- + ": " + nativeGetSize(mNative));
- }
-
- public StringBlock(byte[] data, int offset, int size, boolean useSparse) {
- mNative = nativeCreate(data, offset, size);
- mUseSparse = useSparse;
- mOwnsNative = true;
- if (localLOGV) Log.v(TAG, "Created string block " + this
- + ": " + nativeGetSize(mNative));
- }
-
- public CharSequence get(int idx) {
- synchronized (this) {
- if (mStrings != null) {
- CharSequence res = mStrings[idx];
- if (res != null) {
- return res;
- }
- } else if (mSparseStrings != null) {
- CharSequence res = mSparseStrings.get(idx);
- if (res != null) {
- return res;
- }
- } else {
- final int num = nativeGetSize(mNative);
- if (mUseSparse && num > 250) {
- mSparseStrings = new SparseArray<CharSequence>();
- } else {
- mStrings = new CharSequence[num];
- }
- }
- String str = nativeGetString(mNative, idx);
- CharSequence res = str;
- int[] style = nativeGetStyle(mNative, idx);
- if (localLOGV) Log.v(TAG, "Got string: " + str);
- if (localLOGV) Log.v(TAG, "Got styles: " + style);
- if (style != null) {
- if (mStyleIDs == null) {
- mStyleIDs = new StyleIDs();
- mStyleIDs.boldId = nativeIndexOfString(mNative, "b");
- mStyleIDs.italicId = nativeIndexOfString(mNative, "i");
- mStyleIDs.underlineId = nativeIndexOfString(mNative, "u");
- mStyleIDs.ttId = nativeIndexOfString(mNative, "tt");
- mStyleIDs.bigId = nativeIndexOfString(mNative, "big");
- mStyleIDs.smallId = nativeIndexOfString(mNative, "small");
- mStyleIDs.supId = nativeIndexOfString(mNative, "sup");
- mStyleIDs.subId = nativeIndexOfString(mNative, "sub");
- mStyleIDs.strikeId = nativeIndexOfString(mNative, "strike");
- mStyleIDs.listItemId = nativeIndexOfString(mNative, "li");
- mStyleIDs.marqueeId = nativeIndexOfString(mNative, "marquee");
-
- if (localLOGV) Log.v(TAG, "BoldId=" + mStyleIDs.boldId
- + ", ItalicId=" + mStyleIDs.italicId
- + ", UnderlineId=" + mStyleIDs.underlineId);
- }
-
- res = applyStyles(str, style, mStyleIDs);
- }
- if (mStrings != null) mStrings[idx] = res;
- else mSparseStrings.put(idx, res);
- return res;
- }
- }
-
- protected void finalize() throws Throwable {
- if (mOwnsNative) {
- nativeDestroy(mNative);
- }
- }
-
- static final class StyleIDs {
- private int boldId;
- private int italicId;
- private int underlineId;
- private int ttId;
- private int bigId;
- private int smallId;
- private int subId;
- private int supId;
- private int strikeId;
- private int listItemId;
- private int marqueeId;
- }
-
- private CharSequence applyStyles(String str, int[] style, StyleIDs ids) {
- if (style.length == 0)
- return str;
-
- SpannableString buffer = new SpannableString(str);
- int i=0;
- while (i < style.length) {
- 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,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- } else if (type == ids.italicId) {
- buffer.setSpan(new StyleSpan(Typeface.ITALIC),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- } else if (type == ids.underlineId) {
- buffer.setSpan(new UnderlineSpan(),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- } else if (type == ids.ttId) {
- buffer.setSpan(new TypefaceSpan("monospace"),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- } else if (type == ids.bigId) {
- buffer.setSpan(new RelativeSizeSpan(1.25f),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- } else if (type == ids.smallId) {
- buffer.setSpan(new RelativeSizeSpan(0.8f),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- } else if (type == ids.subId) {
- buffer.setSpan(new SubscriptSpan(),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- } else if (type == ids.supId) {
- buffer.setSpan(new SuperscriptSpan(),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- } else if (type == ids.strikeId) {
- buffer.setSpan(new StrikethroughSpan(),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- } else if (type == ids.listItemId) {
- 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,
- Spannable.SPAN_INCLUSIVE_INCLUSIVE);
- } else {
- String tag = nativeGetString(mNative, type);
-
- if (tag.startsWith("font;")) {
- String sub;
-
- sub = subtag(tag, ";height=");
- if (sub != null) {
- int size = Integer.parseInt(sub);
- buffer.setSpan(new Height(size),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_PARAGRAPH);
- }
-
- sub = subtag(tag, ";size=");
- if (sub != null) {
- int size = Integer.parseInt(sub);
- buffer.setSpan(new AbsoluteSizeSpan(size),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
-
- sub = subtag(tag, ";fgcolor=");
- if (sub != null) {
- int color = XmlUtils.convertValueToUnsignedInt(sub, -1);
- buffer.setSpan(new ForegroundColorSpan(color),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
-
- sub = subtag(tag, ";bgcolor=");
- if (sub != null) {
- int color = XmlUtils.convertValueToUnsignedInt(sub, -1);
- buffer.setSpan(new BackgroundColorSpan(color),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- } else if (tag.startsWith("a;")) {
- String sub;
-
- sub = subtag(tag, ";href=");
- if (sub != null) {
- buffer.setSpan(new URLSpan(sub),
- style[i+1], style[i+2]+1,
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- }
- }
- }
-
- i += 3;
- }
- return new SpannedString(buffer);
- }
-
- private static String subtag(String full, String attribute) {
- int start = full.indexOf(attribute);
- if (start < 0) {
- return null;
- }
-
- start += attribute.length();
- int end = full.indexOf(';', start);
-
- if (end < 0) {
- return full.substring(start);
- } else {
- return full.substring(start, end);
- }
- }
-
- /**
- * Forces the text line to be the specified height, shrinking/stretching
- * the ascent if possible, or the descent if shrinking the ascent further
- * will make the text unreadable.
- */
- private static class Height implements LineHeightSpan {
- private int mSize;
- private static float sProportion = 0;
-
- public Height(int size) {
- mSize = size;
- }
-
- public void chooseHeight(CharSequence text, int start, int end,
- int spanstartv, int v,
- Paint.FontMetricsInt fm) {
- if (fm.bottom - fm.top < mSize) {
- fm.top = fm.bottom - mSize;
- fm.ascent = fm.ascent - mSize;
- } else {
- if (sProportion == 0) {
- /*
- * Calculate what fraction of the nominal ascent
- * the height of a capital letter actually is,
- * so that we won't reduce the ascent to less than
- * that unless we absolutely have to.
- */
-
- Paint p = new Paint();
- p.setTextSize(100);
- Rect r = new Rect();
- p.getTextBounds("ABCDEFG", 0, 7, r);
-
- sProportion = (r.top) / p.ascent();
- }
-
- int need = (int) Math.ceil(-fm.top * sProportion);
-
- if (mSize - fm.descent >= need) {
- /*
- * It is safe to shrink the ascent this much.
- */
-
- fm.top = fm.bottom - mSize;
- fm.ascent = fm.descent - mSize;
- } else if (mSize >= need) {
- /*
- * We can't show all the descent, but we can at least
- * show all the ascent.
- */
-
- fm.top = fm.ascent = -need;
- fm.bottom = fm.descent = fm.top + mSize;
- } else {
- /*
- * Show as much of the ascent as we can, and no descent.
- */
-
- fm.top = fm.ascent = -mSize;
- fm.bottom = fm.descent = 0;
- }
- }
- }
- }
-
- /**
- * Create from an existing string block native object. This is
- * -extremely- dangerous -- only use it if you absolutely know what you
- * are doing! The given native object must exist for the entire lifetime
- * of this newly creating StringBlock.
- */
- StringBlock(int obj, boolean useSparse) {
- mNative = obj;
- mUseSparse = useSparse;
- mOwnsNative = false;
- if (localLOGV) Log.v(TAG, "Created string block " + this
- + ": " + nativeGetSize(mNative));
- }
-
- private static final native int nativeCreate(byte[] data,
- int offset,
- int size);
- private static final native int nativeGetSize(int obj);
- private static final native String nativeGetString(int obj, int idx);
- private static final native int[] nativeGetStyle(int obj, int idx);
- private static final native int nativeIndexOfString(int obj, String str);
- private static final native void nativeDestroy(int obj);
-}
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java
deleted file mode 100644
index 82a57dd..0000000
--- a/core/java/android/content/res/TypedArray.java
+++ /dev/null
@@ -1,660 +0,0 @@
-package android.content.res;
-
-import android.graphics.drawable.Drawable;
-import android.util.AttributeSet;
-import android.util.DisplayMetrics;
-import android.util.Log;
-import android.util.TypedValue;
-import com.android.internal.util.XmlUtils;
-
-import java.util.Arrays;
-
-/**
- * Container for an array of values that were retrieved with
- * {@link Resources.Theme#obtainStyledAttributes(AttributeSet, int[], int, int)}
- * or {@link Resources#obtainAttributes}. Be
- * sure to call {@link #recycle} when done with them.
- *
- * The indices used to retrieve values from this structure correspond to
- * the positions of the attributes given to obtainStyledAttributes.
- */
-public class TypedArray {
- private final Resources mResources;
- /*package*/ XmlBlock.Parser mXml;
- /*package*/ int[] mRsrcs;
- /*package*/ int[] mData;
- /*package*/ int[] mIndices;
- /*package*/ int mLength;
- private TypedValue mValue = new TypedValue();
-
- /**
- * Return the number of values in this array.
- */
- public int length() {
- return mLength;
- }
-
- /**
- * Return the number of indices in the array that actually have data.
- */
- public int getIndexCount() {
- return mIndices[0];
- }
-
- /**
- * Return an index in the array that has data.
- *
- * @param at The index you would like to returned, ranging from 0 to
- * {@link #getIndexCount()}.
- *
- * @return The index at the given offset, which can be used with
- * {@link #getValue} and related APIs.
- */
- public int getIndex(int at) {
- return mIndices[1+at];
- }
-
- /**
- * Return the Resources object this array was loaded from.
- */
- public Resources getResources() {
- return mResources;
- }
-
- /**
- * Retrieve the styled string value for the attribute at <var>index</var>.
- *
- * @param index Index of attribute to retrieve.
- *
- * @return CharSequence holding string data. May be styled. Returns
- * null if the attribute is not defined.
- */
- public CharSequence getText(int index) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- if (type == TypedValue.TYPE_NULL) {
- return null;
- } else if (type == TypedValue.TYPE_STRING) {
- return loadStringValueAt(index);
- }
-
- TypedValue v = mValue;
- if (getValueAt(index, v)) {
- Log.w(Resources.TAG, "Converting to string: " + v);
- return v.coerceToString();
- }
- Log.w(Resources.TAG, "getString of bad type: 0x"
- + Integer.toHexString(type));
- return null;
- }
-
- /**
- * Retrieve the string value for the attribute at <var>index</var>.
- *
- * @param index Index of attribute to retrieve.
- *
- * @return String holding string data. Any styling information is
- * removed. Returns null if the attribute is not defined.
- */
- public String getString(int index) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- if (type == TypedValue.TYPE_NULL) {
- return null;
- } else if (type == TypedValue.TYPE_STRING) {
- return loadStringValueAt(index).toString();
- }
-
- TypedValue v = mValue;
- if (getValueAt(index, v)) {
- Log.w(Resources.TAG, "Converting to string: " + v);
- CharSequence cs = v.coerceToString();
- return cs != null ? cs.toString() : null;
- }
- Log.w(Resources.TAG, "getString of bad type: 0x"
- + Integer.toHexString(type));
- return null;
- }
-
- /**
- * Retrieve the string value for the attribute at <var>index</var>, but
- * only if that string comes from an immediate value in an XML file. That
- * is, this does not allow references to string resources, string
- * attributes, or conversions from other types. As such, this method
- * will only return strings for TypedArray objects that come from
- * attributes in an XML file.
- *
- * @param index Index of attribute to retrieve.
- *
- * @return String holding string data. Any styling information is
- * removed. Returns null if the attribute is not defined or is not
- * an immediate string value.
- */
- public String getNonResourceString(int index) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- if (type == TypedValue.TYPE_STRING) {
- final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
- if (cookie < 0) {
- return mXml.getPooledString(
- data[index+AssetManager.STYLE_DATA]).toString();
- }
- }
- return null;
- }
-
- /**
- * Retrieve the boolean value for the attribute at <var>index</var>.
- *
- * @param index Index of attribute to retrieve.
- * @param defValue Value to return if the attribute is not defined.
- *
- * @return Attribute boolean value, or defValue if not defined.
- */
- public boolean getBoolean(int index, boolean defValue) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- if (type == TypedValue.TYPE_NULL) {
- return defValue;
- } else if (type >= TypedValue.TYPE_FIRST_INT
- && type <= TypedValue.TYPE_LAST_INT) {
- return data[index+AssetManager.STYLE_DATA] != 0;
- }
-
- TypedValue v = mValue;
- if (getValueAt(index, v)) {
- Log.w(Resources.TAG, "Converting to boolean: " + v);
- return XmlUtils.convertValueToBoolean(
- v.coerceToString(), defValue);
- }
- Log.w(Resources.TAG, "getBoolean of bad type: 0x"
- + Integer.toHexString(type));
- return defValue;
- }
-
- /**
- * Retrieve the integer value for the attribute at <var>index</var>.
- *
- * @param index Index of attribute to retrieve.
- * @param defValue Value to return if the attribute is not defined.
- *
- * @return Attribute int value, or defValue if not defined.
- */
- public int getInt(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_NULL) {
- return defValue;
- } else if (type >= TypedValue.TYPE_FIRST_INT
- && type <= TypedValue.TYPE_LAST_INT) {
- return data[index+AssetManager.STYLE_DATA];
- }
-
- TypedValue v = mValue;
- if (getValueAt(index, v)) {
- Log.w(Resources.TAG, "Converting to int: " + v);
- return XmlUtils.convertValueToInt(
- v.coerceToString(), defValue);
- }
- Log.w(Resources.TAG, "getInt of bad type: 0x"
- + Integer.toHexString(type));
- return defValue;
- }
-
- /**
- * Retrieve the float value for the attribute at <var>index</var>.
- *
- * @param index Index of attribute to retrieve.
- *
- * @return Attribute float value, or defValue if not defined..
- */
- public float getFloat(int index, float defValue) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- if (type == TypedValue.TYPE_NULL) {
- return defValue;
- } else if (type == TypedValue.TYPE_FLOAT) {
- return Float.intBitsToFloat(data[index+AssetManager.STYLE_DATA]);
- } else if (type >= TypedValue.TYPE_FIRST_INT
- && type <= TypedValue.TYPE_LAST_INT) {
- return data[index+AssetManager.STYLE_DATA];
- }
-
- TypedValue v = mValue;
- if (getValueAt(index, v)) {
- Log.w(Resources.TAG, "Converting to float: " + v);
- CharSequence str = v.coerceToString();
- if (str != null) {
- return Float.parseFloat(str.toString());
- }
- }
- Log.w(Resources.TAG, "getFloat of bad type: 0x"
- + Integer.toHexString(type));
- return defValue;
- }
-
- /**
- * Retrieve the color value for the attribute at <var>index</var>. If
- * the attribute references a color resource holding a complex
- * {@link android.content.res.ColorStateList}, then the default color from
- * the set is returned.
- *
- * @param index Index of attribute to retrieve.
- * @param defValue Value to return if the attribute is not defined or
- * not a resource.
- *
- * @return Attribute color value, or defValue if not defined.
- */
- public int getColor(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_NULL) {
- return defValue;
- } else if (type >= TypedValue.TYPE_FIRST_INT
- && type <= TypedValue.TYPE_LAST_INT) {
- return data[index+AssetManager.STYLE_DATA];
- } else if (type == TypedValue.TYPE_STRING) {
- final TypedValue value = mValue;
- if (getValueAt(index, value)) {
- ColorStateList csl = mResources.loadColorStateList(
- value, value.resourceId);
- return csl.getDefaultColor();
- }
- return defValue;
- }
-
- throw new UnsupportedOperationException("Can't convert to color: type=0x"
- + Integer.toHexString(type));
- }
-
- /**
- * Retrieve the ColorStateList for the attribute at <var>index</var>.
- * The value may be either a single solid color or a reference to
- * a color or complex {@link android.content.res.ColorStateList} description.
- *
- * @param index Index of attribute to retrieve.
- *
- * @return ColorStateList for the attribute, or null if not defined.
- */
- public ColorStateList getColorStateList(int index) {
- final TypedValue value = mValue;
- if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
- return mResources.loadColorStateList(value, value.resourceId);
- }
- return null;
- }
-
- /**
- * Retrieve the integer value for the attribute at <var>index</var>.
- *
- * @param index Index of attribute to retrieve.
- * @param defValue Value to return if the attribute is not defined or
- * not a resource.
- *
- * @return Attribute integer value, or defValue if not defined.
- */
- public int getInteger(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_NULL) {
- return defValue;
- } else if (type >= TypedValue.TYPE_FIRST_INT
- && type <= TypedValue.TYPE_LAST_INT) {
- return data[index+AssetManager.STYLE_DATA];
- }
-
- throw new UnsupportedOperationException("Can't convert to integer: type=0x"
- + Integer.toHexString(type));
- }
-
- /**
- * Retrieve a dimensional unit attribute at <var>index</var>. Unit
- * conversions are based on the current {@link DisplayMetrics}
- * associated with the resources this {@link TypedArray} object
- * came from.
- *
- * @param index Index of attribute to retrieve.
- * @param defValue Value to return if the attribute is not defined or
- * not a resource.
- *
- * @return Attribute dimension value multiplied by the appropriate
- * metric, or defValue if not defined.
- *
- * @see #getDimensionPixelOffset
- * @see #getDimensionPixelSize
- */
- public float getDimension(int index, float defValue) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- if (type == TypedValue.TYPE_NULL) {
- return defValue;
- } else if (type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimension(
- data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
- }
-
- throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
- + Integer.toHexString(type));
- }
-
- /**
- * Retrieve a dimensional unit attribute at <var>index</var> for use
- * as an offset in raw pixels. This is the same as
- * {@link #getDimension}, except the returned value is converted to
- * integer pixels for you. An offset conversion involves simply
- * truncating the base value to an integer.
- *
- * @param index Index of attribute to retrieve.
- * @param defValue Value to return if the attribute is not defined or
- * not a resource.
- *
- * @return Attribute dimension value multiplied by the appropriate
- * metric and truncated to integer pixels, or defValue if not defined.
- *
- * @see #getDimension
- * @see #getDimensionPixelSize
- */
- public int getDimensionPixelOffset(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_NULL) {
- return defValue;
- } else if (type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelOffset(
- data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
- }
-
- throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
- + Integer.toHexString(type));
- }
-
- /**
- * Retrieve a dimensional unit attribute at <var>index</var> for use
- * as a size in raw pixels. This is the same as
- * {@link #getDimension}, except the returned value is converted to
- * integer pixels for use as a size. A size conversion involves
- * rounding the base value, and ensuring that a non-zero base value
- * is at least one pixel in size.
- *
- * @param index Index of attribute to retrieve.
- * @param defValue Value to return if the attribute is not defined or
- * not a resource.
- *
- * @return Attribute dimension value multiplied by the appropriate
- * metric and truncated to integer pixels, or defValue if not defined.
- *
- * @see #getDimension
- * @see #getDimensionPixelOffset
- */
- public int getDimensionPixelSize(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_NULL) {
- return defValue;
- } else if (type == TypedValue.TYPE_DIMENSION) {
- return TypedValue.complexToDimensionPixelSize(
- data[index+AssetManager.STYLE_DATA], mResources.mMetrics);
- }
-
- throw new UnsupportedOperationException("Can't convert to dimension: type=0x"
- + Integer.toHexString(type));
- }
-
- /**
- * 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 name Textual name of attribute for error reporting.
- *
- * @return Attribute dimension value multiplied by the appropriate
- * metric and truncated to integer pixels.
- */
- public int getLayoutDimension(int index, String name) {
- 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);
- }
-
- throw new RuntimeException(getPositionDescription()
- + ": You must supply a " + name + " attribute.");
- }
-
- /**
- * Retrieve a fractional unit attribute at <var>index</var>.
- *
- * @param index Index of attribute to retrieve.
- * @param base The base value of this fraction. In other words, a
- * standard fraction is multiplied by this value.
- * @param pbase The parent base value of this fraction. In other
- * words, a parent fraction (nn%p) is multiplied by this
- * value.
- * @param defValue Value to return if the attribute is not defined or
- * not a resource.
- *
- * @return Attribute fractional value multiplied by the appropriate
- * base value, or defValue if not defined.
- */
- public float getFraction(int index, int base, int pbase, float defValue) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- if (type == TypedValue.TYPE_NULL) {
- return defValue;
- } else if (type == TypedValue.TYPE_FRACTION) {
- return TypedValue.complexToFraction(
- data[index+AssetManager.STYLE_DATA], base, pbase);
- }
-
- throw new UnsupportedOperationException("Can't convert to fraction: type=0x"
- + Integer.toHexString(type));
- }
-
- /**
- * Retrieve the resource identifier for the attribute at
- * <var>index</var>. Note that attribute resource as resolved when
- * the overall {@link TypedArray} object is retrieved. As a
- * result, this function will return the resource identifier of the
- * final resource value that was found, <em>not</em> necessarily the
- * original resource that was specified by the attribute.
- *
- * @param index Index of attribute to retrieve.
- * @param defValue Value to return if the attribute is not defined or
- * not a resource.
- *
- * @return Attribute resource identifier, or defValue if not defined.
- */
- public int getResourceId(int index, int defValue) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- if (data[index+AssetManager.STYLE_TYPE] != TypedValue.TYPE_NULL) {
- final int resid = data[index+AssetManager.STYLE_RESOURCE_ID];
- if (resid != 0) {
- return resid;
- }
- }
- return defValue;
- }
-
- /**
- * Retrieve the Drawable for the attribute at <var>index</var>. This
- * gets the resource ID of the selected attribute, and uses
- * {@link Resources#getDrawable Resources.getDrawable} of the owning
- * Resources object to retrieve its Drawable.
- *
- * @param index Index of attribute to retrieve.
- *
- * @return Drawable for the attribute, or null if not defined.
- */
- public Drawable getDrawable(int index) {
- final TypedValue value = mValue;
- if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
- if (false) {
- System.out.println("******************************************************************");
- System.out.println("Got drawable resource: type="
- + value.type
- + " str=" + value.string
- + " int=0x" + Integer.toHexString(value.data)
- + " cookie=" + value.assetCookie);
- System.out.println("******************************************************************");
- }
- return mResources.loadDrawable(value, value.resourceId);
- }
- return null;
- }
-
- /**
- * Retrieve the CharSequence[] for the attribute at <var>index</var>.
- * This gets the resource ID of the selected attribute, and uses
- * {@link Resources#getTextArray Resources.getTextArray} of the owning
- * Resources object to retrieve its String[].
- *
- * @param index Index of attribute to retrieve.
- *
- * @return CharSequence[] for the attribute, or null if not defined.
- */
- public CharSequence[] getTextArray(int index) {
- final TypedValue value = mValue;
- if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
- if (false) {
- System.out.println("******************************************************************");
- System.out.println("Got drawable resource: type="
- + value.type
- + " str=" + value.string
- + " int=0x" + Integer.toHexString(value.data)
- + " cookie=" + value.assetCookie);
- System.out.println("******************************************************************");
- }
- return mResources.getTextArray(value.resourceId);
- }
- return null;
- }
-
- /**
- * Retrieve the raw TypedValue for the attribute at <var>index</var>.
- *
- * @param index Index of attribute to retrieve.
- * @param outValue TypedValue object in which to place the attribute's
- * data.
- *
- * @return Returns true if the value was retrieved, else false.
- */
- public boolean getValue(int index, TypedValue outValue) {
- return getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, outValue);
- }
-
- /**
- * Determines whether there is an attribute at <var>index</var>.
- *
- * @param index Index of attribute to retrieve.
- *
- * @return True if the attribute has a value, false otherwise.
- */
- public boolean hasValue(int index) {
- index *= AssetManager.STYLE_NUM_ENTRIES;
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- return type != TypedValue.TYPE_NULL;
- }
-
- /**
- * Retrieve the raw TypedValue for the attribute at <var>index</var>
- * and return a temporary object holding its data. This object is only
- * valid until the next call on to {@link TypedArray}.
- *
- * @param index Index of attribute to retrieve.
- *
- * @return Returns a TypedValue object if the attribute is defined,
- * containing its data; otherwise returns null. (You will not
- * receive a TypedValue whose type is TYPE_NULL.)
- */
- public TypedValue peekValue(int index) {
- final TypedValue value = mValue;
- if (getValueAt(index*AssetManager.STYLE_NUM_ENTRIES, value)) {
- return value;
- }
- return null;
- }
-
- /**
- * Returns a message about the parser state suitable for printing error messages.
- */
- public String getPositionDescription() {
- return mXml != null ? mXml.getPositionDescription() : "<internal>";
- }
-
- /**
- * Give back a previously retrieved StyledAttributes, for later re-use.
- */
- public void recycle() {
- synchronized (mResources.mTmpValue) {
- TypedArray cached = mResources.mCachedStyledAttributes;
- if (cached == null || cached.mData.length < mData.length) {
- mXml = null;
- mResources.mCachedStyledAttributes = this;
- }
- }
- }
-
- private boolean getValueAt(int index, TypedValue outValue) {
- final int[] data = mData;
- final int type = data[index+AssetManager.STYLE_TYPE];
- if (type == TypedValue.TYPE_NULL) {
- return false;
- }
- outValue.type = type;
- outValue.data = data[index+AssetManager.STYLE_DATA];
- outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
- outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID];
- outValue.changingConfigurations = data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS];
- if (type == TypedValue.TYPE_STRING) {
- outValue.string = loadStringValueAt(index);
- }
- return true;
- }
-
- private CharSequence loadStringValueAt(int index) {
- final int[] data = mData;
- final int cookie = data[index+AssetManager.STYLE_ASSET_COOKIE];
- if (cookie < 0) {
- if (mXml != null) {
- return mXml.getPooledString(
- data[index+AssetManager.STYLE_DATA]);
- }
- return null;
- }
- //System.out.println("Getting pooled from: " + v);
- return mResources.mAssets.getPooledString(
- cookie, data[index+AssetManager.STYLE_DATA]);
- }
-
- /*package*/ TypedArray(Resources resources, int[] data, int[] indices, int len) {
- mResources = resources;
- mData = data;
- mIndices = indices;
- mLength = len;
- }
-
- public String toString() {
- return Arrays.toString(mData);
- }
-} \ No newline at end of file
diff --git a/core/java/android/content/res/XmlBlock.java b/core/java/android/content/res/XmlBlock.java
deleted file mode 100644
index 6336678..0000000
--- a/core/java/android/content/res/XmlBlock.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import android.util.TypedValue;
-import com.android.internal.util.XmlUtils;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Reader;
-
-/**
- * Wrapper around a compiled XML file.
- *
- * {@hide}
- */
-final class XmlBlock {
- private static final boolean DEBUG=false;
-
- public XmlBlock(byte[] data) {
- mAssets = null;
- mNative = nativeCreate(data, 0, data.length);
- mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
- }
-
- public XmlBlock(byte[] data, int offset, int size) {
- mAssets = null;
- mNative = nativeCreate(data, offset, size);
- mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
- }
-
- public void close() {
- synchronized (this) {
- if (mOpen) {
- mOpen = false;
- decOpenCountLocked();
- }
- }
- }
-
- private void decOpenCountLocked() {
- mOpenCount--;
- if (mOpenCount == 0) {
- nativeDestroy(mNative);
- if (mAssets != null) {
- mAssets.xmlBlockGone();
- }
- }
- }
-
- public XmlResourceParser newParser() {
- synchronized (this) {
- if (mNative != 0) {
- return new Parser(nativeCreateParseState(mNative), this);
- }
- return null;
- }
- }
-
- /*package*/ final class Parser implements XmlResourceParser {
- Parser(int parseState, XmlBlock block) {
- mParseState = parseState;
- mBlock = block;
- block.mOpenCount++;
- }
-
- public void setFeature(String name, boolean state) throws XmlPullParserException {
- if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
- return;
- }
- if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name) && state) {
- return;
- }
- throw new XmlPullParserException("Unsupported feature: " + name);
- }
- public boolean getFeature(String name) {
- if (FEATURE_PROCESS_NAMESPACES.equals(name)) {
- return true;
- }
- if (FEATURE_REPORT_NAMESPACE_ATTRIBUTES.equals(name)) {
- return true;
- }
- return false;
- }
- public void setProperty(String name, Object value) throws XmlPullParserException {
- throw new XmlPullParserException("setProperty() not supported");
- }
- public Object getProperty(String name) {
- return null;
- }
- public void setInput(Reader in) throws XmlPullParserException {
- throw new XmlPullParserException("setInput() not supported");
- }
- public void setInput(InputStream inputStream, String inputEncoding) throws XmlPullParserException {
- throw new XmlPullParserException("setInput() not supported");
- }
- public void defineEntityReplacementText(String entityName, String replacementText) throws XmlPullParserException {
- throw new XmlPullParserException("defineEntityReplacementText() not supported");
- }
- public String getNamespacePrefix(int pos) throws XmlPullParserException {
- throw new XmlPullParserException("getNamespacePrefix() not supported");
- }
- public String getInputEncoding() {
- return null;
- }
- public String getNamespace(String prefix) {
- throw new RuntimeException("getNamespace() not supported");
- }
- public int getNamespaceCount(int depth) throws XmlPullParserException {
- throw new XmlPullParserException("getNamespaceCount() not supported");
- }
- public String getPositionDescription() {
- return "Binary XML file line #" + getLineNumber();
- }
- public String getNamespaceUri(int pos) throws XmlPullParserException {
- throw new XmlPullParserException("getNamespaceUri() not supported");
- }
- public int getColumnNumber() {
- return -1;
- }
- public int getDepth() {
- return mDepth;
- }
- public String getText() {
- int id = nativeGetText(mParseState);
- return id >= 0 ? mStrings.get(id).toString() : null;
- }
- public int getLineNumber() {
- return nativeGetLineNumber(mParseState);
- }
- public int getEventType() throws XmlPullParserException {
- return mEventType;
- }
- public boolean isWhitespace() throws XmlPullParserException {
- // whitespace was stripped by aapt.
- return false;
- }
- public String getPrefix() {
- throw new RuntimeException("getPrefix not supported");
- }
- public char[] getTextCharacters(int[] holderForStartAndLength) {
- String txt = getText();
- char[] chars = null;
- if (txt != null) {
- holderForStartAndLength[0] = 0;
- holderForStartAndLength[1] = txt.length();
- chars = new char[txt.length()];
- txt.getChars(0, txt.length(), chars, 0);
- }
- return chars;
- }
- public String getNamespace() {
- int id = nativeGetNamespace(mParseState);
- return id >= 0 ? mStrings.get(id).toString() : "";
- }
- public String getName() {
- int id = nativeGetName(mParseState);
- return id >= 0 ? mStrings.get(id).toString() : null;
- }
- public String getAttributeNamespace(int index) {
- int id = nativeGetAttributeNamespace(mParseState, index);
- if (DEBUG) System.out.println("getAttributeNamespace of " + index + " = " + id);
- if (id >= 0) return mStrings.get(id).toString();
- else if (id == -1) return "";
- throw new IndexOutOfBoundsException(String.valueOf(index));
- }
- public String getAttributeName(int index) {
- int id = nativeGetAttributeName(mParseState, index);
- if (DEBUG) System.out.println("getAttributeName of " + index + " = " + id);
- if (id >= 0) return mStrings.get(id).toString();
- throw new IndexOutOfBoundsException(String.valueOf(index));
- }
- public String getAttributePrefix(int index) {
- throw new RuntimeException("getAttributePrefix not supported");
- }
- public boolean isEmptyElementTag() throws XmlPullParserException {
- // XXX Need to detect this.
- return false;
- }
- public int getAttributeCount() {
- return mEventType == START_TAG ? nativeGetAttributeCount(mParseState) : -1;
- }
- public String getAttributeValue(int index) {
- int id = nativeGetAttributeStringValue(mParseState, index);
- if (DEBUG) System.out.println("getAttributeValue of " + index + " = " + id);
- if (id >= 0) return mStrings.get(id).toString();
-
- // May be some other type... check and try to convert if so.
- int t = nativeGetAttributeDataType(mParseState, index);
- if (t == TypedValue.TYPE_NULL) {
- throw new IndexOutOfBoundsException(String.valueOf(index));
- }
-
- int v = nativeGetAttributeData(mParseState, index);
- return TypedValue.coerceToString(t, v);
- }
- public String getAttributeType(int index) {
- return "CDATA";
- }
- public boolean isAttributeDefault(int index) {
- return false;
- }
- public int nextToken() throws XmlPullParserException,IOException {
- return next();
- }
- public String getAttributeValue(String namespace, String name) {
- int idx = nativeGetAttributeIndex(mParseState, namespace, name);
- if (idx >= 0) {
- if (DEBUG) System.out.println("getAttributeName of "
- + namespace + ":" + name + " index = " + idx);
- if (DEBUG) System.out.println(
- "Namespace=" + getAttributeNamespace(idx)
- + "Name=" + getAttributeName(idx)
- + ", Value=" + getAttributeValue(idx));
- return getAttributeValue(idx);
- }
- return null;
- }
- public int next() throws XmlPullParserException,IOException {
- if (!mStarted) {
- mStarted = true;
- return START_DOCUMENT;
- }
- if (mParseState == 0) {
- return END_DOCUMENT;
- }
- int ev = nativeNext(mParseState);
- if (mDecNextDepth) {
- mDepth--;
- mDecNextDepth = false;
- }
- switch (ev) {
- case START_TAG:
- mDepth++;
- break;
- case END_TAG:
- mDecNextDepth = true;
- break;
- }
- mEventType = ev;
- if (ev == END_DOCUMENT) {
- // Automatically close the parse when we reach the end of
- // a document, since the standard XmlPullParser interface
- // doesn't have such an API so most clients will leave us
- // dangling.
- close();
- }
- return ev;
- }
- public void require(int type, String namespace, String name) throws XmlPullParserException,IOException {
- if (type != getEventType()
- || (namespace != null && !namespace.equals( getNamespace () ) )
- || (name != null && !name.equals( getName() ) ) )
- throw new XmlPullParserException( "expected "+ TYPES[ type ]+getPositionDescription());
- }
- public String nextText() throws XmlPullParserException,IOException {
- if(getEventType() != START_TAG) {
- throw new XmlPullParserException(
- getPositionDescription()
- + ": parser must be on START_TAG to read next text", this, null);
- }
- int eventType = next();
- if(eventType == TEXT) {
- String result = getText();
- eventType = next();
- if(eventType != END_TAG) {
- throw new XmlPullParserException(
- getPositionDescription()
- + ": event TEXT it must be immediately followed by END_TAG", this, null);
- }
- return result;
- } else if(eventType == END_TAG) {
- return "";
- } else {
- throw new XmlPullParserException(
- getPositionDescription()
- + ": parser must be on START_TAG or TEXT to read text", this, null);
- }
- }
- public int nextTag() throws XmlPullParserException,IOException {
- int eventType = next();
- if(eventType == TEXT && isWhitespace()) { // skip whitespace
- eventType = next();
- }
- if (eventType != START_TAG && eventType != END_TAG) {
- throw new XmlPullParserException(
- getPositionDescription()
- + ": expected start or end tag", this, null);
- }
- return eventType;
- }
-
- public int getAttributeNameResource(int index) {
- return nativeGetAttributeResource(mParseState, index);
- }
-
- public int getAttributeListValue(String namespace, String attribute,
- String[] options, int defaultValue) {
- int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
- if (idx >= 0) {
- return getAttributeListValue(idx, options, defaultValue);
- }
- return defaultValue;
- }
- public boolean getAttributeBooleanValue(String namespace, String attribute,
- boolean defaultValue) {
- int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
- if (idx >= 0) {
- return getAttributeBooleanValue(idx, defaultValue);
- }
- return defaultValue;
- }
- public int getAttributeResourceValue(String namespace, String attribute,
- int defaultValue) {
- int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
- if (idx >= 0) {
- return getAttributeResourceValue(idx, defaultValue);
- }
- return defaultValue;
- }
- public int getAttributeIntValue(String namespace, String attribute,
- int defaultValue) {
- int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
- if (idx >= 0) {
- return getAttributeIntValue(idx, defaultValue);
- }
- return defaultValue;
- }
- public int getAttributeUnsignedIntValue(String namespace, String attribute,
- int defaultValue)
- {
- int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
- if (idx >= 0) {
- return getAttributeUnsignedIntValue(idx, defaultValue);
- }
- return defaultValue;
- }
- public float getAttributeFloatValue(String namespace, String attribute,
- float defaultValue) {
- int idx = nativeGetAttributeIndex(mParseState, namespace, attribute);
- if (idx >= 0) {
- return getAttributeFloatValue(idx, defaultValue);
- }
- return defaultValue;
- }
-
- public int getAttributeListValue(int idx,
- String[] options, int defaultValue) {
- int t = nativeGetAttributeDataType(mParseState, idx);
- int v = nativeGetAttributeData(mParseState, idx);
- if (t == TypedValue.TYPE_STRING) {
- return XmlUtils.convertValueToList(
- mStrings.get(v), options, defaultValue);
- }
- return v;
- }
- public boolean getAttributeBooleanValue(int idx,
- boolean defaultValue) {
- int t = nativeGetAttributeDataType(mParseState, idx);
- // Note: don't attempt to convert any other types, because
- // we want to count on appt doing the conversion for us.
- if (t >= TypedValue.TYPE_FIRST_INT &&
- t <= TypedValue.TYPE_LAST_INT) {
- return nativeGetAttributeData(mParseState, idx) != 0;
- }
- return defaultValue;
- }
- public int getAttributeResourceValue(int idx, int defaultValue) {
- int t = nativeGetAttributeDataType(mParseState, idx);
- // Note: don't attempt to convert any other types, because
- // we want to count on appt doing the conversion for us.
- if (t == TypedValue.TYPE_REFERENCE) {
- return nativeGetAttributeData(mParseState, idx);
- }
- return defaultValue;
- }
- public int getAttributeIntValue(int idx, int defaultValue) {
- int t = nativeGetAttributeDataType(mParseState, idx);
- // Note: don't attempt to convert any other types, because
- // we want to count on appt doing the conversion for us.
- if (t >= TypedValue.TYPE_FIRST_INT &&
- t <= TypedValue.TYPE_LAST_INT) {
- return nativeGetAttributeData(mParseState, idx);
- }
- return defaultValue;
- }
- public int getAttributeUnsignedIntValue(int idx, int defaultValue) {
- int t = nativeGetAttributeDataType(mParseState, idx);
- // Note: don't attempt to convert any other types, because
- // we want to count on appt doing the conversion for us.
- if (t >= TypedValue.TYPE_FIRST_INT &&
- t <= TypedValue.TYPE_LAST_INT) {
- return nativeGetAttributeData(mParseState, idx);
- }
- return defaultValue;
- }
- public float getAttributeFloatValue(int idx, float defaultValue) {
- int t = nativeGetAttributeDataType(mParseState, idx);
- // Note: don't attempt to convert any other types, because
- // we want to count on appt doing the conversion for us.
- if (t == TypedValue.TYPE_FLOAT) {
- return Float.intBitsToFloat(
- nativeGetAttributeData(mParseState, idx));
- }
- throw new RuntimeException("not a float!");
- }
-
- public String getIdAttribute() {
- int id = nativeGetIdAttribute(mParseState);
- return id >= 0 ? mStrings.get(id).toString() : null;
- }
- public String getClassAttribute() {
- int id = nativeGetClassAttribute(mParseState);
- return id >= 0 ? mStrings.get(id).toString() : null;
- }
-
- public int getIdAttributeResourceValue(int defaultValue) {
- //todo: create and use native method
- return getAttributeResourceValue(null, "id", defaultValue);
- }
-
- public int getStyleAttribute() {
- return nativeGetStyleAttribute(mParseState);
- }
-
- public void close() {
- synchronized (mBlock) {
- if (mParseState != 0) {
- nativeDestroyParseState(mParseState);
- mParseState = 0;
- mBlock.decOpenCountLocked();
- }
- }
- }
-
- protected void finalize() throws Throwable {
- close();
- }
-
- /*package*/ final CharSequence getPooledString(int id) {
- return mStrings.get(id);
- }
-
- /*package*/ int mParseState;
- private final XmlBlock mBlock;
- private boolean mStarted = false;
- private boolean mDecNextDepth = false;
- private int mDepth = 0;
- private int mEventType = START_DOCUMENT;
- }
-
- protected void finalize() throws Throwable {
- close();
- }
-
- /**
- * Create from an existing xml block native object. This is
- * -extremely- dangerous -- only use it if you absolutely know what you
- * are doing! The given native object must exist for the entire lifetime
- * of this newly creating XmlBlock.
- */
- XmlBlock(AssetManager assets, int xmlBlock) {
- mAssets = assets;
- mNative = xmlBlock;
- mStrings = new StringBlock(nativeGetStringBlock(xmlBlock), false);
- }
-
- private final AssetManager mAssets;
- private final int mNative;
- private final StringBlock mStrings;
- private boolean mOpen = true;
- private int mOpenCount = 1;
-
- private static final native int nativeCreate(byte[] data,
- int offset,
- int size);
- private static final native int nativeGetStringBlock(int obj);
-
- private static final native int nativeCreateParseState(int obj);
- private static final native int nativeNext(int state);
- private static final native int nativeGetNamespace(int state);
- private static final native int nativeGetName(int state);
- private static final native int nativeGetText(int state);
- private static final native int nativeGetLineNumber(int state);
- private static final native int nativeGetAttributeCount(int state);
- private static final native int nativeGetAttributeNamespace(int state, int idx);
- private static final native int nativeGetAttributeName(int state, int idx);
- private static final native int nativeGetAttributeResource(int state, int idx);
- private static final native int nativeGetAttributeDataType(int state, int idx);
- private static final native int nativeGetAttributeData(int state, int idx);
- private static final native int nativeGetAttributeStringValue(int state, int idx);
- private static final native int nativeGetIdAttribute(int state);
- private static final native int nativeGetClassAttribute(int state);
- private static final native int nativeGetStyleAttribute(int state);
- private static final native int nativeGetAttributeIndex(int state, String namespace, String name);
- private static final native void nativeDestroyParseState(int state);
-
- private static final native void nativeDestroy(int obj);
-}
diff --git a/core/java/android/content/res/XmlResourceParser.java b/core/java/android/content/res/XmlResourceParser.java
deleted file mode 100644
index c59e6d4..0000000
--- a/core/java/android/content/res/XmlResourceParser.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content.res;
-
-import org.xmlpull.v1.XmlPullParser;
-
-import android.util.AttributeSet;
-
-/**
- * The XML parsing interface returned for an XML resource. This is a standard
- * XmlPullParser interface, as well as an extended AttributeSet interface and
- * an additional close() method on this interface for the client to indicate
- * when it is done reading the resource.
- */
-public interface XmlResourceParser extends XmlPullParser, AttributeSet {
- /**
- * Close this interface to the resource. Calls on the interface are no
- * longer value after this call.
- */
- public void close();
-}
-
diff --git a/core/java/android/content/res/package.html b/core/java/android/content/res/package.html
deleted file mode 100644
index bb09dc7..0000000
--- a/core/java/android/content/res/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<HTML>
-<BODY>
-Contains classes for accessing application resources,
-such as raw asset files, colors, drawables, media or other other files
-in the package, plus important device configuration details
-(orientation, input types, etc.) that affect how the application may behave.
-</BODY>
-</HTML> \ No newline at end of file