diff options
39 files changed, 802 insertions, 142 deletions
diff --git a/api/4.xml b/api/4.xml index 49f52713ba85..bca98168dc67 100644 --- a/api/4.xml +++ b/api/4.xml @@ -4123,6 +4123,17 @@ visibility="public" > </field> +<field name="includeInGlobalSearch" + type="int" + transient="false" + volatile="false" + value="16843374" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="indeterminate" type="int" transient="false" @@ -6191,6 +6202,17 @@ visibility="public" > </field> +<field name="queryAfterZeroResults" + type="int" + transient="false" + volatile="false" + value="16843394" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="radioButtonStyle" type="int" transient="false" @@ -6686,6 +6708,17 @@ visibility="public" > </field> +<field name="searchSettingsDescription" + type="int" + transient="false" + volatile="false" + value="16843402" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="searchSuggestAuthority" type="int" transient="false" @@ -6741,6 +6774,17 @@ visibility="public" > </field> +<field name="searchSuggestThreshold" + type="int" + transient="false" + volatile="false" + value="16843373" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="secondaryProgress" type="int" transient="false" @@ -21158,6 +21202,17 @@ visibility="public" > </field> +<field name="INTENT_ACTION_WEB_SEARCH_SETTINGS" + type="java.lang.String" + transient="false" + volatile="false" + value=""android.search.action.WEB_SEARCH_SETTINGS"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="MENU_KEY" type="char" transient="false" @@ -21191,6 +21246,17 @@ visibility="public" > </field> +<field name="SHORTCUT_MIME_TYPE" + type="java.lang.String" + transient="false" + volatile="false" + value=""vnd.android.cursor.item/vnd.android.search.suggest"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="SUGGEST_COLUMN_FORMAT" type="java.lang.String" transient="false" @@ -21279,6 +21345,28 @@ visibility="public" > </field> +<field name="SUGGEST_COLUMN_SHORTCUT_ID" + type="java.lang.String" + transient="false" + volatile="false" + value=""suggest_shortcut_id"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="SUGGEST_COLUMN_SPINNER_WHILE_REFRESHING" + type="java.lang.String" + transient="false" + volatile="false" + value=""suggest_spinner_while_refreshing"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="SUGGEST_COLUMN_TEXT_1" type="java.lang.String" transient="false" @@ -21312,6 +21400,17 @@ visibility="public" > </field> +<field name="SUGGEST_NEVER_MAKE_SHORTCUT" + type="java.lang.String" + transient="false" + volatile="false" + value=""_-1"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="SUGGEST_URI_PATH_QUERY" type="java.lang.String" transient="false" @@ -21323,6 +21422,17 @@ visibility="public" > </field> +<field name="SUGGEST_URI_PATH_SHORTCUT" + type="java.lang.String" + transient="false" + volatile="false" + value=""search_suggest_shortcut"" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="USER_QUERY" type="java.lang.String" transient="false" diff --git a/api/current.xml b/api/current.xml index 7e6c2df31a4e..8fad21363f8f 100644 --- a/api/current.xml +++ b/api/current.xml @@ -18039,6 +18039,50 @@ visibility="public" > </field> +<field name="FLAG_FOREGROUND" + type="int" + transient="false" + volatile="false" + value="2" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="FLAG_PERSISTENT_PROCESS" + type="int" + transient="false" + volatile="false" + value="8" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="FLAG_STARTED" + type="int" + transient="false" + volatile="false" + value="1" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="FLAG_SYSTEM_PROCESS" + type="int" + transient="false" + volatile="false" + value="4" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="activeSince" type="long" transient="false" @@ -18069,6 +18113,16 @@ visibility="public" > </field> +<field name="flags" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="foreground" type="boolean" transient="false" @@ -18139,6 +18193,16 @@ visibility="public" > </field> +<field name="uid" + type="int" + transient="false" + volatile="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</field> </class> <class name="ActivityManager.RunningTaskInfo" extends="java.lang.Object" @@ -97544,6 +97608,8 @@ deprecated="not deprecated" visibility="public" > +<implements name="android.os.Parcelable"> +</implements> <constructor name="Debug.MemoryInfo" type="android.os.Debug.MemoryInfo" static="false" @@ -97552,6 +97618,55 @@ visibility="public" > </constructor> +<method name="describeContents" + return="int" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> +<method name="readFromParcel" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="source" type="android.os.Parcel"> +</parameter> +</method> +<method name="writeToParcel" + return="void" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="dest" type="android.os.Parcel"> +</parameter> +<parameter name="flags" type="int"> +</parameter> +</method> +<field name="CREATOR" + type="android.os.Parcelable.Creator" + transient="false" + volatile="false" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> <field name="dalvikPrivateDirty" type="int" transient="false" @@ -117279,6 +117394,17 @@ visibility="public" > </method> +<method name="hasIccCard" + return="boolean" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +</method> <method name="isNetworkRoaming" return="boolean" abstract="false" diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index 18713e9b5182..3ddc9228b4d7 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -20,6 +20,7 @@ #include <unistd.h> #include <sys/stat.h> #include <limits.h> +#include <errno.h> #include <fcntl.h> #include <sys/time.h> #include <sys/resource.h> @@ -34,6 +35,8 @@ static int end_pattern[] = { 75, 50, 75, 50, 75, 0 }; static struct tm now; +static void dump_kernel_log(const char *path, const char *title) ; + /* dumps the current system state to stdout */ static void dumpstate(int full) { if (full) { @@ -101,8 +104,12 @@ static void dumpstate(int full) { DUMP("/data/system/packages.xml"); PRINT("------ PACKAGE UID ERRORS ------"); DUMP("/data/system/uiderrors.txt"); - PRINT("------ LAST KERNEL LOG ------"); - DUMP("/data/last_kmsg"); + + dump_kernel_log("/data/dontpanic/last_kmsg", "RAMCONSOLE"); + dump_kernel_log("/data/dontpanic/apanic_console", + "PANIC CONSOLE"); + dump_kernel_log("/data/dontpanic/apanic_threads", + "PANIC THREADS"); } PRINT("========================================================"); PRINT("== build.prop"); @@ -295,3 +302,13 @@ int main(int argc, char *argv[]) { return 0; } +static void dump_kernel_log(const char *path, const char *title) + +{ + printf("------ KERNEL %s LOG ------\n", title); + if (access(path, R_OK) < 0) + printf("%s: %s\n", path, strerror(errno)); + else + DUMP(path); +} + diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 07520c9d65f7..ad06fa9c26c0 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -289,6 +289,11 @@ public class ActivityManager { public int pid; /** + * The UID that owns this service. + */ + public int uid; + + /** * The name of the process this service runs in. */ public String process; @@ -299,7 +304,7 @@ public class ActivityManager { public boolean foreground; /** - * The time when the service was first made activity, either by someone + * The time when the service was first made active, either by someone * starting or binding to it. */ public long activeSince; @@ -332,6 +337,35 @@ public class ActivityManager { */ public long restarting; + /** + * Bit for {@link #flags}: set if this service has been + * explicitly started. + */ + public static final int FLAG_STARTED = 1<<0; + + /** + * Bit for {@link #flags}: set if the service has asked to + * run as a foreground process. + */ + public static final int FLAG_FOREGROUND = 1<<1; + + /** + * Bit for {@link #flags): set if the service is running in a + * core system process. + */ + public static final int FLAG_SYSTEM_PROCESS = 1<<2; + + /** + * Bit for {@link #flags): set if the service is running in a + * persistent process. + */ + public static final int FLAG_PERSISTENT_PROCESS = 1<<3; + + /** + * Running flags. + */ + public int flags; + public RunningServiceInfo() { } @@ -342,6 +376,7 @@ public class ActivityManager { public void writeToParcel(Parcel dest, int flags) { ComponentName.writeToParcel(service, dest); dest.writeInt(pid); + dest.writeInt(uid); dest.writeString(process); dest.writeInt(foreground ? 1 : 0); dest.writeLong(activeSince); @@ -350,11 +385,13 @@ public class ActivityManager { dest.writeInt(crashCount); dest.writeLong(lastActivityTime); dest.writeLong(restarting); + dest.writeInt(this.flags); } public void readFromParcel(Parcel source) { service = ComponentName.readFromParcel(source); pid = source.readInt(); + uid = source.readInt(); process = source.readString(); foreground = source.readInt() != 0; activeSince = source.readLong(); @@ -363,6 +400,7 @@ public class ActivityManager { crashCount = source.readInt(); lastActivityTime = source.readLong(); restarting = source.readLong(); + flags = source.readInt(); } public static final Creator<RunningServiceInfo> CREATOR = new Creator<RunningServiceInfo>() { diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index d14ec1576e29..1bb21b9ace2f 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -29,6 +29,7 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.Binder; import android.os.Bundle; +import android.os.Debug; import android.os.Parcelable; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -1107,6 +1108,16 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM reply.writeNoException(); return true; } + + case GET_PROCESS_MEMORY_INFO_TRANSACTION: { + data.enforceInterface(IActivityManager.descriptor); + int pid = data.readInt(); + Debug.MemoryInfo mi = new Debug.MemoryInfo(); + getProcessMemoryInfo(pid, mi); + reply.writeNoException(); + mi.writeToParcel(reply, 0); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -2424,6 +2435,19 @@ class ActivityManagerProxy implements IActivityManager data.recycle(); reply.recycle(); } - + + public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo) + throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + data.writeInt(pid); + mRemote.transact(GET_PROCESS_MEMORY_INFO_TRANSACTION, data, reply, 0); + reply.readException(); + outInfo.readFromParcel(reply); + data.recycle(); + reply.recycle(); + } + private IBinder mRemote; } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1e915b4e9f33..b4e57e040e61 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1546,6 +1546,10 @@ public final class ActivityThread { } } + public void getMemoryInfo(Debug.MemoryInfo outInfo) { + Debug.getMemoryInfo(outInfo); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { long nativeMax = Debug.getNativeHeapSize() / 1024; diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java index ad644655cf7f..15bf9edffccf 100644 --- a/core/java/android/app/ApplicationThreadNative.java +++ b/core/java/android/app/ApplicationThreadNative.java @@ -26,6 +26,7 @@ import android.content.pm.ServiceInfo; import android.content.res.Configuration; import android.os.Binder; import android.os.Bundle; +import android.os.Debug; import android.os.Parcelable; import android.os.RemoteException; import android.os.IBinder; @@ -370,6 +371,16 @@ public abstract class ApplicationThreadNative extends Binder scheduleDestroyBackupAgent(appInfo); return true; } + + case GET_MEMORY_INFO_TRANSACTION: + { + data.enforceInterface(IApplicationThread.descriptor); + Debug.MemoryInfo mi = new Debug.MemoryInfo(); + getMemoryInfo(mi); + reply.writeNoException(); + mi.writeToParcel(reply, 0); + return true; + } } return super.onTransact(code, data, reply, flags); @@ -756,5 +767,16 @@ class ApplicationThreadProxy implements IApplicationThread { IBinder.FLAG_ONEWAY); data.recycle(); } + + public void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IApplicationThread.descriptor); + mRemote.transact(GET_MEMORY_INFO_TRANSACTION, data, reply, 0); + reply.readException(); + outInfo.readFromParcel(reply); + data.recycle(); + reply.recycle(); + } } diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index c3e7224a088e..64daea93e8d3 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -30,6 +30,7 @@ import android.content.pm.ProviderInfo; import android.content.res.Configuration; import android.graphics.Bitmap; import android.net.Uri; +import android.os.Debug; import android.os.RemoteException; import android.os.IBinder; import android.os.IInterface; @@ -272,6 +273,9 @@ public interface IActivityManager extends IInterface { public void closeSystemDialogs(String reason) throws RemoteException; + public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo) + throws RemoteException; + /* * Private non-Binder interfaces */ @@ -428,4 +432,5 @@ public interface IActivityManager extends IInterface { int START_ACTIVITY_IN_PACKAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+94; int KILL_APPLICATION_WITH_UID_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+95; int CLOSE_SYSTEM_DIALOGS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+96; + int GET_PROCESS_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+97; } diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java index 6faaa3468e10..da9a957ad5bf 100644 --- a/core/java/android/app/IApplicationThread.java +++ b/core/java/android/app/IApplicationThread.java @@ -25,6 +25,7 @@ import android.content.pm.ProviderInfo; import android.content.pm.ServiceInfo; import android.content.res.Configuration; import android.os.Bundle; +import android.os.Debug; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.IBinder; @@ -97,6 +98,7 @@ public interface IApplicationThread extends IInterface { void profilerControl(boolean start, String path, ParcelFileDescriptor fd) throws RemoteException; void setSchedulingGroup(int group) throws RemoteException; + void getMemoryInfo(Debug.MemoryInfo outInfo) throws RemoteException; String descriptor = "android.app.IApplicationThread"; @@ -130,4 +132,5 @@ public interface IApplicationThread extends IInterface { int SET_SCHEDULING_GROUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+28; int SCHEDULE_CREATE_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+29; int SCHEDULE_DESTROY_BACKUP_AGENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+30; + int GET_MEMORY_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+31; } diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java index 15144a2bab68..4e9e49c1be80 100644 --- a/core/java/android/content/SyncManager.java +++ b/core/java/android/content/SyncManager.java @@ -148,6 +148,9 @@ class SyncManager implements OnAccountsUpdatedListener { private volatile boolean mSyncPollInitialized; private final PendingIntent mSyncAlarmIntent; private final PendingIntent mSyncPollAlarmIntent; + // Synchronized on "this". Instead of using this directly one should instead call + // its accessor, getConnManager(). + private ConnectivityManager mConnManagerDoNotUseDirectly; private final SyncAdaptersCache mSyncAdapters; @@ -280,6 +283,16 @@ class SyncManager implements OnAccountsUpdatedListener { private final boolean mFactoryTest; + private ConnectivityManager getConnectivityManager() { + synchronized (this) { + if (mConnManagerDoNotUseDirectly == null) { + mConnManagerDoNotUseDirectly = (ConnectivityManager)mContext.getSystemService( + Context.CONNECTIVITY_SERVICE); + } + return mConnManagerDoNotUseDirectly; + } + } + public SyncManager(Context context, boolean factoryTest) { mFactoryTest = factoryTest; @@ -536,6 +549,14 @@ class SyncManager implements OnAccountsUpdatedListener { return; } + if (!getConnectivityManager().getBackgroundDataSetting()) { + if (isLoggable) { + Log.v(TAG, "not syncing because background data usage isn't allowed"); + } + 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"); @@ -602,6 +623,8 @@ class SyncManager implements OnAccountsUpdatedListener { if (hasSyncAdapter) syncableAuthorities.add(requestedAuthority); } + final boolean masterSyncAutomatically = mSyncStorageEngine.getMasterSyncAutomatically(); + for (String authority : syncableAuthorities) { for (Account account : accounts) { int isSyncable = mSyncStorageEngine.getIsSyncable(account, authority); @@ -618,22 +641,36 @@ class SyncManager implements OnAccountsUpdatedListener { if (!syncAdapterInfo.type.supportsUploading() && uploadOnly) { continue; } + // make this an initialization sync if the isSyncable state is unknown Bundle extrasCopy = extras; + long delayCopy = delay; if (isSyncable < 0) { extrasCopy = new Bundle(extras); extrasCopy.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true); + delayCopy = -1; // expedite this + } else { + final boolean syncAutomatically = masterSyncAutomatically + && mSyncStorageEngine.getSyncAutomatically(account, authority); + boolean syncAllowed = manualSync || syncAutomatically; + if (!syncAllowed) { + if (isLoggable) { + Log.d(TAG, "scheduleSync: sync of " + account + ", " + authority + + " is not allowed, dropping request"); + continue; + } + } } if (isLoggable) { Log.v(TAG, "scheduleSync:" - + " delay " + delay + + " delay " + delayCopy + ", source " + source + ", account " + account + ", authority " + authority + ", extras " + extrasCopy); } scheduleSyncOperation( - new SyncOperation(account, source, authority, extrasCopy, delay)); + new SyncOperation(account, source, authority, extrasCopy, delayCopy)); } } } @@ -1591,9 +1628,8 @@ class SyncManager implements OnAccountsUpdatedListener { // found that is runnable (not disabled, etc). If that one is ready to run then // start it, otherwise just get out. SyncOperation op; - final ConnectivityManager connManager = (ConnectivityManager) - mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - final boolean backgroundDataUsageAllowed = connManager.getBackgroundDataSetting(); + final boolean backgroundDataUsageAllowed = + getConnectivityManager().getBackgroundDataSetting(); synchronized (mSyncQueue) { while (true) { op = mSyncQueue.head(); diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index 5d7af69d256a..57bf3f7c7743 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -62,53 +62,53 @@ public class SQLiteDatabase extends SQLiteClosable { */ public enum ConflictAlgorithm { /** - * When a constraint violation occurs, an immediate ROLLBACK occurs, - * thus ending the current transaction, and the command aborts with a - * return code of SQLITE_CONSTRAINT. If no transaction is active + * When a constraint violation occurs, an immediate ROLLBACK occurs, + * thus ending the current transaction, and the command aborts with a + * return code of SQLITE_CONSTRAINT. If no transaction is active * (other than the implied transaction that is created on every command) * then this algorithm works the same as ABORT. */ ROLLBACK("ROLLBACK"), - + /** - * When a constraint violation occurs,no ROLLBACK is executed - * so changes from prior commands within the same transaction + * When a constraint violation occurs,no ROLLBACK is executed + * so changes from prior commands within the same transaction * are preserved. This is the default behavior. */ ABORT("ABORT"), - + /** - * When a constraint violation occurs, the command aborts with a return - * code SQLITE_CONSTRAINT. But any changes to the database that - * the command made prior to encountering the constraint violation + * When a constraint violation occurs, the command aborts with a return + * code SQLITE_CONSTRAINT. But any changes to the database that + * the command made prior to encountering the constraint violation * are preserved and are not backed out. */ FAIL("FAIL"), - + /** - * When a constraint violation occurs, the one row that contains - * the constraint violation is not inserted or changed. - * But the command continues executing normally. Other rows before and - * after the row that contained the constraint violation continue to be + * When a constraint violation occurs, the one row that contains + * the constraint violation is not inserted or changed. + * But the command continues executing normally. Other rows before and + * after the row that contained the constraint violation continue to be * inserted or updated normally. No error is returned. */ IGNORE("IGNORE"), - + /** * When a UNIQUE constraint violation occurs, the pre-existing rows that - * are causing the constraint violation are removed prior to inserting + * are causing the constraint violation are removed prior to inserting * or updating the current row. Thus the insert or update always occurs. - * The command continues executing normally. No error is returned. + * The command continues executing normally. No error is returned. * If a NOT NULL constraint violation occurs, the NULL value is replaced - * by the default value for that column. If the column has no default - * value, then the ABORT algorithm is used. If a CHECK constraint - * violation occurs then the IGNORE algorithm is used. When this conflict - * resolution strategy deletes rows in order to satisfy a constraint, + * by the default value for that column. If the column has no default + * value, then the ABORT algorithm is used. If a CHECK constraint + * violation occurs then the IGNORE algorithm is used. When this conflict + * resolution strategy deletes rows in order to satisfy a constraint, * it does not invoke delete triggers on those rows. * This behavior might change in a future release. */ REPLACE("REPLACE"); - + private final String mValue; ConflictAlgorithm(String value) { mValue = value; @@ -117,7 +117,7 @@ public class SQLiteDatabase extends SQLiteClosable { return mValue; } } - + /** * Maximum Length Of A LIKE Or GLOB Pattern * The pattern matching algorithm used in the default LIKE and GLOB implementation @@ -180,17 +180,19 @@ public class SQLiteDatabase extends SQLiteClosable { private long mLockAcquiredWallTime = 0L; private long mLockAcquiredThreadTime = 0L; - + // limit the frequency of complaints about each database to one within 20 sec - // unless run command adb shell setprop log.tag.Database VERBOSE + // unless run command adb shell setprop log.tag.Database VERBOSE private static final int LOCK_WARNING_WINDOW_IN_MS = 20000; /** If the lock is held this long then a warning will be printed when it is released. */ private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS = 300; private static final int LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS = 100; private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT = 2000; + private static final int SLEEP_AFTER_YIELD_QUANTUM = 500; + private long mLastLockMessageTime = 0L; - + /** Used by native code, do not rename */ /* package */ int mNativeHandle = 0; @@ -205,15 +207,15 @@ public class SQLiteDatabase extends SQLiteClosable { /** The optional factory to use when creating new Cursors */ private CursorFactory mFactory; - + private WeakHashMap<SQLiteClosable, Object> mPrograms; - + private final RuntimeException mLeakedException; // package visible, since callers will access directly to minimize overhead in the case // that logging is not enabled. /* package */ final boolean mLogStats; - + /** * @param closable */ @@ -225,7 +227,7 @@ public class SQLiteDatabase extends SQLiteClosable { unlock(); } } - + void removeSQLiteClosable(SQLiteClosable closable) { lock(); try { @@ -233,8 +235,8 @@ public class SQLiteDatabase extends SQLiteClosable { } finally { unlock(); } - } - + } + @Override protected void onAllReferencesReleased() { if (isOpen()) { @@ -245,10 +247,10 @@ public class SQLiteDatabase extends SQLiteClosable { /** * Attempts to release memory that SQLite holds but does not require to * operate properly. Typically this memory will come from the page cache. - * + * * @return the number of bytes actually released */ - static public native int releaseMemory(); + static public native int releaseMemory(); /** * Control whether or not the SQLiteDatabase is made thread-safe by using locks @@ -284,7 +286,7 @@ public class SQLiteDatabase extends SQLiteClosable { * touch the native sqlite3* object since it is single threaded and uses * a polling lock contention algorithm. The lock is recursive, and may be acquired * multiple times by the same thread. This is a no-op if mLockingEnabled is false. - * + * * @see #unlock() */ /* package */ void lock() { @@ -320,7 +322,7 @@ public class SQLiteDatabase extends SQLiteClosable { /** * Releases the database lock. This is a no-op if mLockingEnabled is false. - * + * * @see #unlock() */ /* package */ void unlock() { @@ -350,7 +352,7 @@ public class SQLiteDatabase extends SQLiteClosable { private void checkLockHoldTime() { // Use elapsed real-time since the CPU may sleep when waiting for IO long elapsedTime = SystemClock.elapsedRealtime(); - long lockedTime = elapsedTime - mLockAcquiredWallTime; + long lockedTime = elapsedTime - mLockAcquiredWallTime; if (lockedTime < LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT && !Log.isLoggable(TAG, Log.VERBOSE) && (elapsedTime - mLastLockMessageTime) < LOCK_WARNING_WINDOW_IN_MS) { @@ -567,10 +569,21 @@ public class SQLiteDatabase extends SQLiteClosable { } } if (sleepAfterYieldDelay > 0) { - try { - Thread.sleep(sleepAfterYieldDelay); - } catch (InterruptedException e) { - Thread.interrupted(); + // Sleep for up to sleepAfterYieldDelay milliseconds, waking up periodically to + // check if anyone is using the database. If the database is not contended, + // retake the lock and return. + long remainingDelay = sleepAfterYieldDelay; + while (remainingDelay > 0) { + try { + Thread.sleep(remainingDelay < SLEEP_AFTER_YIELD_QUANTUM ? + remainingDelay : SLEEP_AFTER_YIELD_QUANTUM); + } catch (InterruptedException e) { + Thread.interrupted(); + } + remainingDelay -= SLEEP_AFTER_YIELD_QUANTUM; + if (mLock.getQueueLength() == 0) { + break; + } } } beginTransaction(); @@ -720,9 +733,9 @@ public class SQLiteDatabase extends SQLiteClosable { if (program != null) { program.onAllReferencesReleasedFromContainer(); } - } + } } - + /** * Native call to close the database. */ @@ -1157,8 +1170,8 @@ public class SQLiteDatabase extends SQLiteClosable { /** * Runs the provided SQL and returns a cursor over the result set. - * The cursor will read an initial set of rows and the return to the caller. - * It will continue to read in batches and send data changed notifications + * The cursor will read an initial set of rows and the return to the caller. + * It will continue to read in batches and send data changed notifications * when the later batches are ready. * @param sql the SQL query. The SQL string must not be ; terminated * @param selectionArgs You may include ?s in where clause in the query, @@ -1167,19 +1180,19 @@ public class SQLiteDatabase extends SQLiteClosable { * @param initialRead set the initial count of items to read from the cursor * @param maxRead set the count of items to read on each iteration after the first * @return A {@link Cursor} object, which is positioned before the first entry - * + * * This work is incomplete and not fully tested or reviewed, so currently * hidden. * @hide */ - public Cursor rawQuery(String sql, String[] selectionArgs, + public Cursor rawQuery(String sql, String[] selectionArgs, int initialRead, int maxRead) { SQLiteCursor c = (SQLiteCursor)rawQueryWithFactory( null, sql, selectionArgs, null); c.setLoadStyle(initialRead, maxRead); return c; } - + /** * Convenience method for inserting a row into the database. * @@ -1232,7 +1245,7 @@ public class SQLiteDatabase extends SQLiteClosable { */ public long replace(String table, String nullColumnHack, ContentValues initialValues) { try { - return insertWithOnConflict(table, nullColumnHack, initialValues, + return insertWithOnConflict(table, nullColumnHack, initialValues, ConflictAlgorithm.REPLACE); } catch (SQLException e) { Log.e(TAG, "Error inserting " + initialValues, e); @@ -1254,7 +1267,7 @@ public class SQLiteDatabase extends SQLiteClosable { */ public long replaceOrThrow(String table, String nullColumnHack, ContentValues initialValues) throws SQLException { - return insertWithOnConflict(table, nullColumnHack, initialValues, + return insertWithOnConflict(table, nullColumnHack, initialValues, ConflictAlgorithm.REPLACE); } @@ -1410,7 +1423,7 @@ public class SQLiteDatabase extends SQLiteClosable { public int update(String table, ContentValues values, String whereClause, String[] whereArgs) { return updateWithOnConflict(table, values, whereClause, whereArgs, null); } - + /** * Convenience method for updating rows in the database. * @@ -1423,7 +1436,7 @@ public class SQLiteDatabase extends SQLiteClosable { * @return the number of rows affected * @hide */ - public int updateWithOnConflict(String table, ContentValues values, + public int updateWithOnConflict(String table, ContentValues values, String whereClause, String[] whereArgs, ConflictAlgorithm algorithm) { if (!isOpen()) { throw new IllegalStateException("database not open"); @@ -1440,7 +1453,7 @@ public class SQLiteDatabase extends SQLiteClosable { sql.append(algorithm.value()); sql.append(" "); } - + sql.append(table); sql.append(" SET "); @@ -1601,7 +1614,7 @@ public class SQLiteDatabase extends SQLiteClosable { mFlags = flags; mPath = path; mLogStats = "1".equals(android.os.SystemProperties.get("db.logstats")); - + mLeakedException = new IllegalStateException(path + " SQLiteDatabase created and never closed"); mFactory = factory; diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java index b0fc78e0ca40..5352cf63eaf3 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -104,7 +104,7 @@ public final class Debug * This class is used to retrieved various statistics about the memory mappings for this * process. The returns info broken down by dalvik, native, and other. All results are in kB. */ - public static class MemoryInfo { + public static class MemoryInfo implements Parcelable { /** The proportional set size for dalvik. */ public int dalvikPss; /** The private dirty pages used by dalvik. */ @@ -125,6 +125,50 @@ public final class Debug public int otherPrivateDirty; /** The shared dirty pages used by everything else. */ public int otherSharedDirty; + + public MemoryInfo() { + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(dalvikPss); + dest.writeInt(dalvikPrivateDirty); + dest.writeInt(dalvikSharedDirty); + dest.writeInt(nativePss); + dest.writeInt(nativePrivateDirty); + dest.writeInt(nativeSharedDirty); + dest.writeInt(otherPss); + dest.writeInt(otherPrivateDirty); + dest.writeInt(otherSharedDirty); + } + + public void readFromParcel(Parcel source) { + dalvikPss = source.readInt(); + dalvikPrivateDirty = source.readInt(); + dalvikSharedDirty = source.readInt(); + nativePss = source.readInt(); + nativePrivateDirty = source.readInt(); + nativeSharedDirty = source.readInt(); + otherPss = source.readInt(); + otherPrivateDirty = source.readInt(); + otherSharedDirty = source.readInt(); + } + + public static final Creator<MemoryInfo> CREATOR = new Creator<MemoryInfo>() { + public MemoryInfo createFromParcel(Parcel source) { + return new MemoryInfo(source); + } + public MemoryInfo[] newArray(int size) { + return new MemoryInfo[size]; + } + }; + + private MemoryInfo(Parcel source) { + readFromParcel(source); + } } @@ -556,6 +600,13 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo public static native void getMemoryInfo(MemoryInfo memoryInfo); /** + * Note: currently only works when the requested pid has the same UID + * as the caller. + * @hide + */ + public static native void getMemoryInfo(int pid, MemoryInfo memoryInfo); + + /** * Establish an object allocation limit in the current thread. Useful * for catching regressions in code that is expected to operate * without causing any allocations. diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index e48f539c8410..9dfab99e5cb8 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -991,13 +991,13 @@ public final class ContactsContract { private Phone() {} /** MIME type used when storing this in data table. */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/phone_v2"; /** * The MIME type of {@link #CONTENT_URI} providing a directory of * phones. */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/phone_v2"; /** * The content:// style URI for all data records of the @@ -1076,7 +1076,7 @@ public final class ContactsContract { private Email() {} /** MIME type used when storing this in data table. */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email"; + public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email_v2"; /** * The content:// style URI for all data records of the @@ -1114,13 +1114,14 @@ public final class ContactsContract { } /** MIME type used when storing this in data table. */ - public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/postal-address"; + public static final String CONTENT_ITEM_TYPE = + "vnd.android.cursor.item/postal-address_v2"; /** * The MIME type of {@link #CONTENT_URI} providing a directory of * postal addresses. */ - public static final String CONTENT_TYPE = "vnd.android.cursor.dir/postal-address"; + public static final String CONTENT_TYPE = "vnd.android.cursor.dir/postal-address_v2"; /** * The content:// style URI for all data records of the diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java index 0207330259e6..4584382001ff 100644 --- a/core/java/android/provider/Telephony.java +++ b/core/java/android/provider/Telephony.java @@ -558,6 +558,23 @@ public final class Telephony { "android.provider.Telephony.SIM_FULL"; /** + * Broadcast Action: An incoming SMS has been rejected by the + * telephony framework. This intent is sent in lieu of any + * of the RECEIVED_ACTION intents. The intent will have the + * following extra value:</p> + * + * <ul> + * <li><em>result</em> - An int result code, eg, + * <code>{@link #RESULT_SMS_OUT_OF_MEMORY}</code>, + * indicating the error returned to the network.</li> + * </ul> + + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String SMS_REJECTED_ACTION = + "android.provider.Telephony.SMS_REJECTED"; + + /** * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a * {@link #DATA_SMS_RECEIVED_ACTION} intent. * @@ -1522,6 +1539,9 @@ public final class Telephony { public static final Uri CONTENT_DRAFT_URI = Uri.parse( "content://mms-sms/draft"); + public static final Uri CONTENT_LOCKED_URI = Uri.parse( + "content://mms-sms/locked"); + /*** * Pass in a query parameter called "pattern" which is the text * to search for. diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index 29dc2ea5246e..a92800d011ee 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -1527,7 +1527,7 @@ public abstract class Layout { if (bm != null) { workPaint.set(paint); Styled.measureText(paint, workPaint, text, - offset, offset + 1, null); + j, j + 2, null); float wid = (float) bm.getWidth() * -workPaint.ascent() / bm.getHeight(); diff --git a/core/java/android/webkit/ContentLoader.java b/core/java/android/webkit/ContentLoader.java index 27cd6b5356a1..19aa087c49e6 100644 --- a/core/java/android/webkit/ContentLoader.java +++ b/core/java/android/webkit/ContentLoader.java @@ -57,6 +57,16 @@ class ContentLoader extends StreamLoader { } + private String errString(Exception ex) { + String exMessage = ex.getMessage(); + String errString = mContext.getString( + com.android.internal.R.string.httpErrorFileNotFound); + if (exMessage != null) { + errString += " " + exMessage; + } + return errString; + } + @Override protected boolean setupStreamAndSendStatus() { Uri uri = Uri.parse(mUrl); @@ -73,28 +83,16 @@ class ContentLoader extends StreamLoader { mDataStream = mContext.getContentResolver().openInputStream(uri); mHandler.status(1, 1, 0, "OK"); } catch (java.io.FileNotFoundException ex) { - mHandler.error( - EventHandler.FILE_NOT_FOUND_ERROR, - mContext.getString( - com.android.internal.R.string.httpErrorFileNotFound) + - " " + ex.getMessage()); + mHandler.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex)); return false; } catch (java.io.IOException ex) { - mHandler.error( - EventHandler.FILE_ERROR, - mContext.getString( - com.android.internal.R.string.httpErrorFileNotFound) + - " " + ex.getMessage()); + mHandler.error(EventHandler.FILE_ERROR, errString(ex)); return false; } catch (RuntimeException ex) { // readExceptionWithFileNotFoundExceptionFromParcel in DatabaseUtils // can throw a serial of RuntimeException. Catch them all here. - mHandler.error( - EventHandler.FILE_ERROR, - mContext.getString( - com.android.internal.R.string.httpErrorFileNotFound) + - " " + ex.getMessage()); + mHandler.error(EventHandler.FILE_ERROR, errString(ex)); return false; } return true; diff --git a/core/java/android/webkit/FileLoader.java b/core/java/android/webkit/FileLoader.java index 54a4c1d12468..085f1f405c72 100644 --- a/core/java/android/webkit/FileLoader.java +++ b/core/java/android/webkit/FileLoader.java @@ -72,6 +72,15 @@ class FileLoader extends StreamLoader { } } + private String errString(Exception ex) { + String exMessage = ex.getMessage(); + String errString = mContext.getString(R.string.httpErrorFileNotFound); + if (exMessage != null) { + errString += " " + exMessage; + } + return errString; + } + @Override protected boolean setupStreamAndSendStatus() { try { @@ -95,16 +104,11 @@ class FileLoader extends StreamLoader { mHandler.status(1, 1, 0, "OK"); } catch (java.io.FileNotFoundException ex) { - mHandler.error( - EventHandler.FILE_NOT_FOUND_ERROR, - mContext.getString(R.string.httpErrorFileNotFound) + - " " + ex.getMessage()); + mHandler.error(EventHandler.FILE_NOT_FOUND_ERROR, errString(ex)); return false; } catch (java.io.IOException ex) { - mHandler.error(EventHandler.FILE_ERROR, - mContext.getString(R.string.httpErrorFileNotFound) + - " " + ex.getMessage()); + mHandler.error(EventHandler.FILE_ERROR, errString(ex)); return false; } return true; diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index f474f15ac479..081250b1cd67 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -1244,6 +1244,18 @@ final class WebViewCore { } } + private synchronized boolean hasMessages(int what) { + if (mBlockMessages) { + return false; + } + if (mMessages != null) { + Log.w(LOGTAG, "hasMessages() is not supported in this case."); + return false; + } else { + return mHandler.hasMessages(what); + } + } + private synchronized void sendMessageDelayed(Message msg, long delay) { if (mBlockMessages) { return; @@ -1355,9 +1367,22 @@ final class WebViewCore { // We don't want anyone to post a message between removing pending // messages and sending the destroy message. synchronized (mEventHub) { + // RESUME_TIMERS and PAUSE_TIMERS are per process base. They need to + // be preserved even the WebView is destroyed. + // Note: we should not have more than one RESUME_TIMERS/PAUSE_TIMERS + boolean hasResume = mEventHub.hasMessages(EventHub.RESUME_TIMERS); + boolean hasPause = mEventHub.hasMessages(EventHub.PAUSE_TIMERS); mEventHub.removeMessages(); mEventHub.sendMessageAtFrontOfQueue( Message.obtain(null, EventHub.DESTROY)); + if (hasPause) { + mEventHub.sendMessageAtFrontOfQueue( + Message.obtain(null, EventHub.PAUSE_TIMERS)); + } + if (hasResume) { + mEventHub.sendMessageAtFrontOfQueue( + Message.obtain(null, EventHub.RESUME_TIMERS)); + } mEventHub.blockMessages(); mWebView = null; } diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index b179a1396941..2f28d9f02cbc 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -651,6 +651,7 @@ public class ProgressBar extends View { if (mProgress > max) { mProgress = max; + refreshProgress(R.id.progress, mProgress, false); } } } diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp index b4c60f1ff2dc..3ee404adc434 100644 --- a/core/jni/android_os_Debug.cpp +++ b/core/jni/android_os_Debug.cpp @@ -200,12 +200,13 @@ static void load_maps(int pid, stats_t* stats) fclose(fp); } -static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) +static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, + jint pid, jobject object) { stats_t stats; memset(&stats, 0, sizeof(stats_t)); - load_maps(getpid(), &stats); + load_maps(pid, &stats); env->SetIntField(object, dalvikPss_field, stats.dalvikPss); env->SetIntField(object, dalvikPrivateDirty_field, stats.dalvikPrivateDirty); @@ -220,6 +221,11 @@ static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject o env->SetIntField(object, otherSharedDirty_field, stats.otherSharedDirty); } +static void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) +{ + android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object); +} + static jint read_binder_stat(const char* stat) { FILE* fp = fopen(BINDER_STATS, "r"); @@ -281,6 +287,8 @@ static JNINativeMethod gMethods[] = { (void*) android_os_Debug_getNativeHeapFreeSize }, { "getMemoryInfo", "(Landroid/os/Debug$MemoryInfo;)V", (void*) android_os_Debug_getDirtyPages }, + { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V", + (void*) android_os_Debug_getDirtyPagesPid }, { "getBinderSentTransactions", "()I", (void*) android_os_Debug_getBinderSentTransactions }, { "getBinderReceivedTransactions", "()I", diff --git a/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png Binary files differnew file mode 100644 index 000000000000..58d2dbb3af7c --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png diff --git a/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png Binary files differnew file mode 100644 index 000000000000..cd1afe9a2bed --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png diff --git a/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png Binary files differnew file mode 100644 index 000000000000..c398d6fa7f5f --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png diff --git a/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png b/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png Binary files differnew file mode 100644 index 000000000000..e1eb5b056e78 --- /dev/null +++ b/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png diff --git a/core/res/res/drawable/stat_sys_data_connected_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_connected_1x.png Binary files differindex 130724fd0550..130724fd0550 100644 --- a/core/res/res/drawable/stat_sys_data_connected_1x.png +++ b/core/res/res/drawable-mdpi/stat_sys_data_connected_1x.png diff --git a/core/res/res/drawable/stat_sys_data_in_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_in_1x.png Binary files differindex 3155e632fe7b..3155e632fe7b 100644 --- a/core/res/res/drawable/stat_sys_data_in_1x.png +++ b/core/res/res/drawable-mdpi/stat_sys_data_in_1x.png diff --git a/core/res/res/drawable/stat_sys_data_inandout_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_inandout_1x.png Binary files differindex 1017e3bb4166..1017e3bb4166 100644 --- a/core/res/res/drawable/stat_sys_data_inandout_1x.png +++ b/core/res/res/drawable-mdpi/stat_sys_data_inandout_1x.png diff --git a/core/res/res/drawable/stat_sys_data_out_1x.png b/core/res/res/drawable-mdpi/stat_sys_data_out_1x.png Binary files differindex 54187912f6b8..54187912f6b8 100644 --- a/core/res/res/drawable/stat_sys_data_out_1x.png +++ b/core/res/res/drawable-mdpi/stat_sys_data_out_1x.png diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd index 0248985eecb3..e5083923370f 100644 --- a/docs/html/guide/topics/manifest/uses-feature-element.jd +++ b/docs/html/guide/topics/manifest/uses-feature-element.jd @@ -15,20 +15,60 @@ page.title=<uses-feature> <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code></dd> <dt>description:</dt> -<dd>This element specifies a specific feature used by the application. +<dd>This element declares a specific feature used by the application. Android provides some features that may not be equally supported by all Android devices. In a manner similar to the <code><a href="uses-sdk-element.html"><uses-sdk></a></code> -element, this element allows an application to specify which potentially variable -features it requires. In this way, the application -will not be installed on devices that do not offer the required feature.</p> +element, this element allows an application to specify which device-variable +features it uses. In this way, the application +will not be installed on devices that do not offer the feature.</p> -<p>For example, an application might specify that it requires a certain version of Open GL. -If a device does not support that version of Open GL, then it will not allow installation of the application.</p> +<p>For example, an application might specify that it requires a camera with auto-focus capabilities. +If a device does not provide a camera with auto-focus, then it will not allow +installation of the application.</p> + +<p>In order to maintain strict device compatibility, it's very important that you use +this element to declare all features that your application uses. Failure to declare +a feature may result your application being installed on a device +that does not support the feature and your application failing.</p> + +<p>For some features, there may exist a specfic attribute that allows you to define +a version of the feature, such as the version of Open GL used (declared with +<a href="#glEsVersion">{@code glEsVersion}</a>). Other features that either do or do not +exist for a device, such as camera auto-focus, are declared using the +<a href="#name">{@code name}</a> attribute.</p> + +<p>Any software or hardware features that may vary among Android-powered +devices will be listed on this page among the attributes below. If you see any features +here that you use in your application, you should include a {@code +<uses-feature>} element for each one. For example, if your application uses the device +camera, then you should include the following in your {@code AndroidManifest.xml}:</p> + +<pre> +<uses-feature android:name="android.hardware.camera" /> +</pre> + +<p>If you declare "android.hardware.camera", then your application is considered +compatible with all devices that include a camera, regardless of whether auto-focus is +available or not. If you also use the auto-focus features (available through the {@link +android.hardware.Camera Camera API}), then you need to include an additional +{@code <uses-feature>} element that declares the "android.hardware.camera.autofocus" +feature. Also note that you must still request the {@link android.Manifest.permission#CAMERA +CAMERA permission}. Requesting permission grants your application access to the +appropriate hardware and software, while declaring the features used by +your application ensures proper device compatibility.</p> + +<p>Although the {@code <uses-feature>} element is only activated for devices running +API Level 4 or higher, it is safe to include this for applications that declare +a <a href="uses-sdk-element.html#min">{@code minSdkVersion}</a> +of "3" or lower. Devices running older versions of the platform +will simply ignore this element, but newer devices will recognize it and enforce +installation restrictions based on whether the device supports the feature.</p> <p class="note"><strong>Note:</strong> For each feature required by your application, you must include a new {@code <uses-feature>} element. Multiple features cannot be declared in one instance of this element.</p> + </dd> @@ -51,16 +91,30 @@ instance of this element.</p> <table> <tr> + <th>Feature</th> <th>Value</th> <th>Description</th> </tr><tr> + <td rowspan="3">Camera</td> <td>"{@code android.hardware.camera}"</td> <td>The application requires a camera.</td> </tr><tr> <td>"{@code android.hardware.camera.autofocus}"</td> <td>The application requires a camera with auto-focus capability. As a prerequisite, "{@code android.hardware.camera}" must also be declared - with a separate {@code <uses-feature>} element.</td> + with a separate {@code <uses-feature>} element. + </td> + <tr> + <td colspan="2"> + <strong>Note:</strong> Any application that requests the + {@link android.Manifest.permission#CAMERA CAMERA permission} but does <em>not</em> + declare any camera features with the {@code <uses-feature>} element will be assumed + to use all camera features (such as auto-focus). Thus, the application will not + be compatible with devices that do not support all features. Please use + {@code <uses-feature>} to declare only the camera features that your + application needs. + </td> + </tr> </tr> </table> diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd index adcdc286cbed..ee8d03dc06d1 100644 --- a/docs/html/guide/topics/manifest/uses-sdk-element.jd +++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd @@ -3,7 +3,10 @@ page.title=<uses-sdk> <dl class="xml"> <dt>syntax:</dt> -<dd><pre class="stx"><uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>" /></pre></dd> +<dd><pre> +<uses-sdk android:<a href="#min">minSdkVersion</a>="<i>integer</i>" + android:<a href="#max">maxSdkVersion</a>="<i>integer</i>" + android:<a href="#target">targetSdkVersion</a>="<i>integer</i>" /></pre></dd> <dt>contained in:</dt> <dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code></dd> @@ -64,12 +67,16 @@ and minor versions).</p> <dt><a name="target"></a>{@code android:targetSdkVersion}</dt> <dd>An integer designating the API Level that the application is targetting. - <p>With this attribute set, the application says that is is be able to run on + <p>With this attribute set, the application says that it is able to run on older versions (down to {@code minSdkVersion}), but was explicitly tested to work with the version specified here. - Specifying this version allows the platform to disable compatibility - code that is not required or enable newer features that are not - available to older applications.</p> + Specifying this target version allows the platform to disable compatibility + settings that are not required for the target version (which may otherwise be turned on + in order to maintain forward-compatibility) or enable newer features that are not + available to older applications. This does not mean that you can program different + features for different versions of the platform—it simply informs the platform that you + have tested against the target version and the platform should not perform any extra + work to maintain forward-compatibility with the target version.</p> <p>Introduced in: API Level 4</p> </dd> diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp index 3a419b579b89..ef7164152367 100644 --- a/libs/audioflinger/AudioFlinger.cpp +++ b/libs/audioflinger/AudioFlinger.cpp @@ -1449,6 +1449,8 @@ void AudioFlinger::MixerThread::putTracks( int j = activeTracks.indexOf(t); if (j >= 0) { mActiveTracks.add(t); + // force buffer refilling and no ramp volume when the track is mixed for the first time + t->mFillingUpStatus = Track::FS_FILLING; } } } @@ -3512,10 +3514,11 @@ status_t AudioFlinger::setStreamOutput(uint32_t stream, int output) if (tracks.size()) { dstThread->putTracks(tracks, activeTracks); } - dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream); } } + dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream); + return NO_ERROR; } diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp index 071a90de5b6a..0ec8dabb9bdb 100644 --- a/packages/TtsService/jni/android_tts_SynthProxy.cpp +++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp @@ -41,7 +41,7 @@ #define FILTER_LOWSHELF_ATTENUATION -18.0f // in dB #define FILTER_TRANSITION_FREQ 1100.0f // in Hz #define FILTER_SHELF_SLOPE 1.0f // Q -#define FILTER_GAIN 6.0f // linear gain +#define FILTER_GAIN 5.5f // linear gain // such a huge gain is justified by how much energy in the low frequencies is "wasted" at the output // of the synthesis. The low shelving filter removes it, leaving room for amplification. diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index d4e69c0ac2e6..c9452d3209a8 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -68,6 +68,7 @@ import android.graphics.Bitmap; import android.net.Uri; import android.os.Binder; import android.os.Bundle; +import android.os.Debug; import android.os.Environment; import android.os.FileUtils; import android.os.Handler; @@ -4895,6 +4896,25 @@ public final class ActivityManagerService extends ActivityManagerNative implemen Binder.restoreCallingIdentity(origId); } + public void getProcessMemoryInfo(int pid, Debug.MemoryInfo mi) + throws RemoteException { + ProcessRecord proc; + synchronized (mPidsSelfLocked) { + proc = mPidsSelfLocked.get(pid); + } + + if (proc == null) { + throw new RemoteException(); + } + + IApplicationThread thread = proc.thread; + if (thread == null) { + throw new RemoteException(); + } + + thread.getMemoryInfo(mi); + } + private void restartPackageLocked(final String packageName, int uid) { uninstallPackageLocked(packageName, uid, false); Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED, @@ -7367,6 +7387,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // In this case the provider is a single instance, so we can // return it right away. if (r != null) { + if(true) Log.v(TAG, "Adding content provider requested by "+ + r.processName +" from process "+cpr.info.processName); r.conProviders.add(cpr); cpr.clients.add(r); } else { @@ -7477,6 +7499,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen mProvidersByName.put(name, cpr); if (r != null) { + if(true) Log.v(TAG, "Adding content provider requested by "+ + r.processName +" from process "+cpr.info.processName); r.conProviders.add(cpr); cpr.clients.add(r); } else { @@ -7532,7 +7556,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen ContentProviderRecord cpr = (ContentProviderRecord)mProvidersByName.get(name); if(cpr == null) { //remove from mProvidersByClass - if(localLOGV) Log.v(TAG, name+" content provider not found in providers list"); + if(true) Log.v(TAG, name+" content provider not found in providers list"); return; } final ProcessRecord r = getRecordForAppLocked(caller); @@ -7543,11 +7567,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } //update content provider record entry info ContentProviderRecord localCpr = (ContentProviderRecord) mProvidersByClass.get(cpr.info.name); - if(localLOGV) Log.v(TAG, "Removing content provider requested by "+ - r.info.processName+" from process "+localCpr.appInfo.processName); - if(localCpr.appInfo.processName == r.info.processName) { + if(true) Log.v(TAG, "Removing content provider requested by "+ + r.processName+" from process "+localCpr.info.processName); + if(localCpr.app == r) { //should not happen. taken care of as a local provider - if(localLOGV) Log.v(TAG, "local provider doing nothing Ignoring other names"); + if(true) Log.v(TAG, "local provider doing nothing Ignoring other names"); return; } else { localCpr.clients.remove(r); @@ -9818,6 +9842,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (r.app != null) { info.pid = r.app.pid; } + info.uid = r.appInfo.uid; info.process = r.processName; info.foreground = r.isForeground; info.activeSince = r.createTime; @@ -9825,6 +9850,18 @@ public final class ActivityManagerService extends ActivityManagerNative implemen info.clientCount = r.connections.size(); info.crashCount = r.crashCount; info.lastActivityTime = r.lastActivity; + if (r.isForeground) { + info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND; + } + if (r.startRequested) { + info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED; + } + if (r.app != null && r.app.pid == Process.myPid()) { + info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS; + } + if (r.app != null && r.app.persistent) { + info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS; + } return info; } diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index f3304a3fb323..a690e3c04995 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -481,6 +481,13 @@ public class TelephonyManager { public static final int SIM_STATE_READY = 5; /** + * @return true if a ICC card is present + */ + public boolean hasIccCard() { + return PhoneFactory.getDefaultPhone().getIccCard().hasIccCard(); + } + + /** * Returns a constant indicating the state of the * device SIM card. * diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java index 665706022887..200340e7b9f0 100644 --- a/telephony/java/com/android/internal/telephony/IccCard.java +++ b/telephony/java/com/android/internal/telephony/IccCard.java @@ -667,6 +667,19 @@ public abstract class IccCard { return false; } + /** + * @return true if a ICC card is present + */ + public boolean hasIccCard() { + boolean isIccPresent; + if (mPhone.getPhoneName().equals("GSM")) { + return mIccCardStatus.getCardState().isCardPresent(); + } else { + // TODO: Make work with a CDMA device with a RUIM card. + return false; + } + } + private void log(String msg) { Log.d(mLogTag, "[IccCard] " + msg); } diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java index 7efaa2eb4b35..d26a092f16a2 100644 --- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java @@ -150,7 +150,8 @@ public abstract class SMSDispatcher extends Handler { private static SmsMessage mSmsMessage; private static SmsMessageBase mSmsMessageBase; private SmsMessageBase.SubmitPduBase mSubmitPduBase; - private boolean mStorageAvailable = true; + + protected boolean mStorageAvailable = true; protected static int getNextConcatenatedRef() { sConcatenatedRef += 1; @@ -294,19 +295,15 @@ public abstract class SMSDispatcher extends Handler { sms = (SmsMessage) ar.result; try { - if (mStorageAvailable) { - int result = dispatchMessage(sms.mWrappedSmsMessage); - if (result != Activity.RESULT_OK) { - // RESULT_OK means that message was broadcast for app(s) to handle. - // Any other result, we should ack here. - boolean handled = (result == Intents.RESULT_SMS_HANDLED); - acknowledgeLastIncomingSms(handled, result, null); - } - } else { - acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_OUT_OF_MEMORY, null); + int result = dispatchMessage(sms.mWrappedSmsMessage); + if (result != Activity.RESULT_OK) { + // RESULT_OK means that message was broadcast for app(s) to handle. + // Any other result, we should ack here. + boolean handled = (result == Intents.RESULT_SMS_HANDLED); + notifyAndAcknowledgeLastIncomingSms(handled, result, null); } } catch (RuntimeException ex) { - acknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null); + notifyAndAcknowledgeLastIncomingSms(false, Intents.RESULT_SMS_GENERIC_ERROR, null); } break; @@ -866,6 +863,25 @@ public abstract class SMSDispatcher extends Handler { int result, Message response); /** + * Notify interested apps if the framework has rejected an incoming SMS, + * and send an acknowledge message to the network. + * @param success indicates that last message was successfully received. + * @param result result code indicating any error + * @param response callback message sent when operation completes. + */ + private void notifyAndAcknowledgeLastIncomingSms(boolean success, + int result, Message response) { + if (!success) { + // broadcast SMS_REJECTED_ACTION intent + Intent intent = new Intent(Intents.SMS_REJECTED_ACTION); + intent.putExtra("result", result); + mWakeLock.acquire(WAKE_LOCK_TIMEOUT); + mContext.sendBroadcast(intent, "android.permission.RECEIVE_SMS"); + } + acknowledgeLastIncomingSms(success, result, response); + } + + /** * Check if a SmsTracker holds multi-part Sms * * @param tracker a SmsTracker could hold a multi-part Sms diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java index ca15a03d6135..1e3a2e192a97 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java @@ -33,6 +33,7 @@ import android.preference.PreferenceManager; import android.util.Config; import android.util.Log; import android.telephony.SmsManager; +import android.telephony.SmsMessage.MessageClass; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.CommandsInterface; @@ -91,8 +92,20 @@ final class CdmaSMSDispatcher extends SMSDispatcher { int teleService = sms.getTeleService(); boolean handled = false; - if ((sms.getUserData() == null) && (SmsEnvelope.TELESERVICE_MWI != teleService) && - (SmsEnvelope.TELESERVICE_VMN != teleService)) { + if ((SmsEnvelope.TELESERVICE_VMN == teleService) || + (SmsEnvelope.TELESERVICE_MWI == teleService)) { + // handling Voicemail + int voicemailCount = sms.getNumOfVoicemails(); + Log.d(TAG, "Voicemail count=" + voicemailCount); + // Store the voicemail count in preferences. + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( + ((CDMAPhone) mPhone).getContext()); + SharedPreferences.Editor editor = sp.edit(); + editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount); + editor.commit(); + ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount); + handled = true; + } else if ((sms.getUserData() == null)) { if (Config.LOGD) { Log.d(TAG, "Received SMS without user data"); } @@ -103,22 +116,16 @@ final class CdmaSMSDispatcher extends SMSDispatcher { return Intents.RESULT_SMS_HANDLED; } + if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) { + // It's a storable message and there's no storage available. Bail. + // (See C.S0015-B v2.0 for a description of "Immediate Display" + // messages, which we represent as CLASS_0.) + return Intents.RESULT_SMS_OUT_OF_MEMORY; + } + if (SmsEnvelope.TELESERVICE_WAP == teleService) { return processCdmaWapPdu(sms.getUserData(), sms.messageRef, sms.getOriginatingAddress()); - } else if ((SmsEnvelope.TELESERVICE_VMN == teleService) || - (SmsEnvelope.TELESERVICE_MWI == teleService)) { - // handling Voicemail - int voicemailCount = sms.getNumOfVoicemails(); - Log.d(TAG, "Voicemail count=" + voicemailCount); - // Store the voicemail count in preferences. - SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences( - ((CDMAPhone) mPhone).getContext()); - SharedPreferences.Editor editor = sp.edit(); - editor.putInt(CDMAPhone.VM_COUNT_CDMA, voicemailCount); - editor.commit(); - ((CDMAPhone) mPhone).updateMessageWaitingIndicator(voicemailCount); - return Intents.RESULT_SMS_HANDLED; } /** diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java index b412fec5bc45..0ca31488cc34 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java @@ -37,6 +37,7 @@ import com.android.internal.telephony.SmsMessageBase; import java.util.ArrayList; import java.util.HashMap; +import static android.telephony.SmsMessage.MessageClass; final class GsmSMSDispatcher extends SMSDispatcher { private static final String TAG = "GSM"; @@ -111,6 +112,12 @@ final class GsmSMSDispatcher extends SMSDispatcher { return Intents.RESULT_SMS_HANDLED; } + if (!mStorageAvailable && (sms.getMessageClass() != MessageClass.CLASS_0)) { + // It's a storable message and there's no storage available. Bail. + // (See TS 23.038 for a description of class 0 messages.) + return Intents.RESULT_SMS_OUT_OF_MEMORY; + } + SmsHeader smsHeader = sms.getUserDataHeader(); // See if message is partial or port addressed. if ((smsHeader == null) || (smsHeader.concatRef == null)) { diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java index 2eecef8304f2..b98071028c69 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java @@ -16,6 +16,7 @@ package com.android.dumprendertree; +import com.android.dumprendertree.TestShellActivity.DumpDataType; import com.android.dumprendertree.forwarder.AdbUtils; import com.android.dumprendertree.forwarder.ForwardServer; @@ -313,6 +314,7 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh } public void timedOut(String url) { + Log.v(LOGTAG, "layout timeout: " + url); } }); @@ -398,7 +400,8 @@ public class LayoutTestsAutoTest extends ActivityInstrumentationTestCase2<TestSh if (resume) resumeTestList(); - TestShellActivity activity = (TestShellActivity) getActivity(); + TestShellActivity activity = getActivity(); + activity.setDefaultDumpDataType(DumpDataType.DUMP_AS_TEXT); // Run tests. int addr = -1; |