Merge change 23461 into eclair
* changes:
Mimetypes in ContactsProvider2 shouldn't overlap with those in ContactsProvider
diff --git a/api/current.xml b/api/current.xml
index 3e616a4..46dfd89 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"
@@ -167386,6 +167501,171 @@
<parameter name="url" type="java.lang.String">
</parameter>
</method>
+<field name="ERROR_AUTHENTICATION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_BAD_URL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-12"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_CONNECT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-6"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_FAILED_SSL_HANDSHAKE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-11"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_FILE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-13"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_FILE_NOT_FOUND"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-14"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_HOST_LOOKUP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_IO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_PROXY_AUTHENTICATION"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-5"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_REDIRECT_LOOP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-9"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_TIMEOUT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_TOO_MANY_REQUESTS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-15"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_UNKNOWN"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_UNSUPPORTED_AUTH_SCHEME"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ERROR_UNSUPPORTED_SCHEME"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="-10"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="WebViewDatabase"
extends="java.lang.Object"
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index fd9e708..7adaf57 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -546,6 +546,9 @@
case PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE:
s = "INSTALL_FAILED_CPU_ABI_INCOMPATIBLE";
break;
+ case PackageManager.INSTALL_FAILED_MISSING_FEATURE:
+ s = "INSTALL_FAILED_MISSING_FEATURE";
+ break;
case PackageManager.INSTALL_PARSE_FAILED_NOT_APK:
s = "INSTALL_PARSE_FAILED_NOT_APK";
break;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 07520c9d..ad06fa9 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -289,6 +289,11 @@
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 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 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 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 @@
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 @@
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 d14ec15..1bb21b9 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -29,6 +29,7 @@
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 @@
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 @@
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 1e915b4..b4e57e0 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1546,6 +1546,10 @@
}
}
+ 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 ad64465..15bf9ed 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -26,6 +26,7 @@
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 @@
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 @@
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 c3e7224..64daea9 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -30,6 +30,7 @@
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 void closeSystemDialogs(String reason) throws RemoteException;
+ public void getProcessMemoryInfo(int pid, Debug.MemoryInfo outInfo)
+ throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -428,4 +432,5 @@
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 6faaa34..da9a957 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -25,6 +25,7 @@
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 @@
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 @@
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/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index d17775e..1edcb0a 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -111,8 +111,7 @@
if (mSyncThread != null
&& mSyncThread.mSyncContext.getISyncContext().asBinder()
== syncContext.asBinder()) {
- // TODO: figure out why canceling causes a hang
-// mSyncThread.interrupt();
+ mSyncThread.interrupt();
}
}
}
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 5d7af69d..57bf3f7 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -62,53 +62,53 @@
*/
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 @@
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 @@
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 @@
/** 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 @@
unlock();
}
}
-
+
void removeSQLiteClosable(SQLiteClosable closable) {
lock();
try {
@@ -233,8 +235,8 @@
} finally {
unlock();
}
- }
-
+ }
+
@Override
protected void onAllReferencesReleased() {
if (isOpen()) {
@@ -245,10 +247,10 @@
/**
* 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 @@
* 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 @@
/**
* Releases the database lock. This is a no-op if mLockingEnabled is false.
- *
+ *
* @see #unlock()
*/
/* package */ void unlock() {
@@ -350,7 +352,7 @@
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 @@
}
}
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 @@
if (program != null) {
program.onAllReferencesReleasedFromContainer();
}
- }
+ }
}
-
+
/**
* Native call to close the database.
*/
@@ -1157,8 +1170,8 @@
/**
* 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 @@
* @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 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 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 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 @@
* @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 @@
sql.append(algorithm.value());
sql.append(" ");
}
-
+
sql.append(table);
sql.append(" SET ");
@@ -1601,7 +1614,7 @@
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 b0fc78e..5352cf6 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -104,7 +104,7 @@
* 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 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 @@
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/pim/vcard/ContactStruct.java b/core/java/android/pim/vcard/ContactStruct.java
index 8e8d46a..0064bf2 100644
--- a/core/java/android/pim/vcard/ContactStruct.java
+++ b/core/java/android/pim/vcard/ContactStruct.java
@@ -773,11 +773,7 @@
} else if (typeString.equals(Constants.ATTR_TYPE_WORK)) {
type = Email.TYPE_WORK;
} else if (typeString.equals(Constants.ATTR_TYPE_CELL)) {
- // We do not have TYPE_MOBILE yet.
- // TODO: modify this code when TYPE_MOBILE is supported.
- type = Email.TYPE_CUSTOM;
- label =
- android.provider.Contacts.ContactMethodsColumns.MOBILE_EMAIL_TYPE_NAME;
+ type = Email.TYPE_MOBILE;
} else {
if (typeString.startsWith("X-") && type < 0) {
typeString = typeString.substring(2);
diff --git a/core/java/android/pim/vcard/VCardComposer.java b/core/java/android/pim/vcard/VCardComposer.java
index 283d00b..5a09c64f 100644
--- a/core/java/android/pim/vcard/VCardComposer.java
+++ b/core/java/android/pim/vcard/VCardComposer.java
@@ -967,6 +967,9 @@
if (contentValuesList != null) {
for (ContentValues contentValues : contentValuesList) {
byte[] data = contentValues.getAsByteArray(Photo.PHOTO);
+ if (data == null) {
+ continue;
+ }
final String photoType;
// Use some heuristics for guessing the format of the image.
// TODO: there should be some general API for detecting the file format.
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 975c2ff..79a7cf8 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -283,10 +283,12 @@
String value = null;
int len = Integer.valueOf(propValues[1]);
if (len > 0) {
- value = "";
+ StringBuilder str = new StringBuilder();
for (int i = 2; i < propValues.length; i++) {
- value = value + propValues[i] + ',';
+ str.append(propValues[i]);
+ str.append(",");
}
+ value = str.toString();
}
mBluetoothService.setProperty(name, value);
} else if (name.equals("Powered")) {
@@ -331,10 +333,12 @@
String uuid = null;
int len = Integer.valueOf(propValues[1]);
if (len > 0) {
- uuid = "";
+ StringBuilder str = new StringBuilder();
for (int i = 2; i < propValues.length; i++) {
- uuid = uuid + propValues[i] + ",";
+ str.append(propValues[i]);
+ str.append(",");
}
+ uuid = str.toString();
}
mBluetoothService.setRemoteDeviceProperty(address, name, uuid);
} else if (name.equals("Paired")) {
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 413f6a8..21104c8 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -551,20 +551,21 @@
for (int i = 0; i < properties.length; i++) {
String name = properties[i];
- String newValue;
+ String newValue = null;
int len;
if (name == null) {
Log.e(TAG, "Error:Adapter Property at index" + i + "is null");
continue;
}
if (name.equals("Devices")) {
+ StringBuilder str = new StringBuilder();
len = Integer.valueOf(properties[++i]);
- if (len != 0)
- newValue = "";
- else
- newValue = null;
for (int j = 0; j < len; j++) {
- newValue += properties[++i] + ",";
+ str.append(properties[++i]);
+ str.append(",");
+ }
+ if (len > 0) {
+ newValue = str.toString();
}
} else {
newValue = properties[++i];
@@ -837,32 +838,32 @@
* We get a DeviceFound signal every time RSSI changes or name changes.
* Don't create a new Map object every time */
Map<String, String> propertyValues = mDeviceProperties.get(address);
- if (propertyValues != null) {
- propertyValues.clear();
- } else {
+ if (propertyValues == null) {
propertyValues = new HashMap<String, String>();
}
for (int i = 0; i < properties.length; i++) {
String name = properties[i];
- String newValue;
+ String newValue = null;
int len;
if (name == null) {
Log.e(TAG, "Error: Remote Device Property at index" + i + "is null");
continue;
}
if (name.equals("UUIDs") || name.equals("Nodes")) {
+ StringBuilder str = new StringBuilder();
len = Integer.valueOf(properties[++i]);
- if (len != 0)
- newValue = "";
- else
- newValue = null;
for (int j = 0; j < len; j++) {
- newValue += properties[++i] + ",";
+ str.append(properties[++i]);
+ str.append(",");
+ }
+ if (len > 0) {
+ newValue = str.toString();
}
} else {
newValue = properties[++i];
}
+
propertyValues.put(name, newValue);
}
mDeviceProperties.put(address, propertyValues);
diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java
index 29dc2ea52..a92800d 100644
--- a/core/java/android/text/Layout.java
+++ b/core/java/android/text/Layout.java
@@ -1527,7 +1527,7 @@
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/view/View.java b/core/java/android/view/View.java
index 425ccab..d569220 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -46,7 +46,6 @@
import android.os.SystemProperties;
import android.util.AttributeSet;
import android.util.Config;
-import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
import android.util.Pool;
diff --git a/core/java/android/webkit/ContentLoader.java b/core/java/android/webkit/ContentLoader.java
index 27cd6b5..19aa087 100644
--- a/core/java/android/webkit/ContentLoader.java
+++ b/core/java/android/webkit/ContentLoader.java
@@ -57,6 +57,16 @@
}
+ 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 @@
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 54a4c1d..085f1f4 100644
--- a/core/java/android/webkit/FileLoader.java
+++ b/core/java/android/webkit/FileLoader.java
@@ -72,6 +72,15 @@
}
}
+ 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 @@
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/GoogleLocationSettingManager.java b/core/java/android/webkit/GoogleLocationSettingManager.java
similarity index 100%
rename from core/java/android/GoogleLocationSettingManager.java
rename to core/java/android/webkit/GoogleLocationSettingManager.java
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 43c76a8..1a5b2eb 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -606,6 +606,7 @@
// before calling it.
if (mCacheLoader != null) {
mCacheLoader.load();
+ mFromCache = true;
if (DebugFlags.LOAD_LISTENER) {
Log.v(LOGTAG, "LoadListener cache load url=" + url());
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index e39e3f1..792fdf2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -342,6 +342,9 @@
*/
VelocityTracker mVelocityTracker;
private int mMaximumFling;
+ private float mLastVelocity;
+ private float mLastVelX;
+ private float mLastVelY;
// use this flag to control whether enabling the new double tap zoom
static final boolean ENABLE_DOUBLETAP_ZOOM = true;
@@ -1795,6 +1798,13 @@
, contentToView(x.right), contentToView(x.bottom));
}
+ // stop the scroll animation, and don't let a subsequent fling add
+ // to the existing velocity
+ private void abortAnimation() {
+ mScroller.abortAnimation();
+ mLastVelocity = 0;
+ }
+
/* call from webcoreview.draw(), so we're still executing in the UI thread
*/
private void recordNewContentSize(int w, int h, boolean updateLayout) {
@@ -1819,7 +1829,7 @@
mScrollY = pinLocY(mScrollY);
// android.util.Log.d("skia", "recordNewContentSize -
// abortAnimation");
- mScroller.abortAnimation(); // just in case
+ abortAnimation(); // just in case
if (oldX != mScrollX || oldY != mScrollY) {
sendOurVisibleRect();
}
@@ -2339,7 +2349,7 @@
animationDuration > 0 ? animationDuration : computeDuration(dx, dy));
invalidate();
} else {
- mScroller.abortAnimation(); // just in case
+ abortAnimation(); // just in case
scrollTo(x, y);
}
return true;
@@ -2963,7 +2973,7 @@
mLastTouchX = halfW;
int halfH = height >> 1;
mLastTouchY = halfH;
- mScroller.abortAnimation();
+ abortAnimation();
mZoomScrollStart = System.currentTimeMillis();
Rect zoomFrame = scrollZoomFrame(width, height
, scrollZoomMagScale(mZoomScrollInvLimit));
@@ -3850,6 +3860,9 @@
mLastScrollY = mZoomScrollY;
// If two taps are close, ignore the first tap
} else if (!mScroller.isFinished()) {
+ // stop the current scroll animation, but if this is
+ // the start of a fling, allow it to add to the current
+ // fling's velocity
mScroller.abortAnimation();
mTouchMode = TOUCH_DRAG_START_MODE;
mPrivateHandler.removeMessages(RESUME_WEBCORE_UPDATE);
@@ -4110,6 +4123,7 @@
doFling();
break;
}
+ mLastVelocity = 0;
WebViewCore.resumeUpdate(mWebViewCore);
break;
case TOUCH_DRAG_START_MODE:
@@ -4475,6 +4489,27 @@
vx = vx * 3 / 4;
vy = vy * 3 / 4;
}
+ float currentVelocity = mScroller.getCurrVelocity();
+ if (mLastVelocity > 0 && currentVelocity > 0) {
+ float deltaR = (float) (Math.abs(Math.atan2(mLastVelY, mLastVelX)
+ - Math.atan2(vy, vx)));
+ final float circle = (float) (Math.PI) * 2.0f;
+ if (deltaR > circle * 0.9f || deltaR < circle * 0.1f) {
+ vx += currentVelocity * mLastVelX / mLastVelocity;
+ vy += currentVelocity * mLastVelY / mLastVelocity;
+ if (DebugFlags.WEB_VIEW) {
+ Log.v(LOGTAG, "doFling vx= " + vx + " vy=" + vy);
+ }
+ } else if (DebugFlags.WEB_VIEW) {
+ Log.v(LOGTAG, "doFling missed " + deltaR / circle);
+ }
+ } else if (DebugFlags.WEB_VIEW) {
+ Log.v(LOGTAG, "doFling start last=" + mLastVelocity
+ + " current=" + currentVelocity);
+ }
+ mLastVelX = vx;
+ mLastVelY = vy;
+ mLastVelocity = (float) Math.hypot(vx, vy);
mScroller.fling(mScrollX, mScrollY, -vx, -vy, 0, maxX, 0, maxY);
// TODO: duration is calculated based on velocity, if the range is
@@ -4683,7 +4718,7 @@
mLastTouchY = y + (float) (mWebTextView.getTop() - mScrollY);
mLastTouchTime = eventTime;
if (!mScroller.isFinished()) {
- mScroller.abortAnimation();
+ abortAnimation();
mPrivateHandler.removeMessages(RESUME_WEBCORE_UPDATE);
}
mSnapScrollMode = SNAP_NONE;
diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java
index a185779..30dea74 100644
--- a/core/java/android/webkit/WebViewClient.java
+++ b/core/java/android/webkit/WebViewClient.java
@@ -92,14 +92,46 @@
cancelMsg.sendToTarget();
}
+ // These ints must match up to the hidden values in EventHandler.
+ /** Generic error */
+ public static final int ERROR_UNKNOWN = -1;
+ /** Server or proxy hostname lookup failed */
+ public static final int ERROR_HOST_LOOKUP = -2;
+ /** Unsupported authentication scheme (not basic or digest) */
+ public static final int ERROR_UNSUPPORTED_AUTH_SCHEME = -3;
+ /** User authentication failed on server */
+ public static final int ERROR_AUTHENTICATION = -4;
+ /** User authentication failed on proxy */
+ public static final int ERROR_PROXY_AUTHENTICATION = -5;
+ /** Failed to connect to the server */
+ public static final int ERROR_CONNECT = -6;
+ /** Failed to read or write to the server */
+ public static final int ERROR_IO = -7;
+ /** Connection timed out */
+ public static final int ERROR_TIMEOUT = -8;
+ /** Too many redirects */
+ public static final int ERROR_REDIRECT_LOOP = -9;
+ /** Unsupported URI scheme */
+ public static final int ERROR_UNSUPPORTED_SCHEME = -10;
+ /** Failed to perform SSL handshake */
+ public static final int ERROR_FAILED_SSL_HANDSHAKE = -11;
+ /** Malformed URL */
+ public static final int ERROR_BAD_URL = -12;
+ /** Generic file error */
+ public static final int ERROR_FILE = -13;
+ /** File not found */
+ public static final int ERROR_FILE_NOT_FOUND = -14;
+ /** Too many requests during this load */
+ public static final int ERROR_TOO_MANY_REQUESTS = -15;
+
/**
- * Report an error to an activity. These errors come up from WebCore, and
- * are network errors.
- *
+ * Report an error to the host application. These errors are unrecoverable
+ * (i.e. the main resource is unavailable). The errorCode parameter
+ * corresponds to one of the ERROR_* constants.
* @param view The WebView that is initiating the callback.
- * @param errorCode The HTTP error code.
- * @param description A String description.
- * @param failingUrl The url that failed.
+ * @param errorCode The error code corresponding to an ERROR_* value.
+ * @param description A String describing the error.
+ * @param failingUrl The url that failed to load.
*/
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 67721c9..2f292d5 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1996,7 +1996,10 @@
if (y != mLastY) {
deltaY -= mMotionCorrection;
int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;
- trackMotionScroll(deltaY, incrementalDeltaY);
+ // No need to do all this work if we're not going to move anyway
+ if (incrementalDeltaY != 0) {
+ trackMotionScroll(deltaY, incrementalDeltaY);
+ }
// Check to see if we have bumped into the scroll limit
View motionView = this.getChildAt(mMotionPosition - mFirstPosition);
@@ -2063,7 +2066,7 @@
if (mSelector != null) {
Drawable d = mSelector.getCurrent();
if (d != null && d instanceof TransitionDrawable) {
- ((TransitionDrawable)d).resetTransition();
+ ((TransitionDrawable) d).resetTransition();
}
}
postDelayed(new Runnable() {
@@ -2087,15 +2090,27 @@
mTouchMode = TOUCH_MODE_REST;
break;
case TOUCH_MODE_SCROLL:
- final VelocityTracker velocityTracker = mVelocityTracker;
- velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
- final int initialVelocity = (int) velocityTracker.getYVelocity();
- if (Math.abs(initialVelocity) > mMinimumVelocity && (getChildCount() > 0)) {
- if (mFlingRunnable == null) {
- mFlingRunnable = new FlingRunnable();
+ final int childCount = getChildCount();
+ if (childCount > 0) {
+ if (mFirstPosition == 0 && getChildAt(0).getTop() >= mListPadding.top &&
+ mFirstPosition + childCount < mItemCount &&
+ getChildAt(childCount - 1).getBottom() <=
+ getHeight() - mListPadding.bottom) {
+ mTouchMode = TOUCH_MODE_REST;
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
+ } else {
+ final VelocityTracker velocityTracker = mVelocityTracker;
+ velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+ final int initialVelocity = (int) velocityTracker.getYVelocity();
+
+ if (Math.abs(initialVelocity) > mMinimumVelocity) {
+ if (mFlingRunnable == null) {
+ mFlingRunnable = new FlingRunnable();
+ }
+ reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
+ mFlingRunnable.start(-initialVelocity);
+ }
}
- reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
- mFlingRunnable.start(-initialVelocity);
} else {
mTouchMode = TOUCH_MODE_REST;
reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 993b7cb..6316864 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1328,19 +1328,23 @@
// Make sure we are 1) Too low, and 2) Either there are more rows below the
// last row or the last row is scrolled off the bottom of the drawable area
- if (topOffset > 0 && (lastPosition < mItemCount - 1 || lastBottom > end)) {
- if (lastPosition == mItemCount - 1 ) {
- // Don't pull the bottom too far up
- topOffset = Math.min(topOffset, lastBottom - end);
- }
- // Move everything up
- offsetChildrenTopAndBottom(-topOffset);
- if (lastPosition < mItemCount - 1) {
- // Fill the gap that was opened below the last position with more rows, if
- // possible
- fillDown(lastPosition + 1, lastChild.getBottom() + mDividerHeight);
- // Close up the remaining gap
- adjustViewsUpOrDown();
+ if (topOffset > 0) {
+ if (lastPosition < mItemCount - 1 || lastBottom > end) {
+ if (lastPosition == mItemCount - 1) {
+ // Don't pull the bottom too far up
+ topOffset = Math.min(topOffset, lastBottom - end);
+ }
+ // Move everything up
+ offsetChildrenTopAndBottom(-topOffset);
+ if (lastPosition < mItemCount - 1) {
+ // Fill the gap that was opened below the last position with more rows, if
+ // possible
+ fillDown(lastPosition + 1, lastChild.getBottom() + mDividerHeight);
+ // Close up the remaining gap
+ adjustViewsUpOrDown();
+ }
+ } else if (lastPosition == mItemCount - 1) {
+ adjustViewsUpOrDown();
}
}
}
diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java
index b179a13..2f28d9f 100644
--- a/core/java/android/widget/ProgressBar.java
+++ b/core/java/android/widget/ProgressBar.java
@@ -651,6 +651,7 @@
if (mProgress > max) {
mProgress = max;
+ refreshProgress(R.id.progress, mProgress, false);
}
}
}
diff --git a/core/java/android/widget/Scroller.java b/core/java/android/widget/Scroller.java
index 381641f..11dab02 100644
--- a/core/java/android/widget/Scroller.java
+++ b/core/java/android/widget/Scroller.java
@@ -133,6 +133,17 @@
}
/**
+ * @hide
+ * Returns the current velocity.
+ *
+ * @return The original velocity less the deceleration. Result may be
+ * negative.
+ */
+ public float getCurrVelocity() {
+ return mVelocity - mDeceleration * timePassed() / 2000.0f;
+ }
+
+ /**
* Returns the start X offset in the scroll.
*
* @return The start X offset as an absolute distance from the origin.
diff --git a/core/jni/android/opengl/util.cpp b/core/jni/android/opengl/util.cpp
index 41044db..4041346 100644
--- a/core/jni/android/opengl/util.cpp
+++ b/core/jni/android/opengl/util.cpp
@@ -1,16 +1,16 @@
/**
** 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
+ ** 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
+ ** 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
+ ** 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.
*/
@@ -53,18 +53,18 @@
MallocHelper() {
mData = 0;
}
-
+
~MallocHelper() {
if (mData != 0) {
free(mData);
}
}
-
+
void* alloc(size_t size) {
mData = malloc(size);
return mData;
}
-
+
private:
void* mData;
};
@@ -88,17 +88,17 @@
int result = POLY_CLIP_OUT;
float* pTransformed = 0;
int transformedIndexCount = 0;
-
+
if ( indexCount < 3 ) {
return POLY_CLIP_OUT;
}
-
+
// Find out how many vertices we need to transform
// We transform every vertex between the min and max indices, inclusive.
// This is OK for the data sets we expect to use with this function, but
// for other loads it might be better to use a more sophisticated vertex
// cache of some sort.
-
+
int minIndex = 65536;
int maxIndex = -1;
for(int i = 0; i < indexCount; i++) {
@@ -110,18 +110,18 @@
maxIndex = index;
}
}
-
+
if ( maxIndex * 3 > positionsLength) {
return -1;
}
-
+
transformedIndexCount = maxIndex - minIndex + 1;
pTransformed = (float*) mallocHelper.alloc(transformedIndexCount * 4 * sizeof(float));
-
+
if (pTransformed == 0 ) {
return -2;
}
-
+
// Transform the vertices
{
const float* pSrc = pPositions + 3 * minIndex;
@@ -130,9 +130,9 @@
mx4transform(pSrc[0], pSrc[1], pSrc[2], 1.0f, pWS, pDst);
}
}
-
+
// Clip the triangles
-
+
Poly poly;
float* pDest = & poly.vert[0].sx;
for (int i = 0; i < indexCount; i += 3) {
@@ -166,14 +166,14 @@
mEnv->ReleasePrimitiveArrayCritical(mRef, mBase, mReleaseParam);
}
}
-
+
// We seperate the bounds check from the initialization because we want to
// be able to bounds-check multiple arrays, and we can't throw an exception
// after we've called GetPrimitiveArrayCritical.
-
+
// Return true if the bounds check succeeded
// Else instruct the runtime to throw an exception
-
+
bool check() {
if ( ! mRef) {
mEnv->ThrowNew(gIAEClass, "array == null");
@@ -190,9 +190,9 @@
}
return true;
}
-
+
// Bind the array.
-
+
void bind() {
mBase = (T*) mEnv->GetPrimitiveArrayCritical(mRef, (jboolean *) 0);
mData = mBase + mOffset;
@@ -201,10 +201,10 @@
void commitChanges() {
mReleaseParam = 0;
}
-
+
T* mData;
int mLength;
-
+
private:
T* mBase;
JNIEnv* mEnv;
@@ -226,29 +226,29 @@
inline float distance(float x, float y, float z) {
return sqrtf(distance2(x, y, z));
}
-
+
static
void util_computeBoundingSphere(JNIEnv *env, jclass clazz,
jfloatArray positions_ref, jint positionsOffset, jint positionsCount,
jfloatArray sphere_ref, jint sphereOffset) {
FloatArrayHelper positions(env, positions_ref, positionsOffset, 0);
FloatArrayHelper sphere(env, sphere_ref, sphereOffset, 4);
-
+
bool checkOK = positions.check() && sphere.check();
if (! checkOK) {
return;
}
-
+
positions.bind();
sphere.bind();
-
+
if ( positionsCount < 1 ) {
env->ThrowNew(gIAEClass, "positionsCount < 1");
return;
}
-
+
const float* pSrc = positions.mData;
-
+
// find bounding box
float x0 = *pSrc++;
float x1 = x0;
@@ -256,7 +256,7 @@
float y1 = y0;
float z0 = *pSrc++;
float z1 = z0;
-
+
for(int i = 1; i < positionsCount; i++) {
{
float x = *pSrc++;
@@ -286,7 +286,7 @@
}
}
}
-
+
// Because we know our input meshes fit pretty well into bounding boxes,
// just take the diagonal of the box as defining our sphere.
float* pSphere = sphere.mData;
@@ -297,7 +297,7 @@
*pSphere++ = y0 + dy * 0.5f;
*pSphere++ = z0 + dz * 0.5f;
*pSphere++ = distance(dx, dy, dz) * 0.5f;
-
+
sphere.commitChanges();
}
@@ -344,7 +344,7 @@
normalizePlane(f);
f+= 4;
- // left
+ // left
f[0] = m3 + m[0];
f[1] = m7 + m[4];
f[2] = m11 + m[8];
@@ -396,20 +396,20 @@
FloatArrayHelper mvp(env, mvp_ref, mvpOffset, 16);
FloatArrayHelper spheres(env, spheres_ref, spheresOffset, spheresCount * 4);
IntArrayHelper results(env, results_ref, resultsOffset, resultsCapacity);
-
+
bool initializedOK = mvp.check() && spheres.check() && results.check();
if (! initializedOK) {
return -1;
}
-
+
mvp.bind();
spheres.bind();
results.bind();
-
+
computeFrustum(mvp.mData, frustum);
-
+
// Cull the spheres
-
+
pSphere = spheres.mData;
pResults = results.mData;
outputCount = 0;
@@ -436,27 +436,27 @@
jfloatArray ws_ref, jint wsOffset,
jfloatArray positions_ref, jint positionsOffset,
jcharArray indices_ref, jint indicesOffset, jint indexCount) {
-
+
FloatArrayHelper ws(env, ws_ref, wsOffset, 16);
FloatArrayHelper positions(env, positions_ref, positionsOffset, 0);
UnsignedShortArrayHelper indices(env, indices_ref, indicesOffset, 0);
-
+
bool checkOK = ws.check() && positions.check() && indices.check();
if (! checkOK) {
// Return value will be ignored, because an exception has been thrown.
return -1;
}
-
+
if (indices.mLength < indexCount) {
env->ThrowNew(gIAEClass, "length < offset + indexCount");
// Return value will be ignored, because an exception has been thrown.
return -1;
}
-
+
ws.bind();
positions.bind();
indices.bind();
-
+
return visibilityTest(ws.mData,
positions.mData, positions.mLength,
indices.mData, indexCount);
@@ -496,19 +496,19 @@
FloatArrayHelper resultMat(env, result_ref, resultOffset, 16);
FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 16);
-
+
bool checkOK = resultMat.check() && lhs.check() && rhs.check();
-
+
if ( !checkOK ) {
return;
}
-
+
resultMat.bind();
lhs.bind();
rhs.bind();
-
+
multiplyMM(resultMat.mData, lhs.mData, rhs.mData);
-
+
resultMat.commitChanges();
}
@@ -527,19 +527,19 @@
FloatArrayHelper resultV(env, result_ref, resultOffset, 4);
FloatArrayHelper lhs(env, lhs_ref, lhsOffset, 16);
FloatArrayHelper rhs(env, rhs_ref, rhsOffset, 4);
-
+
bool checkOK = resultV.check() && lhs.check() && rhs.check();
-
+
if ( !checkOK ) {
return;
}
-
+
resultV.bind();
lhs.bind();
rhs.bind();
-
+
multiplyMV(resultV.mData, lhs.mData, rhs.mData);
-
+
resultV.commitChanges();
}
@@ -550,7 +550,7 @@
void nativeUtilsClassInit(JNIEnv *env, jclass clazz)
{
jclass bitmapClass = env->FindClass("android/graphics/Bitmap");
- nativeBitmapID = env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
+ nativeBitmapID = env->GetFieldID(bitmapClass, "mNativeBitmap", "I");
}
static int checkFormat(SkBitmap::Config config, int format, int type)
@@ -653,7 +653,7 @@
}
int err = checkFormat(config, internalformat, type);
if (err)
- return err;
+ return err;
bitmap.lockPixels();
const int w = bitmap.width();
const int h = bitmap.height();
@@ -665,14 +665,15 @@
}
const size_t size = bitmap.getSize();
const size_t palette_size = 256*sizeof(SkPMColor);
- void* const data = malloc(size + palette_size);
+ const size_t imageSize = size + palette_size;
+ void* const data = malloc(imageSize);
if (data) {
void* const pixels = (char*)data + palette_size;
SkColorTable* ctable = bitmap.getColorTable();
memcpy(data, ctable->lockColors(), ctable->count() * sizeof(SkPMColor));
memcpy(pixels, p, size);
ctable->unlockColors(false);
- glCompressedTexImage2D(target, level, internalformat, w, h, border, 0, data);
+ glCompressedTexImage2D(target, level, internalformat, w, h, border, imageSize, data);
free(data);
} else {
err = -1;
@@ -700,7 +701,7 @@
}
int err = checkFormat(config, format, type);
if (err)
- return err;
+ return err;
bitmap.lockPixels();
const int w = bitmap.width();
const int h = bitmap.height();
@@ -723,22 +724,22 @@
}
static JNINativeMethod gMatrixMethods[] = {
- { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM },
- { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV },
+ { "multiplyMM", "([FI[FI[FI)V", (void*)util_multiplyMM },
+ { "multiplyMV", "([FI[FI[FI)V", (void*)util_multiplyMV },
};
static JNINativeMethod gVisiblityMethods[] = {
- { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
+ { "computeBoundingSphere", "([FII[FI)V", (void*)util_computeBoundingSphere },
{ "frustumCullSpheres", "([FI[FII[III)I", (void*)util_frustumCullSpheres },
- { "visibilityTest", "([FI[FI[CII)I", (void*)util_visibilityTest },
+ { "visibilityTest", "([FI[FI[CII)I", (void*)util_visibilityTest },
};
static JNINativeMethod gUtilsMethods[] = {
{"nativeClassInit", "()V", (void*)nativeUtilsClassInit },
- { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat },
- { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType },
- { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D },
- { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D },
+ { "native_getInternalFormat", "(Landroid/graphics/Bitmap;)I", (void*) util_getInternalFormat },
+ { "native_getType", "(Landroid/graphics/Bitmap;)I", (void*) util_getType },
+ { "native_texImage2D", "(IIILandroid/graphics/Bitmap;II)I", (void*)util_texImage2D },
+ { "native_texSubImage2D", "(IIIILandroid/graphics/Bitmap;II)I", (void*)util_texSubImage2D },
};
typedef struct _ClassRegistrationInfo {
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp
index 9c4f7c7..0aeaadc 100644
--- a/core/jni/android_bluetooth_BluetoothSocket.cpp
+++ b/core/jni/android_bluetooth_BluetoothSocket.cpp
@@ -54,6 +54,8 @@
static const int TYPE_SCO = 2;
static const int TYPE_L2CAP = 3; // TODO: Test l2cap code paths
+static const int RFCOMM_SO_SNDBUF = 70 * 1024; // 70 KB send buffer
+
static struct asocket *get_socketData(JNIEnv *env, jobject obj) {
struct asocket *s =
(struct asocket *) env->GetIntField(obj, field_mSocketData);
@@ -87,6 +89,7 @@
int fd;
int lm = 0;
+ int sndbuf;
jboolean auth;
jboolean encrypt;
jint type;
@@ -131,7 +134,16 @@
if (lm) {
if (setsockopt(fd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
- LOGV("setsockopt() failed, throwing");
+ LOGV("setsockopt(RFCOMM_LM) failed, throwing");
+ jniThrowIOException(env, errno);
+ return;
+ }
+ }
+
+ if (type == TYPE_RFCOMM) {
+ sndbuf = RFCOMM_SO_SNDBUF;
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
+ LOGV("setsockopt(SO_SNDBUF) failed, throwing");
jniThrowIOException(env, errno);
return;
}
@@ -274,16 +286,21 @@
}
if (bind(s->fd, addr, addr_sz)) {
+ LOGV("...bind(%d) gave errno %d", s->fd, errno);
jniThrowIOException(env, errno);
return;
}
if (listen(s->fd, 1)) {
+ LOGV("...listen(%d) gave errno %d", s->fd, errno);
jniThrowIOException(env, errno);
return;
}
+ LOGV("...bindListenNative(%d) success", s->fd);
+
return;
+
#endif
jniThrowIOException(env, ENOSYS);
}
diff --git a/core/jni/android_emoji_EmojiFactory.cpp b/core/jni/android_emoji_EmojiFactory.cpp
index 7d6e24f..4c213a31 100644
--- a/core/jni/android_emoji_EmojiFactory.cpp
+++ b/core/jni/android_emoji_EmojiFactory.cpp
@@ -197,8 +197,11 @@
static void android_emoji_EmojiFactory_destructor(
JNIEnv* env, jobject obj, jint nativeEmojiFactory) {
+ /*
+ // Must not delete this object!!
EmojiFactory *factory = reinterpret_cast<EmojiFactory *>(nativeEmojiFactory);
delete factory;
+ */
}
static jint android_emoji_EmojiFactory_getAndroidPuaFromVendorSpecificSjis(
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index b4c60f1..3ee404ad 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -200,12 +200,13 @@
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 @@
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 @@
(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
new file mode 100644
index 0000000..58d2dbb
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_connected_1x.png
Binary files differ
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
new file mode 100644
index 0000000..cd1afe9
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_in_1x.png
Binary files differ
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
new file mode 100644
index 0000000..c398d6f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_inandout_1x.png
Binary files differ
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
new file mode 100644
index 0000000..e1eb5b0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_sys_data_out_1x.png
Binary files differ
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
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_connected_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_connected_1x.png
Binary files differ
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
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_in_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_in_1x.png
Binary files differ
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
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_inandout_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_inandout_1x.png
Binary files differ
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
similarity index 100%
rename from core/res/res/drawable/stat_sys_data_out_1x.png
rename to core/res/res/drawable-mdpi/stat_sys_data_out_1x.png
Binary files differ
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index ef1a1ea..a5dadbc 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -375,7 +375,7 @@
</ul>
<ul>
<?cs if:android.whichdoc != "online" ?>
- <li><a href="<?cs var:toroot ?>../samples">
+ <li><a href="<?cs var:toroot ?>../platforms/android-<?cs var:sdk.version ?>/samples">
<span class="en">Sample Code</span>
»</a></li>
<?cs else ?>
diff --git a/docs/html/guide/topics/manifest/uses-feature-element.jd b/docs/html/guide/topics/manifest/uses-feature-element.jd
index 2626735..0248985 100644
--- a/docs/html/guide/topics/manifest/uses-feature-element.jd
+++ b/docs/html/guide/topics/manifest/uses-feature-element.jd
@@ -6,7 +6,8 @@
<dt>syntax:</dt>
<dd>
<pre class="stx">
-<uses-feature android:<a href="#glEsVersion">glEsVersion</a>=["true" | "false"] />
+<uses-feature android:<a href="#glEsVersion">glEsVersion</a>="<em>integer</em>"
+ android:<a href="#name">name</a>="<em>string</em>" />
</pre>
</dd>
@@ -14,7 +15,7 @@
<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code></dd>
<dt>description:</dt>
-<dd>This element specifies specific features used by the application.
+<dd>This element specifies 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
@@ -23,6 +24,11 @@
<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 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>
@@ -38,6 +44,30 @@
</dl>
</dd>
+<dd>
+<dl class="attr"><dt><a name="name"></a>{@code android:name}</dt>
+ <dd>The name of a feature required by the application.
+ The value must be one of the following accepted strings:
+
+ <table>
+ <tr>
+ <th>Value</th>
+ <th>Description</th>
+ </tr><tr>
+ <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>
+ </tr>
+ </table>
+
+ </dd>
+</dl>
+</dd>
+
<!-- ##api level indication## -->
<dt>introduced in:</dt>
<dd>API Level 4</dd>
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 2abb777..f60a7be 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -337,19 +337,26 @@
*/
public static Bitmap decodeResource(Resources res, int id, Options opts) {
Bitmap bm = null;
-
+ InputStream is = null;
+
try {
final TypedValue value = new TypedValue();
- final InputStream is = res.openRawResource(id, value);
+ is = res.openRawResource(id, value);
bm = decodeResourceStream(res, value, is, null, opts);
- is.close();
- } catch (java.io.IOException e) {
+ } catch (Exception e) {
/* do nothing.
If the exception happened on open, bm will be null.
If it happened on close, bm is still valid.
*/
+ } finally {
+ try {
+ if (is != null) is.close();
+ } catch (IOException e) {
+ // Ignore
+ }
}
+
return bm;
}
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 3001c743..536f71c 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -16,19 +16,15 @@
package android.renderscript;
-import java.lang.reflect.Field;
-import java.lang.reflect.Array;
-
import java.io.IOException;
import java.io.InputStream;
import android.content.res.Resources;
+import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.os.Bundle;
-import android.renderscript.Type;
-import android.util.Config;
import android.util.Log;
+import android.util.TypedValue;
/**
* @hide
@@ -52,7 +48,7 @@
}
public void data(int[] d) {
- int size = 0;
+ int size;
if(mType != null && mType.mElement != null) {
size = mType.mElement.mSize;
for(int ct=0; ct < mType.mValues.length; ct++) {
@@ -71,7 +67,7 @@
}
public void data(float[] d) {
- int size = 0;
+ int size;
if(mType != null && mType.mElement != null) {
size = mType.mElement.mSize;
for(int ct=0; ct < mType.mValues.length; ct++) {
@@ -245,8 +241,29 @@
static public Allocation createFromBitmapResource(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
throws IllegalArgumentException {
- Bitmap b = BitmapFactory.decodeResource(res, id, mBitmapOptions);
- return createFromBitmap(rs, b, dstFmt, genMips);
+ InputStream is = null;
+ try {
+ final TypedValue value = new TypedValue();
+ is = res.openRawResource(id, value);
+
+ int asset = ((AssetManager.AssetInputStream) is).getAssetInt();
+ int allocationId = rs.nAllocationCreateFromAssetStream(dstFmt.mPredefinedID, genMips,
+ asset);
+
+ return new Allocation(allocationId, rs, null);
+ } catch (Exception e) {
+ // Ignore
+ } finally {
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+
+ return null;
}
static public Allocation createFromBitmapResourceBoxed(RenderScript rs, Resources res, int id, Element dstFmt, boolean genMips)
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index ee7b702..0f188f6 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -16,13 +16,10 @@
package android.renderscript;
-import java.io.IOException;
-import java.io.InputStream;
import java.lang.reflect.Field;
-import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.renderscript.Type;
+import android.graphics.BitmapFactory;
import android.util.Config;
import android.util.Log;
import android.view.Surface;
@@ -35,6 +32,7 @@
public class RenderScript {
static final String LOG_TAG = "libRS_jni";
private static final boolean DEBUG = false;
+ @SuppressWarnings({"UnusedDeclaration", "deprecation"})
private static final boolean LOG_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
@@ -43,6 +41,7 @@
* We use a class initializer to allow the native code to cache some
* field offsets.
*/
+ @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
private static boolean sInitialized;
native private static void _nInit();
@@ -95,6 +94,7 @@
native int nAllocationCreateSized(int elem, int count);
native int nAllocationCreateFromBitmap(int dstFmt, boolean genMips, Bitmap bmp);
native int nAllocationCreateFromBitmapBoxed(int dstFmt, boolean genMips, Bitmap bmp);
+ native int nAllocationCreateFromAssetStream(int dstFmt, boolean genMips, int assetStream);
native void nAllocationUploadToTexture(int alloc, int baseMioLevel);
native void nAllocationUploadToBufferObject(int alloc);
@@ -188,6 +188,7 @@
private int mDev;
private int mContext;
+ @SuppressWarnings({"FieldCanBeLocal"})
private Surface mSurface;
private static boolean mElementsInitialized = false;
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 2550181..558146d 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -26,7 +26,13 @@
#include <ui/Surface.h>
#include <core/SkBitmap.h>
+#include <core/SkPixelRef.h>
+#include <core/SkStream.h>
+#include <core/SkTemplates.h>
+#include <images/SkImageDecoder.h>
+#include <utils/Asset.h>
+#include <utils/ResourceTypes.h>
#include "jni.h"
#include "JNIHelp.h"
@@ -397,6 +403,32 @@
}
static int
+nAllocationCreateFromAssetStream(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jint native_asset)
+{
+ RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
+
+ Asset* asset = reinterpret_cast<Asset*>(native_asset);
+ SkBitmap bitmap;
+ SkImageDecoder::DecodeMemory(asset->getBuffer(false), asset->getLength(),
+ &bitmap, SkBitmap::kNo_Config, SkImageDecoder::kDecodePixels_Mode);
+
+ SkBitmap::Config config = bitmap.getConfig();
+
+ RsElementPredefined e = SkBitmapToPredefined(config);
+
+ if (e != RS_ELEMENT_USER_U8) {
+ bitmap.lockPixels();
+ const int w = bitmap.width();
+ const int h = bitmap.height();
+ const void* ptr = bitmap.getPixels();
+ jint id = (jint)rsAllocationCreateFromBitmap(con, w, h, (RsElementPredefined)dstFmt, e, genMips, ptr);
+ bitmap.unlockPixels();
+ return id;
+ }
+ return 0;
+}
+
+static int
nAllocationCreateFromBitmapBoxed(JNIEnv *_env, jobject _this, jint dstFmt, jboolean genMips, jobject jbitmap)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
@@ -494,7 +526,7 @@
LOG_API("nAllocationRead_i, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
jint *ptr = _env->GetIntArrayElements(data, NULL);
rsAllocationRead(con, (RsAllocation)alloc, ptr);
- _env->ReleaseIntArrayElements(data, ptr, JNI_COMMIT);
+ _env->ReleaseIntArrayElements(data, ptr, 0);
}
static void
@@ -505,7 +537,7 @@
LOG_API("nAllocationRead_f, con(%p), alloc(%p), len(%i)", con, (RsAllocation)alloc, len);
jfloat *ptr = _env->GetFloatArrayElements(data, NULL);
rsAllocationRead(con, (RsAllocation)alloc, ptr);
- _env->ReleaseFloatArrayElements(data, ptr, JNI_COMMIT);
+ _env->ReleaseFloatArrayElements(data, ptr, 0);
}
@@ -1239,6 +1271,7 @@
{"nAllocationCreateSized", "(II)I", (void*)nAllocationCreateSized },
{"nAllocationCreateFromBitmap", "(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmap },
{"nAllocationCreateFromBitmapBoxed","(IZLandroid/graphics/Bitmap;)I", (void*)nAllocationCreateFromBitmapBoxed },
+{"nAllocationCreateFromAssetStream","(IZI)I", (void*)nAllocationCreateFromAssetStream },
{"nAllocationUploadToTexture", "(II)V", (void*)nAllocationUploadToTexture },
{"nAllocationUploadToBufferObject","(I)V", (void*)nAllocationUploadToBufferObject },
{"nAllocationData", "(I[II)V", (void*)nAllocationData_i },
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index 3a419b5..ef71641 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -1449,6 +1449,8 @@
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 @@
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/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 8326361..94ced22 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -105,9 +105,6 @@
*/
public static final String KEY_LOCATION_CHANGED = "location";
- /** @hide */
- public static final String SYSTEM_DIR = "/data/system/location";
-
// Map from LocationListeners to their associated ListenerTransport objects
private HashMap<LocationListener,ListenerTransport> mListeners =
new HashMap<LocationListener,ListenerTransport>();
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index d578c81..aba40b3 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -340,6 +340,7 @@
ParsePosition pos = new ParsePosition(0);
try {
Date date = sFormatter.parse(dateTimeString, pos);
+ if (date == null) return -1;
return date.getTime();
} catch (IllegalArgumentException ex) {
return -1;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index eaad4fc..3a065ae 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1321,6 +1321,10 @@
return;
}
+ // We're going to temporarily give up the lock while reading data
+ // from the source. A certain client unfortunately chose to have the
+ // thread supplying input data and reading output data be the same...
+
MediaBuffer *srcBuffer;
status_t err;
if (mSeekTimeUs >= 0) {
@@ -1328,10 +1332,13 @@
options.setSeekTo(mSeekTimeUs);
mSeekTimeUs = -1;
+ mLock.unlock();
err = mSource->read(&srcBuffer, &options);
} else {
+ mLock.unlock();
err = mSource->read(&srcBuffer);
}
+ mLock.lock();
OMX_U32 flags = OMX_BUFFERFLAG_ENDOFFRAME;
OMX_TICKS timestamp = 0;
diff --git a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsBroadcastReceiver.java b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsBroadcastReceiver.java
index 3513215..ea14307 100644
--- a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsBroadcastReceiver.java
+++ b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsBroadcastReceiver.java
@@ -16,6 +16,7 @@
package com.android.providers.subscribedfeeds;
+import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -35,7 +36,10 @@
public void onReceive(Context context, Intent intent) {
if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Received intent " + intent);
- intent.setClass(context, SubscribedFeedsIntentService.class);
+ if (intent.getAction().equals(Intent.ACTION_REMOTE_INTENT)) {
+ setResultCode(Activity.RESULT_OK);
+ }
+ intent.setClass(context, SubscribedFeedsIntentService.class);
context.startService(intent);
}
}
diff --git a/packages/TtsService/jni/android_tts_SynthProxy.cpp b/packages/TtsService/jni/android_tts_SynthProxy.cpp
index 1793587..071a90d 100644
--- a/packages/TtsService/jni/android_tts_SynthProxy.cpp
+++ b/packages/TtsService/jni/android_tts_SynthProxy.cpp
@@ -721,6 +721,27 @@
}
+static int
+android_tts_SynthProxy_stopSync(JNIEnv *env, jobject thiz, jint jniData)
+{
+ int result = TTS_FAILURE;
+
+ if (jniData == 0) {
+ LOGE("android_tts_SynthProxy_stop(): invalid JNI data");
+ return result;
+ }
+
+ // perform a regular stop
+ result = android_tts_SynthProxy_stop(env, thiz, jniData);
+ // but wait on the engine having released the engine mutex which protects
+ // the synthesizer resources.
+ engineMutex.lock();
+ engineMutex.unlock();
+
+ return result;
+}
+
+
static jobjectArray
android_tts_SynthProxy_getLanguage(JNIEnv *env, jobject thiz, jint jniData)
{
@@ -778,6 +799,10 @@
"(I)I",
(void*)android_tts_SynthProxy_stop
},
+ { "native_stopSync",
+ "(I)I",
+ (void*)android_tts_SynthProxy_stopSync
+ },
{ "native_speak",
"(ILjava/lang/String;I)I",
(void*)android_tts_SynthProxy_speak
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index a0814aa..1d37ba0 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -40,7 +40,7 @@
* Constructor; pass the location of the native TTS .so to use.
*/
public SynthProxy(String nativeSoLib) {
- Log.e("TTS is loading", nativeSoLib);
+ Log.v(TtsService.SERVICE_TAG, "TTS is loading " + nativeSoLib);
native_setup(new WeakReference<SynthProxy>(this), nativeSoLib);
}
@@ -52,6 +52,18 @@
}
/**
+ * Synchronous stop of the synthesizer. This method returns when the synth
+ * has completed the stop procedure and doesn't use any of the resources it
+ * was using while synthesizing.
+ *
+ * @return {@link android.speech.tts.TextToSpeech.SUCCESS} or
+ * {@link android.speech.tts.TextToSpeech.ERROR}
+ */
+ public int stopSync() {
+ return native_stopSync(mJniData);
+ }
+
+ /**
* Synthesize speech and speak it directly using AudioTrack.
*/
public int speak(String text, int streamType) {
@@ -156,6 +168,8 @@
private native final int native_stop(int jniData);
+ private native final int native_stopSync(int jniData);
+
private native final int native_speak(int jniData, String text, int streamType);
private native final int native_synthesizeToFile(int jniData, String text, String filename);
diff --git a/packages/TtsService/src/android/tts/TtsService.java b/packages/TtsService/src/android/tts/TtsService.java
index 2e11698..217d3bb 100755
--- a/packages/TtsService/src/android/tts/TtsService.java
+++ b/packages/TtsService/src/android/tts/TtsService.java
@@ -122,6 +122,7 @@
private static final String ACTION = "android.intent.action.START_TTS_SERVICE";
private static final String CATEGORY = "android.intent.category.TTS";
private static final String PKGNAME = "android.tts";
+ protected static final String SERVICE_TAG = "TtsService";
private final RemoteCallbackList<ITtsCallback> mCallbacks
= new RemoteCallbackList<ITtsCallback>();
@@ -188,6 +189,8 @@
// Unregister all callbacks.
mCallbacks.kill();
+
+ Log.v(SERVICE_TAG, "onDestroy() completed");
}
@@ -300,7 +303,7 @@
private int setLanguage(String callingApp, String lang, String country, String variant) {
- Log.v("TtsService", "TtsService.setLanguage(" + lang + ", " + country + ", " + variant + ")");
+ Log.v(SERVICE_TAG, "TtsService.setLanguage(" + lang + ", " + country + ", " + variant + ")");
int res = TextToSpeech.ERROR;
try {
if (isDefaultEnforced()) {
@@ -384,7 +387,7 @@
* engines.
*/
private int speak(String callingApp, String text, int queueMode, ArrayList<String> params) {
- Log.v("TtsService", "TTS service received " + text);
+ Log.v(SERVICE_TAG, "TTS service received " + text);
if (queueMode == TextToSpeech.QUEUE_FLUSH) {
stop(callingApp);
} else if (queueMode == 2) {
@@ -433,7 +436,7 @@
speechQueueAvailable =
speechQueueLock.tryLock(SPEECHQUEUELOCK_TIMEOUT, TimeUnit.MILLISECONDS);
if (speechQueueAvailable) {
- Log.i("TtsService", "Stopping");
+ Log.i(SERVICE_TAG, "Stopping");
for (int i = mSpeechQueue.size() - 1; i > -1; i--){
if (mSpeechQueue.get(i).mCallingApp.equals(callingApp)){
mSpeechQueue.remove(i);
@@ -460,13 +463,13 @@
} else {
result = TextToSpeech.SUCCESS;
}
- Log.i("TtsService", "Stopped");
+ Log.i(SERVICE_TAG, "Stopped");
} else {
- Log.e("TtsService", "TTS stop(): queue locked longer than expected");
+ Log.e(SERVICE_TAG, "TTS stop(): queue locked longer than expected");
result = TextToSpeech.ERROR;
}
} catch (InterruptedException e) {
- Log.e("TtsService", "TTS stop: tryLock interrupted");
+ Log.e(SERVICE_TAG, "TTS stop: tryLock interrupted");
e.printStackTrace();
} finally {
// This check is needed because finally will always run; even if the
@@ -497,22 +500,21 @@
// clear the current speech item
if (mCurrentSpeechItem != null) {
- result = sNativeSynth.stop();
+ result = sNativeSynth.stopSync();
mKillList.put(mCurrentSpeechItem, true);
mIsSpeaking = false;
// was the engine writing to a file?
if (mCurrentSpeechItem.mType == SpeechItem.TEXT_TO_FILE) {
// delete the file that was being written
- // TODO make sure the synth is not writing to the file anymore
if (mCurrentSpeechItem.mFilename != null) {
File tempFile = new File(mCurrentSpeechItem.mFilename);
- Log.v("TtsService", "Leaving behind " + mCurrentSpeechItem.mFilename);
+ Log.v(SERVICE_TAG, "Leaving behind " + mCurrentSpeechItem.mFilename);
if (tempFile.exists()) {
- Log.v("TtsService", "About to delete "
+ Log.v(SERVICE_TAG, "About to delete "
+ mCurrentSpeechItem.mFilename);
if (tempFile.delete()) {
- Log.v("TtsService", "file successfully deleted");
+ Log.v(SERVICE_TAG, "file successfully deleted");
}
}
}
@@ -521,11 +523,11 @@
mCurrentSpeechItem = null;
}
} else {
- Log.e("TtsService", "TTS killAllUtterances(): queue locked longer than expected");
+ Log.e(SERVICE_TAG, "TTS killAllUtterances(): queue locked longer than expected");
result = TextToSpeech.ERROR;
}
} catch (InterruptedException e) {
- Log.e("TtsService", "TTS killAllUtterances(): tryLock interrupted");
+ Log.e(SERVICE_TAG, "TTS killAllUtterances(): tryLock interrupted");
result = TextToSpeech.ERROR;
} finally {
// This check is needed because finally will always run, even if the
@@ -576,13 +578,13 @@
} else {
result = TextToSpeech.SUCCESS;
}
- Log.i("TtsService", "Stopped all");
+ Log.i(SERVICE_TAG, "Stopped all");
} else {
- Log.e("TtsService", "TTS stopAll(): queue locked longer than expected");
+ Log.e(SERVICE_TAG, "TTS stopAll(): queue locked longer than expected");
result = TextToSpeech.ERROR;
}
} catch (InterruptedException e) {
- Log.e("TtsService", "TTS stopAll: tryLock interrupted");
+ Log.e(SERVICE_TAG, "TTS stopAll: tryLock interrupted");
e.printStackTrace();
} finally {
// This check is needed because finally will always run; even if the
@@ -709,11 +711,11 @@
sNativeSynth.speak(speechItem.mText, streamType);
} catch (NullPointerException e) {
// synth will become null during onDestroy()
- Log.v("TtsService", " null synth, can't speak");
+ Log.v(SERVICE_TAG, " null synth, can't speak");
}
}
} catch (InterruptedException e) {
- Log.e("TtsService", "TTS speakInternalOnly(): tryLock interrupted");
+ Log.e(SERVICE_TAG, "TTS speakInternalOnly(): tryLock interrupted");
e.printStackTrace();
} finally {
// This check is needed because finally will always run;
@@ -739,7 +741,7 @@
public void run() {
boolean synthAvailable = false;
String utteranceId = "";
- Log.i("TtsService", "Synthesizing to " + speechItem.mFilename);
+ Log.i(SERVICE_TAG, "Synthesizing to " + speechItem.mFilename);
try {
synthAvailable = synthesizerLock.tryLock();
if (!synthAvailable) {
@@ -783,11 +785,11 @@
sNativeSynth.synthesizeToFile(speechItem.mText, speechItem.mFilename);
} catch (NullPointerException e) {
// synth will become null during onDestroy()
- Log.v("TtsService", " null synth, can't synthesize to file");
+ Log.v(SERVICE_TAG, " null synth, can't synthesize to file");
}
}
} catch (InterruptedException e) {
- Log.e("TtsService", "TTS synthToFileInternalOnly(): tryLock interrupted");
+ Log.e(SERVICE_TAG, "TTS synthToFileInternalOnly(): tryLock interrupted");
e.printStackTrace();
} finally {
// This check is needed because finally will always run;
@@ -832,7 +834,7 @@
if (cb == null){
return;
}
- Log.v("TtsService", "TTS callback: dispatch started");
+ Log.v(SERVICE_TAG, "TTS callback: dispatch started");
// Broadcast to all clients the new value.
final int N = mCallbacks.beginBroadcast();
try {
@@ -842,7 +844,7 @@
// the dead object for us.
}
mCallbacks.finishBroadcast();
- Log.v("TtsService", "TTS callback: dispatch completed to " + N);
+ Log.v(SERVICE_TAG, "TTS callback: dispatch completed to " + N);
}
private SpeechItem splitCurrentTextIfNeeded(SpeechItem currentSpeechItem){
@@ -879,11 +881,12 @@
speechQueueAvailable =
speechQueueLock.tryLock(SPEECHQUEUELOCK_TIMEOUT, TimeUnit.MILLISECONDS);
if (!speechQueueAvailable) {
- Log.e("TtsService", "processSpeechQueue - Speech queue is unavailable.");
+ Log.e(SERVICE_TAG, "processSpeechQueue - Speech queue is unavailable.");
return;
}
if (mSpeechQueue.size() < 1) {
mIsSpeaking = false;
+ mKillList.clear();
broadcastTtsQueueProcessingCompleted();
return;
}
@@ -893,7 +896,7 @@
SoundResource sr = getSoundResource(mCurrentSpeechItem);
// Synth speech as needed - synthesizer should call
// processSpeechQueue to continue running the queue
- Log.v("TtsService", "TTS processing: " + mCurrentSpeechItem.mText);
+ Log.v(SERVICE_TAG, "TTS processing: " + mCurrentSpeechItem.mText);
if (sr == null) {
if (mCurrentSpeechItem.mType == SpeechItem.TEXT) {
mCurrentSpeechItem = splitCurrentTextIfNeeded(mCurrentSpeechItem);
@@ -949,7 +952,7 @@
mSpeechQueue.remove(0);
}
} catch (InterruptedException e) {
- Log.e("TtsService", "TTS processSpeechQueue: tryLock interrupted");
+ Log.e(SERVICE_TAG, "TTS processSpeechQueue: tryLock interrupted");
e.printStackTrace();
} finally {
// This check is needed because finally will always run; even if the
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 7c33e37..af60556 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -16,12 +16,7 @@
package com.android.server;
-import java.io.BufferedReader;
-import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
@@ -31,7 +26,6 @@
import java.util.Observable;
import java.util.Observer;
import java.util.Set;
-import java.util.regex.Pattern;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -64,7 +58,6 @@
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
-import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.util.PrintWriterPrinter;
@@ -84,17 +77,9 @@
private static final String TAG = "LocationManagerService";
private static final boolean LOCAL_LOGV = false;
- // Minimum time interval between last known location writes, in milliseconds.
- private static final long MIN_LAST_KNOWN_LOCATION_TIME = 60L * 1000L;
-
- // Max time to hold wake lock for, in milliseconds.
- private static final long MAX_TIME_FOR_WAKE_LOCK = 60 * 1000L;
-
// The last time a location was written, by provider name.
private HashMap<String,Long> mLastWriteTime = new HashMap<String,Long>();
- private static final Pattern PATTERN_COMMA = Pattern.compile(",");
-
private static final String ACCESS_FINE_LOCATION =
android.Manifest.permission.ACCESS_FINE_LOCATION;
private static final String ACCESS_COARSE_LOCATION =
@@ -416,97 +401,6 @@
}
}
- private Location readLastKnownLocationLocked(String provider) {
- Location location = null;
- String s = null;
- try {
- File f = new File(LocationManager.SYSTEM_DIR + "/location."
- + provider);
- if (!f.exists()) {
- return null;
- }
- BufferedReader reader = new BufferedReader(new FileReader(f), 256);
- s = reader.readLine();
- } catch (IOException e) {
- Log.w(TAG, "Unable to read last known location", e);
- }
-
- if (s == null) {
- return null;
- }
- try {
- String[] tokens = PATTERN_COMMA.split(s);
- int idx = 0;
- long time = Long.parseLong(tokens[idx++]);
- double latitude = Double.parseDouble(tokens[idx++]);
- double longitude = Double.parseDouble(tokens[idx++]);
- double altitude = Double.parseDouble(tokens[idx++]);
- float bearing = Float.parseFloat(tokens[idx++]);
- float speed = Float.parseFloat(tokens[idx++]);
-
- location = new Location(provider);
- location.setTime(time);
- location.setLatitude(latitude);
- location.setLongitude(longitude);
- location.setAltitude(altitude);
- location.setBearing(bearing);
- location.setSpeed(speed);
- } catch (NumberFormatException nfe) {
- Log.e(TAG, "NumberFormatException reading last known location", nfe);
- return null;
- }
-
- return location;
- }
-
- private void writeLastKnownLocationLocked(String provider,
- Location location) {
- long now = SystemClock.elapsedRealtime();
- Long last = mLastWriteTime.get(provider);
- if ((last != null)
- && (now - last.longValue() < MIN_LAST_KNOWN_LOCATION_TIME)) {
- return;
- }
- mLastWriteTime.put(provider, now);
-
- StringBuilder sb = new StringBuilder(100);
- sb.append(location.getTime());
- sb.append(',');
- sb.append(location.getLatitude());
- sb.append(',');
- sb.append(location.getLongitude());
- sb.append(',');
- sb.append(location.getAltitude());
- sb.append(',');
- sb.append(location.getBearing());
- sb.append(',');
- sb.append(location.getSpeed());
-
- FileWriter writer = null;
- try {
- File d = new File(LocationManager.SYSTEM_DIR);
- if (!d.exists()) {
- if (!d.mkdirs()) {
- Log.w(TAG, "Unable to create directory to write location");
- return;
- }
- }
- File f = new File(LocationManager.SYSTEM_DIR + "/location." + provider);
- writer = new FileWriter(f);
- writer.write(sb.toString());
- } catch (IOException e) {
- Log.w(TAG, "Unable to write location", e);
- } finally {
- if (writer != null) {
- try {
- writer.close();
- } catch (IOException e) {
- Log.w(TAG, "Exception closing file", e);
- }
- }
- }
- }
-
private void addProvider(LocationProviderProxy provider) {
mProviders.add(provider);
mProvidersByName.put(provider.getName(), provider);
@@ -854,7 +748,9 @@
*/
void disposeLocked() {
ArrayList<UpdateRecord> records = mRecordsByProvider.get(this.mProvider);
- records.remove(this);
+ if (records != null) {
+ records.remove(this);
+ }
}
@Override
@@ -873,15 +769,6 @@
mLastFixBroadcast.dump(new PrintWriterPrinter(pw), prefix + " ");
pw.println(prefix + "mLastStatusBroadcast=" + mLastStatusBroadcast);
}
-
- /**
- * Calls dispose().
- */
- @Override protected void finalize() {
- synchronized (mLock) {
- disposeLocked();
- }
- }
}
private Receiver getReceiver(ILocationListener listener) {
@@ -1512,16 +1399,7 @@
return null;
}
- Location location = mLastKnownLocation.get(provider);
- if (location == null) {
- // Get the persistent last known location for the provider
- location = readLastKnownLocationLocked(provider);
- if (location != null) {
- mLastKnownLocation.put(provider, location);
- }
- }
-
- return location;
+ return mLastKnownLocation.get(provider);
}
private static boolean shouldBroadcastSafe(Location loc, Location lastLoc, UpdateRecord record) {
@@ -1566,7 +1444,6 @@
} else {
lastLocation.set(location);
}
- writeLastKnownLocationLocked(provider, location);
// Fetch latest status update time
long newStatusUpdateTime = p.getStatusUpdateTime();
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d4e69c0..867d8a6e 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.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 @@
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,
@@ -9818,6 +9838,7 @@
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 +9846,18 @@
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/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 14b1563d..80de074 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -81,9 +81,14 @@
throw new IllegalArgumentException("Invalid message body");
}
- SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
- scAddress, destinationAddress, text, (deliveryIntent != null));
- sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
+ try {
+ ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
+ if (iccISms != null) {
+ iccISms.sendText(destinationAddress, scAddress, text, sentIntent, deliveryIntent);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
}
/**
@@ -202,43 +207,11 @@
throw new IllegalArgumentException("Invalid message data");
}
- SmsMessage.SubmitPdu pdus = SmsMessage.getSubmitPdu(
- scAddress, destinationAddress,
- destinationPort, data, (deliveryIntent != null));
- sendRawPdu(pdus.encodedScAddress, pdus.encodedMessage, sentIntent, deliveryIntent);
- }
-
- /**
- * Send a raw SMS PDU.
- * A PDU is a protocol data unit. It contains the message and the
- * associated meta information.
- *
- * @param smsc the SMSC to send the message through, or NULL for the
- * default SMSC
- * @param pdu the raw PDU to send
- * @param sentIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is successfully sent, or failed.
- * The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:<br>
- * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
- * <code>RESULT_ERROR_RADIO_OFF</code><br>
- * <code>RESULT_ERROR_NULL_PDU</code><br>
- * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
- * the extra "errorCode" containing a radio technology specific value,
- * generally only useful for troubleshooting.<br>
- * The per-application based SMS control checks sentIntent. If sentIntent
- * is NULL the caller will be checked against all unknown applications,
- * which cause smaller number of SMS to be sent in checking period.
- * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
- * broadcast when the message is delivered to the recipient. The
- * raw pdu of the status report is in the extended data ("pdu").
- */
- private void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
try {
ISms iccISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
if (iccISms != null) {
- iccISms.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
+ iccISms.sendData(destinationAddress, scAddress, destinationPort & 0xFFFF,
+ data, sentIntent, deliveryIntent);
}
} catch (RemoteException ex) {
// ignore it
diff --git a/telephony/java/android/telephony/SmsMessage.java b/telephony/java/android/telephony/SmsMessage.java
index 0617dad..7a10512 100644
--- a/telephony/java/android/telephony/SmsMessage.java
+++ b/telephony/java/android/telephony/SmsMessage.java
@@ -309,8 +309,13 @@
while (pos < textLen) {
int nextPos = 0; // Counts code units.
if (ted.codeUnitSize == ENCODING_7BIT) {
- // For multi-segment messages, CDMA 7bit equals GSM 7bit encoding (EMS mode).
- nextPos = GsmAlphabet.findGsmSeptetLimitIndex(text, pos, limit);
+ if (activePhone == PHONE_TYPE_CDMA && ted.msgCount == 1) {
+ // For a singleton CDMA message, the encoding must be ASCII...
+ nextPos = pos + Math.min(limit, textLen - pos);
+ } else {
+ // For multi-segment messages, CDMA 7bit equals GSM 7bit encoding (EMS mode).
+ nextPos = GsmAlphabet.findGsmSeptetLimitIndex(text, pos, limit);
+ }
} else { // Assume unicode.
nextPos = pos + Math.min(limit / 2, textLen - pos);
}
@@ -345,6 +350,25 @@
return calculateLength((CharSequence)messageBody, use7bitOnly);
}
+ /*
+ * TODO(cleanup): It looks like there is now no useful reason why
+ * apps should generate pdus themselves using these routines,
+ * instead of handing the raw data to SMSDispatcher (and thereby
+ * have the phone process do the encoding). Moreover, CDMA now
+ * has shared state (in the form of the msgId system property)
+ * which can only be modified by the phone process, and hence
+ * makes the output of these routines incorrect. Since they now
+ * serve no purpose, they should probably just return null
+ * directly, and be deprecated. Going further in that direction,
+ * the above parsers of serialized pdu data should probably also
+ * be gotten rid of, hiding all but the necessarily visible
+ * structured data from client apps. A possible concern with
+ * doing this is that apps may be using these routines to generate
+ * pdus that are then sent elsewhere, some network server, for
+ * example, and that always returning null would thereby break
+ * otherwise useful apps.
+ */
+
/**
* Get an SMS-SUBMIT PDU for a destination address and a message
*
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 257f1e6..65bad96 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -67,24 +67,56 @@
boolean copyMessageToIccEf(int status, in byte[] pdu, in byte[] smsc);
/**
- * Send a SMS
+ * Send a data SMS.
*
* @param smsc the SMSC to send the message through, or NULL for the
* default SMSC
- * @param pdu the raw PDU to send
- * @param sentIntent if not NULL this <code>Intent</code> is
- * broadcast when the message is successfully sent, or failed.
+ * @param data the body of the message to send
+ * @param sentIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is sucessfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * @param deliveryIntent if not NULL this <code>Intent</code> is
+ * or one of these errors:<br>
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+ * <code>RESULT_ERROR_RADIO_OFF</code><br>
+ * <code>RESULT_ERROR_NULL_PDU</code><br>
+ * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+ * the extra "errorCode" containing a radio technology specific value,
+ * generally only useful for troubleshooting.<br>
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applicaitons,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*/
- void sendRawPdu(in byte[] smsc, in byte[] pdu, in PendingIntent sentIntent,
- in PendingIntent deliveryIntent);
+ void sendData(in String destAddr, in String scAddr, in int destPort,
+ in byte[] data, in PendingIntent sentIntent, in PendingIntent deliveryIntent);
+
+ /**
+ * Send an SMS.
+ *
+ * @param smsc the SMSC to send the message through, or NULL for the
+ * default SMSC
+ * @param text the body of the message to send
+ * @param sentIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is sucessfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:<br>
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+ * <code>RESULT_ERROR_RADIO_OFF</code><br>
+ * <code>RESULT_ERROR_NULL_PDU</code><br>
+ * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+ * the extra "errorCode" containing a radio technology specific value,
+ * generally only useful for troubleshooting.<br>
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applications,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is delivered to the recipient. The
+ * raw pdu of the status report is in the extended data ("pdu").
+ */
+ void sendText(in String destAddr, in String scAddr, in String text,
+ in PendingIntent sentIntent, in PendingIntent deliveryIntent);
/**
* Send a multi-part text based SMS.
diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index 620f2de..2cb0041 100644
--- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -20,6 +20,8 @@
import android.content.Context;
import android.util.Log;
+import com.android.internal.util.HexDump;
+
import java.util.ArrayList;
import java.util.List;
@@ -49,40 +51,81 @@
}
/**
- * Send a Raw PDU SMS
+ * Send a data based SMS to a specific application port.
*
- * @param smsc the SMSC to send the message through, or NULL for the
- * defatult SMSC
- * @param pdu the raw PDU to send
- * @param sentIntent if not NULL this <code>Intent</code> is
+ * @param destAddr the address to send the message to
+ * @param scAddr is the service center address or null to use
+ * the current default SMSC
+ * @param destPort the port to deliver the message to
+ * @param data the body of the message to send
+ * @param sentIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is sucessfully sent, or failed.
* The result code will be <code>Activity.RESULT_OK<code> for success,
- * or one of these errors:
- * <code>RESULT_ERROR_GENERIC_FAILURE</code>
- * <code>RESULT_ERROR_RADIO_OFF</code>
- * <code>RESULT_ERROR_NULL_PDU</code>.
- * @param deliveryIntent if not NULL this <code>Intent</code> is
+ * or one of these errors:<br>
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+ * <code>RESULT_ERROR_RADIO_OFF</code><br>
+ * <code>RESULT_ERROR_NULL_PDU</code><br>
+ * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+ * the extra "errorCode" containing a radio technology specific value,
+ * generally only useful for troubleshooting.<br>
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applicaitons,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
* broadcast when the message is delivered to the recipient. The
* raw pdu of the status report is in the extended data ("pdu").
*/
- public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
- Context context = mPhone.getContext();
-
- context.enforceCallingPermission(
+ public void sendData(String destAddr, String scAddr, int destPort,
+ byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ mPhone.getContext().enforceCallingPermission(
"android.permission.SEND_SMS",
"Sending SMS message");
- if (DBG) log("sendRawPdu: smsc=" + smsc +
- " pdu="+ pdu + " sentIntent" + sentIntent +
- " deliveryIntent" + deliveryIntent);
- mDispatcher.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
+ if (DBG) log("sendData: destAddr=" + destAddr + " scAddr=" + scAddr + " destPort=" +
+ destPort + " data='"+ HexDump.toHexString(data) + "' sentIntent=" +
+ sentIntent + " deliveryIntent=" + deliveryIntent);
+ mDispatcher.sendData(destAddr, scAddr, destPort, data, sentIntent, deliveryIntent);
+ }
+
+ /**
+ * Send a text based SMS.
+ *
+ * @param destAddr the address to send the message to
+ * @param scAddr is the service center address or null to use
+ * the current default SMSC
+ * @param text the body of the message to send
+ * @param sentIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is sucessfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:<br>
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+ * <code>RESULT_ERROR_RADIO_OFF</code><br>
+ * <code>RESULT_ERROR_NULL_PDU</code><br>
+ * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+ * the extra "errorCode" containing a radio technology specific value,
+ * generally only useful for troubleshooting.<br>
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applications,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is delivered to the recipient. The
+ * raw pdu of the status report is in the extended data ("pdu").
+ */
+ public void sendText(String destAddr, String scAddr,
+ String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ mPhone.getContext().enforceCallingPermission(
+ "android.permission.SEND_SMS",
+ "Sending SMS message");
+ if (DBG) log("sendText: destAddr=" + destAddr + " scAddr=" + scAddr +
+ " text='"+ text + "' sentIntent=" +
+ sentIntent + " deliveryIntent=" + deliveryIntent);
+ mDispatcher.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
}
/**
* Send a multi-part text based SMS.
*
- * @param destinationAddress the address to send the message to
- * @param scAddress is the service center address or null to use
+ * @param destAddr the address to send the message to
+ * @param scAddr is the service center address or null to use
* the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message
@@ -94,21 +137,22 @@
* <code>RESULT_ERROR_GENERIC_FAILURE</code>
* <code>RESULT_ERROR_RADIO_OFF</code>
* <code>RESULT_ERROR_NULL_PDU</code>.
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applicaitons,
+ * which cause smaller number of SMS to be sent in checking period.
* @param deliveryIntents if not null, an <code>ArrayList</code> of
* <code>PendingIntent</code>s (one for each message part) that is
* broadcast when the corresponding message part has been delivered
* to the recipient. The raw pdu of the status report is in the
* extended data ("pdu").
*/
- public void sendMultipartText(String destinationAddress, String scAddress, List<String> parts,
+ public void sendMultipartText(String destAddr, String scAddr, List<String> parts,
List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents) {
- Context context = mPhone.getContext();
-
- context.enforceCallingPermission(
+ mPhone.getContext().enforceCallingPermission(
"android.permission.SEND_SMS",
"Sending SMS message");
if (DBG) log("sendMultipartText");
- mDispatcher.sendMultipartText(destinationAddress, scAddress, (ArrayList<String>) parts,
+ mDispatcher.sendMultipartText(destAddr, scAddr, (ArrayList<String>) parts,
(ArrayList<PendingIntent>) sentIntents, (ArrayList<PendingIntent>) deliveryIntents);
}
@@ -163,4 +207,3 @@
protected abstract void log(String msg);
}
-
diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
index a51d074..1910a9c 100644
--- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
+++ b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManagerProxy.java
@@ -50,16 +50,21 @@
return mIccSmsInterfaceManager.getAllMessagesFromIccEf();
}
- public void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) throws android.os.RemoteException {
- mIccSmsInterfaceManager.sendRawPdu(smsc, pdu, sentIntent,
- deliveryIntent);
+ public void sendData(String destAddr, String scAddr, int destPort,
+ byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ mIccSmsInterfaceManager.sendData(destAddr, scAddr, destPort, data,
+ sentIntent, deliveryIntent);
}
- public void sendMultipartText(String destinationAddress, String scAddress,
+ public void sendText(String destAddr, String scAddr,
+ String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ mIccSmsInterfaceManager.sendText(destAddr, scAddr, text, sentIntent, deliveryIntent);
+ }
+
+ public void sendMultipartText(String destAddr, String scAddr,
List<String> parts, List<PendingIntent> sentIntents,
List<PendingIntent> deliveryIntents) throws android.os.RemoteException {
- mIccSmsInterfaceManager.sendMultipartText(destinationAddress, scAddress,
+ mIccSmsInterfaceManager.sendMultipartText(destAddr, scAddr,
parts, sentIntents, deliveryIntents);
}
diff --git a/telephony/java/com/android/internal/telephony/SMSDispatcher.java b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
index bbfc6c9..7efaa2e 100644
--- a/telephony/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/SMSDispatcher.java
@@ -635,12 +635,66 @@
dispatch(intent, "android.permission.RECEIVE_SMS");
}
+ /**
+ * Send a data based SMS to a specific application port.
+ *
+ * @param destAddr the address to send the message to
+ * @param scAddr is the service center address or null to use
+ * the current default SMSC
+ * @param destPort the port to deliver the message to
+ * @param data the body of the message to send
+ * @param sentIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is sucessfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:<br>
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+ * <code>RESULT_ERROR_RADIO_OFF</code><br>
+ * <code>RESULT_ERROR_NULL_PDU</code><br>
+ * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+ * the extra "errorCode" containing a radio technology specific value,
+ * generally only useful for troubleshooting.<br>
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applicaitons,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is delivered to the recipient. The
+ * raw pdu of the status report is in the extended data ("pdu").
+ */
+ protected abstract void sendData(String destAddr, String scAddr, int destPort,
+ byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent);
+
+ /**
+ * Send a text based SMS.
+ *
+ * @param destAddr the address to send the message to
+ * @param scAddr is the service center address or null to use
+ * the current default SMSC
+ * @param text the body of the message to send
+ * @param sentIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is sucessfully sent, or failed.
+ * The result code will be <code>Activity.RESULT_OK<code> for success,
+ * or one of these errors:<br>
+ * <code>RESULT_ERROR_GENERIC_FAILURE</code><br>
+ * <code>RESULT_ERROR_RADIO_OFF</code><br>
+ * <code>RESULT_ERROR_NULL_PDU</code><br>
+ * For <code>RESULT_ERROR_GENERIC_FAILURE</code> the sentIntent may include
+ * the extra "errorCode" containing a radio technology specific value,
+ * generally only useful for troubleshooting.<br>
+ * The per-application based SMS control checks sentIntent. If sentIntent
+ * is NULL the caller will be checked against all unknown applications,
+ * which cause smaller number of SMS to be sent in checking period.
+ * @param deliveryIntent if not NULL this <code>PendingIntent</code> is
+ * broadcast when the message is delivered to the recipient. The
+ * raw pdu of the status report is in the extended data ("pdu").
+ */
+ protected abstract void sendText(String destAddr, String scAddr,
+ String text, PendingIntent sentIntent, PendingIntent deliveryIntent);
/**
* Send a multi-part text based SMS.
*
- * @param destinationAddress the address to send the message to
- * @param scAddress is the service center address or null to use
+ * @param destAddr the address to send the message to
+ * @param scAddr is the service center address or null to use
* the current default SMSC
* @param parts an <code>ArrayList</code> of strings that, in order,
* comprise the original message
@@ -661,7 +715,7 @@
* to the recipient. The raw pdu of the status report is in the
* extended data ("pdu").
*/
- protected abstract void sendMultipartText(String destinationAddress, String scAddress,
+ protected abstract void sendMultipartText(String destAddr, String scAddr,
ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents);
diff --git a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
index c74bb8d..cc13450 100644
--- a/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -28,20 +28,9 @@
* {@hide}
*/
public abstract class ServiceStateTracker extends Handler {
+
/**
- * The access technology currently in use:
- * 0 = unknown
- * 1 = GPRS only
- * 2 = EDGE
- * 3 = UMTS
- * 4 = IS95A
- * 5 = IS95B
- * 6 = 1xRTT
- * 7 = EvDo_0
- * 8 = EvDo_A
- * 9 = HSDPA
- * 10 = HSUPA
- * 11 = HSPA
+ * Access technology currently in use.
*/
protected static final int DATA_ACCESS_UNKNOWN = 0;
protected static final int DATA_ACCESS_GPRS = 1;
@@ -55,7 +44,6 @@
protected static final int DATA_ACCESS_HSDPA = 9;
protected static final int DATA_ACCESS_HSUPA = 10;
protected static final int DATA_ACCESS_HSPA = 11;
- //***** Instance Variables
protected CommandsInterface cm;
@@ -64,33 +52,36 @@
public SignalStrength mSignalStrength;
- // Used as a unique identifier to track requests associated with a poll
- // and ignore stale responses.The value is a count-down of expected responses
- // in this pollingContext
+ /**
+ * A unique identifier to track requests associated with a poll
+ * and ignore stale responses. The value is a count-down of
+ * expected responses in this pollingContext.
+ */
protected int[] pollingContext;
protected boolean mDesiredPowerState;
- protected boolean dontPollSignalStrength = false; // Default is to poll strength
- // If we're getting unsolicited signal strength updates from the radio,
- // set value to true and don't bother polling any more
+ /**
+ * By default, strength polling is enabled. However, if we're
+ * getting unsolicited signal strength updates from the radio, set
+ * value to true and don't bother polling any more.
+ */
+ protected boolean dontPollSignalStrength = false;
protected RegistrantList networkAttachedRegistrants = new RegistrantList();
protected RegistrantList roamingOnRegistrants = new RegistrantList();
protected RegistrantList roamingOffRegistrants = new RegistrantList();
- //***** Constants
-
protected static final boolean DBG = true;
- // signal strength poll rate
+ /** Signal strength poll rate. */
protected static final int POLL_PERIOD_MILLIS = 20 * 1000;
- // waiting period before recheck gprs and voice registration
+ /** Waiting period before recheck gprs and voice registration. */
public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
public static final int DATA_STATE_POLL_SLEEP_MS = 100;
- //*****GSM events
+ /** GSM events */
protected static final int EVENT_RADIO_STATE_CHANGED = 1;
protected static final int EVENT_NETWORK_STATE_CHANGED = 2;
protected static final int EVENT_GET_SIGNAL_STRENGTH = 3;
@@ -112,7 +103,7 @@
protected static final int EVENT_CHECK_REPORT_GPRS = 22;
protected static final int EVENT_RESTRICTED_STATE_CHANGED = 23;
- //*****CDMA events:
+ /** CDMA events */
protected static final int EVENT_POLL_STATE_REGISTRATION_CDMA = 24;
protected static final int EVENT_POLL_STATE_OPERATOR_CDMA = 25;
protected static final int EVENT_RUIM_READY = 26;
@@ -129,13 +120,14 @@
protected static final int EVENT_OTA_PROVISION_STATUS_CHANGE = 37;
protected static final int EVENT_SET_RADIO_POWER_OFF = 38;
- //***** Time Zones
protected static final String TIMEZONE_PROPERTY = "persist.sys.timezone";
- // List of ISO codes for countries that can have an offset of GMT+0
- // when not in daylight savings time. This ignores some small places
- // such as the Canary Islands (Spain) and Danmarkshavn (Denmark).
- // The list must be sorted by code.
+ /**
+ * List of ISO codes for countries that can have an offset of
+ * GMT+0 when not in daylight savings time. This ignores some
+ * small places such as the Canary Islands (Spain) and
+ * Danmarkshavn (Denmark). The list must be sorted by code.
+ */
protected static final String[] GMT_COUNTRY_CODES = {
"bf", // Burkina Faso
"ci", // Cote d'Ivoire
@@ -159,11 +151,10 @@
"uk", // U.K
};
- //***** Registration denied reason
+ /** Reason for registration denial. */
protected static final String REGISTRATION_DENIED_GEN = "General";
protected static final String REGISTRATION_DENIED_AUTH = "Authentication Failure";
- //***** Constructors
public ServiceStateTracker() {
}
@@ -228,8 +219,6 @@
obtainMessage(EVENT_GET_PREFERRED_NETWORK_TYPE, onComplete));
}
-
- //***** Called from Phone
public void
setRadioPower(boolean power) {
mDesiredPowerState = power;
@@ -237,7 +226,6 @@
setPowerStateToDesired();
}
-
public void enableLocationUpdates() {
cm.setLocationUpdates(true, obtainMessage(EVENT_LOCATION_UPDATES_ENABLED));
}
@@ -246,17 +234,15 @@
cm.setLocationUpdates(false, null);
}
- //***** Overridden from Handler
public abstract void handleMessage(Message msg);
- //***** Protected abstract Methods
protected abstract void handlePollStateResult(int what, AsyncResult ar);
protected abstract void updateSpnDisplay();
protected abstract void setPowerStateToDesired();
/** Cancel a pending (if any) pollState() operation */
protected void cancelPollState() {
- // This will effectively cancel the rest of the poll requests
+ // This will effectively cancel the rest of the poll requests.
pollingContext = new int[1];
}
}
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 6177c8a..e73039b 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -116,6 +116,16 @@
* android.telephony.SmsMessage ENCODING_*).
*/
public int codeUnitSize;
+
+ @Override
+ public String toString() {
+ return "TextEncodingDetails " +
+ "{ msgCount=" + msgCount +
+ ", codeUnitCount=" + codeUnitCount +
+ ", codeUnitsRemaining=" + codeUnitsRemaining +
+ ", codeUnitSize=" + codeUnitSize +
+ " }";
+ }
}
// TODO(): This class is duplicated in SmsMessage.java. Refactor accordingly.
diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
index de5bbc1..55ba149 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java
@@ -130,4 +130,10 @@
* The number of milli-seconds between CALL_RING notifications.
*/
static final String PROPERTY_CALL_RING_DELAY = "ro.telephony.call_ring.delay";
+
+ /**
+ * Track CDMA SMS message id numbers to ensure they increment
+ * monotonically, regardless of reboots.
+ */
+ static final String PROPERTY_CDMA_MSG_ID = "persist.radio.cdma.msgid";
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 88cccd3..ca15a03 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -286,6 +286,22 @@
}
/** {@inheritDoc} */
+ protected void sendData(String destAddr, String scAddr, int destPort,
+ byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
+ scAddr, destAddr, destPort, data, (deliveryIntent != null));
+ sendSubmitPdu(pdu, sentIntent, deliveryIntent);
+ }
+
+ /** {@inheritDoc} */
+ protected void sendText(String destAddr, String scAddr, String text,
+ PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
+ scAddr, destAddr, text, (deliveryIntent != null), null);
+ sendSubmitPdu(pdu, sentIntent, deliveryIntent);
+ }
+
+ /** {@inheritDoc} */
protected void sendMultipartText(String destAddr, String scAddr,
ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents) {
@@ -329,16 +345,9 @@
}
}
- protected void sendSubmitPdu(SmsMessage.SubmitPdu submitPdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
- sendRawPdu(submitPdu.encodedScAddress, submitPdu.encodedMessage,
- sentIntent, deliveryIntent);
- }
-
- protected void sendRawPdu(byte[] smsc, byte[] pdu, PendingIntent sentIntent,
- PendingIntent deliveryIntent) {
- String inEcm = SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE);
- if (Boolean.parseBoolean(inEcm)) {
+ protected void sendSubmitPdu(SmsMessage.SubmitPdu pdu,
+ PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ if (SystemProperties.getBoolean(TelephonyProperties.PROPERTY_INECM_MODE, false)) {
if (sentIntent != null) {
try {
sentIntent.send(SmsManager.RESULT_ERROR_NO_SERVICE);
@@ -349,8 +358,7 @@
}
return;
}
-
- super.sendRawPdu(smsc, pdu, sentIntent, deliveryIntent);
+ sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
}
/** {@inheritDoc} */
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index b4de09b..4c958f6 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -41,28 +41,19 @@
import android.util.Log;
import android.util.Config;
import android.util.TimeUtils;
-import java.util.Calendar;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.DataConnectionTracker;
-// pretty sure importing stuff from GSM is bad:
import com.android.internal.telephony.gsm.MccTable;
import com.android.internal.telephony.PhoneProxy;
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
import com.android.internal.telephony.TelephonyIntents;
-
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISMANUAL;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISROAMING;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_NUMERIC;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
+import com.android.internal.telephony.TelephonyProperties;
import java.util.Arrays;
+import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
@@ -70,14 +61,14 @@
* {@hide}
*/
final class CdmaServiceStateTracker extends ServiceStateTracker {
+ static final String LOG_TAG = "CDMA";
- //***** Instance Variables
CDMAPhone phone;
CdmaCellLocation cellLoc;
CdmaCellLocation newCellLoc;
/**
- * The access technology currently in use: DATA_ACCESS_
+ * Values correspond to ServiceStateTracker.DATA_ACCESS_ definitions.
*/
private int networkType = 0;
private int newNetworkType = 0;
@@ -87,7 +78,9 @@
private boolean mIsInPrl;
private int mDefaultRoamingIndicator;
- // Initially we assume no data connection
+ /**
+ * Initially assume no data connection.
+ */
private int cdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
private int newCdmaDataConnectionState = ServiceState.STATE_OUT_OF_SERVICE;
private int mRegistrationState = -1;
@@ -95,9 +88,11 @@
private RegistrantList cdmaDataConnectionDetachedRegistrants = new RegistrantList();
private RegistrantList cdmaForSubscriptionInfoReadyRegistrants = new RegistrantList();
- // Sometimes we get the NITZ time before we know what country we are in.
- // Keep the time zone information from the NITZ string so we can fix
- // the time zone once know the country.
+ /**
+ * Sometimes we get the NITZ time before we know what country we
+ * are in. Keep the time zone information from the NITZ string so
+ * we can fix the time zone once know the country.
+ */
private boolean mNeedFixZone = false;
private int mZoneOffset;
private boolean mZoneDst;
@@ -107,20 +102,23 @@
long mSavedTime;
long mSavedAtTime;
- // We can't register for SIM_RECORDS_LOADED immediately because the
- // SIMRecords object may not be instantiated yet.
+ /**
+ * We can't register for SIM_RECORDS_LOADED immediately because the
+ * SIMRecords object may not be instantiated yet.
+ */
private boolean mNeedToRegForRuimLoaded = false;
- // Wake lock used while setting time of day.
+ /** Wake lock used while setting time of day. */
private PowerManager.WakeLock mWakeLock;
private static final String WAKELOCK_TAG = "ServiceStateTracker";
- // Keep track of SPN display rules, so we only broadcast intent if something changes.
+ /** Track of SPN display rules, so we only broadcast intent if something changes. */
private String curSpn = null;
- private String curPlmn = null; // it contains the name of the registered network in CDMA can
- // be the ONS or ERI text
private int curSpnRule = 0;
+ /** Contains the name of the registered network in CDMA (either ONS or ERI text). */
+ private String curPlmn = null;
+
private String mMdn;
private int mHomeSystemId[] = null;
private int mHomeNetworkId[] = null;
@@ -133,12 +131,9 @@
private boolean mPendingRadioPowerOffAfterDataOff = false;
- // Registration Denied Reason, General/Authentication Failure, used only for debugging purposes
+ /* Used only for debugging purposes. */
private String mRegistrationDeniedReason;
- //***** Constants
- static final String LOG_TAG = "CDMA";
-
private ContentResolver cr;
private String currentCarrier = null;
@@ -151,9 +146,6 @@
}
};
-
- //***** Constructors
-
public CdmaServiceStateTracker(CDMAPhone phone) {
super();
@@ -182,7 +174,7 @@
phone.registerForEriFileLoaded(this, EVENT_ERI_FILE_LOADED, null);
cm.registerForCdmaOtaProvision(this,EVENT_OTA_PROVISION_STATUS_CHANGE, null);
- // system setting property AIRPLANE_MODE_ON is set in Settings.
+ // System setting property AIRPLANE_MODE_ON is set in Settings.
int airplaneMode = Settings.System.getInt(
phone.getContext().getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0);
@@ -198,7 +190,7 @@
}
public void dispose() {
- //Unregister for all events
+ // Unregister for all events.
cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
cm.unregisterForNetworkStateChanged(this);
@@ -236,8 +228,7 @@
* @param what what code of message when delivered
* @param obj placed in Message.obj
*/
- /*protected*/ void
- registerForCdmaDataConnectionAttached(Handler h, int what, Object obj) {
+ void registerForCdmaDataConnectionAttached(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
cdmaDataConnectionAttachedRegistrants.add(r);
@@ -245,6 +236,7 @@
r.notifyRegistrant();
}
}
+
void unregisterForCdmaDataConnectionAttached(Handler h) {
cdmaDataConnectionAttachedRegistrants.remove(h);
}
@@ -255,8 +247,7 @@
* @param what what code of message when delivered
* @param obj placed in Message.obj
*/
- /*protected*/ void
- registerForCdmaDataConnectionDetached(Handler h, int what, Object obj) {
+ void registerForCdmaDataConnectionDetached(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
cdmaDataConnectionDetachedRegistrants.add(r);
@@ -264,6 +255,7 @@
r.notifyRegistrant();
}
}
+
void unregisterForCdmaDataConnectionDetached(Handler h) {
cdmaDataConnectionDetachedRegistrants.remove(h);
}
@@ -287,7 +279,6 @@
cdmaForSubscriptionInfoReadyRegistrants.remove(h);
}
- //***** Called from CDMAPhone
public void
getLacAndCid(Message onComplete) {
cm.getRegistrationState(obtainMessage(
@@ -302,14 +293,11 @@
switch (msg.what) {
case EVENT_RADIO_AVAILABLE:
- //this is unnecessary
- //setPowerStateToDesired();
break;
case EVENT_RUIM_READY:
- // The RUIM is now ready i.e if it was locked
- // it has been unlocked. At this stage, the radio is already
- // powered on.
+ // The RUIM is now ready i.e if it was locked it has been
+ // unlocked. At this stage, the radio is already powered on.
isSubscriptionFromRuim = true;
if (mNeedToRegForRuimLoaded) {
phone.mRuimRecords.registerForRecordsLoaded(this,
@@ -320,10 +308,10 @@
cm.getCDMASubscription(obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
if (DBG) log("Receive EVENT_RUIM_READY and Send Request getCDMASubscription.");
- // restore the previous network selection.
+ // Restore the previous network selection.
pollState();
- // Signal strength polling stops when radio is off
+ // Signal strength polling stops when radio is off.
queueNextSignalStrengthPoll();
break;
@@ -334,13 +322,12 @@
// subscription info.
cm.getCDMASubscription( obtainMessage(EVENT_POLL_STATE_CDMA_SUBSCRIPTION));
pollState();
- // Signal strength polling stops when radio is off
+ // Signal strength polling stops when radio is off.
queueNextSignalStrengthPoll();
break;
case EVENT_RADIO_STATE_CHANGED:
- // This will do nothing in the radio not
- // available case
+ // This will do nothing in the 'radio not available' case.
setPowerStateToDesired();
pollState();
break;
@@ -351,10 +338,10 @@
case EVENT_GET_SIGNAL_STRENGTH:
// This callback is called when signal strength is polled
- // all by itself
+ // all by itself.
if (!(cm.getRadioState().isOn()) || (cm.getRadioState().isGsm())) {
- // Polling will continue when radio turns back on
+ // Polling will continue when radio turns back on.
return;
}
ar = (AsyncResult) msg.obj;
@@ -390,7 +377,7 @@
}
}
- // only update if cell location really changed
+ // Only update if cell location really changed.
if (cellLoc.getBaseStationId() != baseStationData[0]
|| cellLoc.getBaseStationLatitude() != baseStationData[1]
|| cellLoc.getBaseStationLongitude() != baseStationData[2]) {
@@ -479,13 +466,12 @@
break;
case EVENT_SIGNAL_STRENGTH_UPDATE:
- // This is a notification from
- // CommandsInterface.setOnSignalStrengthUpdate
+ // This is a notification from CommandsInterface.setOnSignalStrengthUpdate.
ar = (AsyncResult) msg.obj;
- // The radio is telling us about signal strength changes
- // we don't have to ask it
+ // The radio is telling us about signal strength changes,
+ // so we don't have to ask it.
dontPollSignalStrength = true;
onSignalStrengthResult(ar);
@@ -504,7 +490,7 @@
break;
case EVENT_ERI_FILE_LOADED:
- // Repoll the state once the ERI file has been loaded
+ // Repoll the state once the ERI file has been loaded.
if (DBG) log("[CdmaServiceStateTracker] ERI file has been loaded, repolling.");
pollState();
break;
@@ -627,7 +613,7 @@
int ints[];
String states[];
- // Ignore stale requests from last poll
+ // Ignore stale requests from last poll.
if (ar.userObj != pollingContext) return;
if (ar.exception != null) {
@@ -638,13 +624,13 @@
}
if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
- // Radio has crashed or turned off
+ // Radio has crashed or turned off.
cancelPollState();
return;
}
if (!cm.getRadioState().isOn()) {
- // Radio has crashed or turned off
+ // Radio has crashed or turned off.
cancelPollState();
return;
}
@@ -698,13 +684,15 @@
}
mRegistrationState = registrationState;
- // mCdmaRoaming is true when registration state is roaming and TSB58 roaming
- // indicator is not in the carrier-specified list of ERIs for home system
+ // When registration state is roaming and TSB58
+ // roaming indicator is not in the carrier-specified
+ // list of ERIs for home system, mCdmaRoaming is true.
mCdmaRoaming =
regCodeIsRoaming(registrationState) && !isRoamIndForHomeSystem(states[10]);
newSS.setState (regCodeToServiceState(registrationState));
- this.newCdmaDataConnectionState = radioTechnologyToDataServiceState(radioTechnology);
+ this.newCdmaDataConnectionState =
+ radioTechnologyToDataServiceState(radioTechnology);
newSS.setRadioTechnology(radioTechnology);
newNetworkType = radioTechnology;
@@ -715,7 +703,7 @@
mDefaultRoamingIndicator = defaultRoamingIndicator;
- // values are -1 if not available
+ // Values are -1 if not available.
newCellLoc.setCellLocationData(baseStationId, baseStationLatitude,
baseStationLongitude, systemId, networkId);
@@ -737,8 +725,8 @@
if (opNames != null && opNames.length >= 3) {
if (cm.getRadioState().isNVReady()) {
- // In CDMA in case on NV the ss.mOperatorAlphaLong is set later with the
- // ERI text, so here it is ignored what is coming from the modem
+ // In CDMA in case on NV, the ss.mOperatorAlphaLong is set later with the
+ // ERI text, so here it is ignored what is coming from the modem.
newSS.setOperatorName(null, opNames[1], opNames[2]);
} else {
newSS.setOperatorName(opNames[0], opNames[1], opNames[2]);
@@ -803,9 +791,8 @@
}
}
-
- // NOTE: Some operator may require to override the mCdmaRoaming (set by the modem)
- // depending on the mRoamingIndicator.
+ // NOTE: Some operator may require overriding mCdmaRoaming
+ // (set by the modem), depending on the mRoamingIndicator.
if (DBG) {
log("Set CDMA Roaming Indicator to: " + newSS.getCdmaRoamingIndicator()
@@ -865,13 +852,13 @@
setSignalStrengthDefaultValues();
mGotCountryCode = false;
- //NOTE: pollStateDone() is not needed in this case
+ // NOTE: pollStateDone() is not needed in this case
break;
default:
- // Issue all poll-related commands at once
- // then count down the responses, which
- // are allowed to arrive out-of-order
+ // Issue all poll-related commands at once, then count
+ // down the responses which are allowed to arrive
+ // out-of-order.
pollingContext[0]++;
// RIL_REQUEST_OPERATOR is necessary for CDMA
@@ -1000,7 +987,7 @@
newSS.setStateOutOfService(); // clean slate for next time
if (hasNetworkTypeChanged) {
- phone.setSystemProperty(PROPERTY_DATA_NETWORK_TYPE,
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
networkTypeToString(networkType));
}
@@ -1027,14 +1014,14 @@
String operatorNumeric;
- phone.setSystemProperty(PROPERTY_OPERATOR_ALPHA,
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
ss.getOperatorAlphaLong());
operatorNumeric = ss.getOperatorNumeric();
- phone.setSystemProperty(PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
if (operatorNumeric == null) {
- phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, "");
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
} else {
String isoCountryCode = "";
try{
@@ -1046,14 +1033,15 @@
Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
}
- phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, isoCountryCode);
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY,
+ isoCountryCode);
mGotCountryCode = true;
if (mNeedFixZone) {
fixTimeZone(isoCountryCode);
}
}
- phone.setSystemProperty(PROPERTY_OPERATOR_ISROAMING,
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
ss.getRoaming() ? "true" : "false");
updateSpnDisplay();
@@ -1282,7 +1270,7 @@
*/
private
boolean isRoamingBetweenOperators(boolean cdmaRoaming, ServiceState s) {
- String spn = SystemProperties.get(PROPERTY_ICC_OPERATOR_ALPHA, "empty");
+ String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
// NOTE: in case of RUIM we should completely ignore the ERI data file and
// mOperatorAlphaLong is set from RIL_REQUEST_OPERATOR response 0 (alpha ONS)
@@ -1366,7 +1354,7 @@
zone = TimeZone.getTimeZone( tzname );
}
- String iso = SystemProperties.get(PROPERTY_OPERATOR_ISO_COUNTRY);
+ String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
if (zone == null) {
@@ -1549,7 +1537,6 @@
* that could support voice and data simultaneously.
*/
boolean isConcurrentVoiceAndData() {
-
// Note: it needs to be confirmed which CDMA network types
// can support voice and data calls concurrently.
// For the time-being, the return value will be false.
@@ -1576,11 +1563,12 @@
/**
* Returns IMSI as MCC + MNC + MIN
*/
- /*package*/ String getImsi() {
+ String getImsi() {
// TODO(Moto): When RUIM is enabled, IMSI will come from RUIM
// not build-time props. Moto will provide implementation
// for RUIM-ready case later.
- String operatorNumeric = SystemProperties.get(PROPERTY_ICC_OPERATOR_NUMERIC, "");
+ String operatorNumeric = SystemProperties.get(
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
if (!TextUtils.isEmpty(operatorNumeric) && getCdmaMin() != null) {
return (operatorNumeric + getCdmaMin());
diff --git a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
index 1597427..2c20784 100755
--- a/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/cdma/SmsMessage.java
@@ -17,6 +17,7 @@
package com.android.internal.telephony.cdma;
import android.os.Parcel;
+import android.os.SystemProperties;
import android.text.format.Time;
import android.util.Config;
import android.util.Log;
@@ -25,6 +26,7 @@
import com.android.internal.telephony.IccUtils;
import com.android.internal.telephony.SmsHeader;
import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.TelephonyProperties;
import com.android.internal.telephony.cdma.sms.BearerData;
import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
import com.android.internal.telephony.cdma.sms.SmsEnvelope;
@@ -38,7 +40,6 @@
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-import java.util.Random;
/**
* TODO(cleanup): these constants are disturbing... are they not just
@@ -78,14 +79,6 @@
*/
private int status;
- /** The next message ID for the BearerData. Shall be a random value on first use.
- * (See C.S0015-B, v2.0, 4.3.1.5)
- */
- private static int nextMessageId = 0;
-
- /** Specifies if this is the first SMS message submit */
- private static boolean firstSMS = true;
-
/** Specifies if a return of an acknowledgment is requested for send SMS */
private static final int RETURN_NO_ACK = 0;
private static final int RETURN_ACK = 1;
@@ -331,7 +324,7 @@
* address, if applicable, and the encoded message.
* Returns null on encode error.
*/
- public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, short destPort,
+ public static SubmitPdu getSubmitPdu(String scAddr, String destAddr, int destPort,
byte[] data, boolean statusReportRequested) {
/**
@@ -605,18 +598,28 @@
}
/**
- * Set the nextMessageId to a random value between 0 and 65536
- * See C.S0015-B, v2.0, 4.3.1.5
+ * Calculate the next message id, starting at 0 and iteratively
+ * incrementing within the range 0..65535 remembering the state
+ * via a persistent system property. (See C.S0015-B, v2.0,
+ * 4.3.1.5)
*/
- private static void setNextMessageId() {
- // Message ID, modulo 65536
- if(firstSMS) {
- Random generator = new Random();
- nextMessageId = generator.nextInt(65536);
- firstSMS = false;
- } else {
- nextMessageId = ++nextMessageId & 0xFFFF;
+ private synchronized static int getNextMessageId() {
+ // The only (meaningful) way this code can be called is via
+ // binder-call into the Phone process. All other calls will
+ // assumedly not be as with UID radio, and hence will be
+ // unable to modify the system property. Synchronization has
+ // thus been added to this function conservatively -- if it
+ // can be conclusively reasoned to be unnecessary, it should
+ // be removed.
+ int msgId = SystemProperties.getInt(TelephonyProperties.PROPERTY_CDMA_MSG_ID, 0);
+ String nextMsgId = Integer.toString((msgId + 1) & 0xFFFF);
+ SystemProperties.set(TelephonyProperties.PROPERTY_CDMA_MSG_ID, nextMsgId);
+ if (DBG_SMS) {
+ Log.d(LOG_TAG, "next " + TelephonyProperties.PROPERTY_CDMA_MSG_ID + " = " + nextMsgId);
+ Log.d(LOG_TAG, "readback gets " +
+ SystemProperties.get(TelephonyProperties.PROPERTY_CDMA_MSG_ID));
}
+ return msgId;
}
/**
@@ -642,8 +645,7 @@
BearerData bearerData = new BearerData();
bearerData.messageType = BearerData.MESSAGE_TYPE_SUBMIT;
- if (userData != null) setNextMessageId();
- bearerData.messageId = nextMessageId;
+ bearerData.messageId = getNextMessageId();
bearerData.deliveryAckReq = statusReportRequested;
bearerData.userAckReq = false;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 2770ddc..b412fec 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -137,6 +137,22 @@
}
/** {@inheritDoc} */
+ protected void sendData(String destAddr, String scAddr, int destPort,
+ byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
+ scAddr, destAddr, destPort, data, (deliveryIntent != null));
+ sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
+ }
+
+ /** {@inheritDoc} */
+ protected void sendText(String destAddr, String scAddr, String text,
+ PendingIntent sentIntent, PendingIntent deliveryIntent) {
+ SmsMessage.SubmitPdu pdu = SmsMessage.getSubmitPdu(
+ scAddr, destAddr, text, (deliveryIntent != null));
+ sendRawPdu(pdu.encodedScAddress, pdu.encodedMessage, sentIntent, deliveryIntent);
+ }
+
+ /** {@inheritDoc} */
protected void sendMultipartText(String destinationAddress, String scAddress,
ArrayList<String> parts, ArrayList<PendingIntent> sentIntents,
ArrayList<PendingIntent> deliveryIntents) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
index e7406e2..a9be068 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
@@ -16,13 +16,6 @@
package com.android.internal.telephony.gsm;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ALPHA;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_ISROAMING;
-import static com.android.internal.telephony.TelephonyProperties.PROPERTY_OPERATOR_NUMERIC;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -60,6 +53,7 @@
import com.android.internal.telephony.ServiceStateTracker;
import com.android.internal.telephony.TelephonyEventLog;
import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.TelephonyProperties;
import java.util.Arrays;
import java.util.Calendar;
@@ -70,8 +64,9 @@
* {@hide}
*/
final class GsmServiceStateTracker extends ServiceStateTracker {
+ static final String LOG_TAG = "GSM";
+ static final boolean DBG = true;
- //***** Instance Variables
GSMPhone phone;
GsmCellLocation cellLoc;
GsmCellLocation newCellLoc;
@@ -82,13 +77,15 @@
private int newGPRSState = ServiceState.STATE_OUT_OF_SERVICE;
/**
- * The access technology currently in use: DATA_ACCESS_
+ * Values correspond to ServiceStateTracker.DATA_ACCESS_ definitions.
*/
private int networkType = 0;
private int newNetworkType = 0;
- /* gsm roaming status solely based on TS 27.007 7.2 CREG */
+
+ /** GSM roaming status solely based on TS 27.007 7.2 CREG. */
private boolean mGsmRoaming = false;
- /* data roaming status solely based on TS 27.007 10.1.19 CGREG */
+
+ /** Data roaming status solely based on TS 27.007 10.1.19 CGREG. */
private boolean mDataRoaming = false;
private boolean newDataRoaming = false;
@@ -97,9 +94,11 @@
private RegistrantList psRestrictEnabledRegistrants = new RegistrantList();
private RegistrantList psRestrictDisabledRegistrants = new RegistrantList();
- // Sometimes we get the NITZ time before we know what country we are in.
- // Keep the time zone information from the NITZ string so we can fix
- // the time zone once know the country.
+ /**
+ * Sometimes we get the NITZ time before we know what country we
+ * are in. Keep the time zone information from the NITZ string so
+ * we can fix the time zone once know the country.
+ */
private boolean mNeedFixZone = false;
private int mZoneOffset;
private boolean mZoneDst;
@@ -111,13 +110,16 @@
long mSavedTime;
long mSavedAtTime;
- // We can't register for SIM_RECORDS_LOADED immediately because the
- // SIMRecords object may not be instantiated yet.
+ /**
+ * We can't register for SIM_RECORDS_LOADED immediately because the
+ * SIMRecords object may not be instantiated yet.
+ */
private boolean mNeedToRegForSimLoaded;
- // Started the recheck process after finding gprs should registerd but not
+ /** Started the recheck process after finding gprs should registerd but not. */
private boolean mStartedGprsRegCheck = false;
- // Already sent the event-log for no gprs register
+
+ /** Already sent the event-log for no gprs register. */
private boolean mReportedGprsNoReg = false;
/**
@@ -125,34 +127,29 @@
*/
private Notification mNotification;
- // Wake lock used while setting time of day.
+ /** Wake lock used while setting time of day. */
private PowerManager.WakeLock mWakeLock;
private static final String WAKELOCK_TAG = "ServiceStateTracker";
- // Keep track of SPN display rules, so we only broadcast intent if something changes.
+ /** Keep track of SPN display rules, so we only broadcast intent if something changes. */
private String curSpn = null;
private String curPlmn = null;
private int curSpnRule = 0;
- //***** Constants
-
- static final boolean DBG = true;
- static final String LOG_TAG = "GSM";
-
- // waiting period before recheck gprs and voice registration
+ /** waiting period before recheck gprs and voice registration. */
static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
- // notification type
- static final int PS_ENABLED = 1001; // Access Control blocks data service
- static final int PS_DISABLED = 1002; // Access Control enables data service
- static final int CS_ENABLED = 1003; // Access Control blocks all voice/sms service
- static final int CS_DISABLED = 1004; // Access Control enables all voice/sms service
- static final int CS_NORMAL_ENABLED = 1005; // Access Control blocks normal voice/sms service
- static final int CS_EMERGENCY_ENABLED = 1006; // Access Control blocks emergency call service
+ /** Notification type. */
+ static final int PS_ENABLED = 1001; // Access Control blocks data service
+ static final int PS_DISABLED = 1002; // Access Control enables data service
+ static final int CS_ENABLED = 1003; // Access Control blocks all voice/sms service
+ static final int CS_DISABLED = 1004; // Access Control enables all voice/sms service
+ static final int CS_NORMAL_ENABLED = 1005; // Access Control blocks normal voice/sms service
+ static final int CS_EMERGENCY_ENABLED = 1006; // Access Control blocks emergency call service
- // notification id
- static final int PS_NOTIFICATION = 888; //id to update and cancel PS restricted
- static final int CS_NOTIFICATION = 999; //id to update and cancel CS restricted
+ /** Notification id. */
+ static final int PS_NOTIFICATION = 888; // Id to update and cancel PS restricted
+ static final int CS_NOTIFICATION = 999; // Id to update and cancel CS restricted
static final int MAX_NUM_DATA_STATE_READS = 15;
@@ -164,9 +161,6 @@
}
};
-
- //***** Constructors
-
public GsmServiceStateTracker(GSMPhone phone) {
super();
@@ -207,7 +201,7 @@
}
public void dispose() {
- //Unregister for all events
+ // Unregister for all events.
cm.unregisterForAvailable(this);
cm.unregisterForRadioStateChanged(this);
cm.unregisterForNetworkStateChanged(this);
@@ -230,7 +224,7 @@
* @param what what code of message when delivered
* @param obj placed in Message.obj
*/
- /*protected*/ void registerForGprsAttached(Handler h, int what, Object obj) {
+ void registerForGprsAttached(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
gprsAttachedRegistrants.add(r);
@@ -239,11 +233,11 @@
}
}
- /*protected*/ void unregisterForGprsAttached(Handler h) {
+ void unregisterForGprsAttached(Handler h) {
gprsAttachedRegistrants.remove(h);
}
- /*protected*/ void registerForNetworkAttach(Handler h, int what, Object obj) {
+ void registerForNetworkAttach(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
networkAttachedRegistrants.add(r);
@@ -252,16 +246,17 @@
}
}
- /*protected*/ void unregisterForNetworkAttach(Handler h) {
+ void unregisterForNetworkAttach(Handler h) {
networkAttachedRegistrants.remove(h);
}
+
/**
* Registration point for transition into GPRS detached.
* @param h handler to notify
* @param what what code of message when delivered
* @param obj placed in Message.obj
*/
- /*protected*/ void registerForGprsDetached(Handler h, int what, Object obj) {
+ void registerForGprsDetached(Handler h, int what, Object obj) {
Registrant r = new Registrant(h, what, obj);
gprsDetachedRegistrants.add(r);
@@ -270,7 +265,7 @@
}
}
- /*protected*/ void unregisterForGprsDetached(Handler h) {
+ void unregisterForGprsDetached(Handler h) {
gprsDetachedRegistrants.remove(h);
}
@@ -280,7 +275,7 @@
* @param what what code of message when delivered
* @param obj placed in Message.obj
*/
- /*protected*/ void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
+ void registerForPsRestrictedEnabled(Handler h, int what, Object obj) {
Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedEnabled ");
Registrant r = new Registrant(h, what, obj);
psRestrictEnabledRegistrants.add(r);
@@ -290,7 +285,7 @@
}
}
- /*protected*/ void unregisterForPsRestrictedEnabled(Handler h) {
+ void unregisterForPsRestrictedEnabled(Handler h) {
psRestrictEnabledRegistrants.remove(h);
}
@@ -300,7 +295,7 @@
* @param what what code of message when delivered
* @param obj placed in Message.obj
*/
- /*protected*/ void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
+ void registerForPsRestrictedDisabled(Handler h, int what, Object obj) {
Log.d(LOG_TAG, "[DSAC DEB] " + "registerForPsRestrictedDisabled ");
Registrant r = new Registrant(h, what, obj);
psRestrictDisabledRegistrants.add(r);
@@ -310,25 +305,20 @@
}
}
- /*protected*/ void unregisterForPsRestrictedDisabled(Handler h) {
+ void unregisterForPsRestrictedDisabled(Handler h) {
psRestrictDisabledRegistrants.remove(h);
}
- /*protected*/ boolean getDataRoaming() {
+ boolean getDataRoaming() {
return mDataRoaming;
}
- //***** Called from GSMPhone
- public void
- getLacAndCid(Message onComplete) {
+ public void getLacAndCid(Message onComplete) {
cm.getRegistrationState(obtainMessage(
EVENT_GET_LOC_DONE, onComplete));
}
-
- //***** Overridden from ServiceStateTracker
- public void
- handleMessage (Message msg) {
+ public void handleMessage (Message msg) {
AsyncResult ar;
int[] ints;
String[] strings;
@@ -529,10 +519,7 @@
}
}
- //***** Private Instance Methods
-
- protected void setPowerStateToDesired()
- {
+ protected void setPowerStateToDesired() {
// If we want it on and it's off, turn it on
if (mDesiredPowerState
&& cm.getRadioState() == CommandsInterface.RadioState.RADIO_OFF) {
@@ -593,9 +580,7 @@
/**
* Handle the result of one of the pollState()-related requests
*/
-
- protected void
- handlePollStateResult (int what, AsyncResult ar) {
+ protected void handlePollStateResult (int what, AsyncResult ar) {
int ints[];
String states[];
@@ -726,9 +711,7 @@
* and start over again if the radio notifies us that some
* event has changed
*/
-
- private void
- pollState() {
+ private void pollState() {
pollingContext = new int[1];
pollingContext[0] = 0;
@@ -828,8 +811,7 @@
return ret;
}
- private void
- pollStateDone() {
+ private void pollStateDone() {
if (DBG) {
Log.d(LOG_TAG, "Poll ServiceState done: " +
" oldSS=[" + ss + "] newSS=[" + newSS +
@@ -882,7 +864,7 @@
newSS.setStateOutOfService(); // clean slate for next time
if (hasNetworkTypeChanged) {
- phone.setSystemProperty(PROPERTY_DATA_NETWORK_TYPE,
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_DATA_NETWORK_TYPE,
networkTypeToString(networkType));
}
@@ -895,14 +877,14 @@
if (hasChanged) {
String operatorNumeric;
- phone.setSystemProperty(PROPERTY_OPERATOR_ALPHA,
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ALPHA,
ss.getOperatorAlphaLong());
operatorNumeric = ss.getOperatorNumeric();
- phone.setSystemProperty(PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, operatorNumeric);
if (operatorNumeric == null) {
- phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, "");
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, "");
} else {
String iso = "";
try{
@@ -914,7 +896,7 @@
Log.w(LOG_TAG, "countryCodeForMcc error" + ex);
}
- phone.setSystemProperty(PROPERTY_OPERATOR_ISO_COUNTRY, iso);
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, iso);
mGotCountryCode = true;
if (mNeedFixZone) {
@@ -957,7 +939,7 @@
}
}
- phone.setSystemProperty(PROPERTY_OPERATOR_ISROAMING,
+ phone.setSystemProperty(TelephonyProperties.PROPERTY_OPERATOR_ISROAMING,
ss.getRoaming() ? "true" : "false");
updateSpnDisplay();
@@ -1052,8 +1034,7 @@
return guess;
}
- private void
- queueNextSignalStrengthPoll() {
+ private void queueNextSignalStrengthPoll() {
if (dontPollSignalStrength || (cm.getRadioState().isCdma())) {
// The radio is telling us about signal strength changes
// we don't have to ask it
@@ -1075,8 +1056,7 @@
* send signal-strength-changed notification if changed
* Called both for solicited and unsolicited signal stength updates
*/
- private void
- onSignalStrengthResult(AsyncResult ar) {
+ private void onSignalStrengthResult(AsyncResult ar) {
SignalStrength oldSignalStrength = mSignalStrength;
int rssi = 99;
@@ -1117,8 +1097,7 @@
*
* @param ar an int value of RIL_RESTRICTED_STATE_*
*/
- private void onRestrictedStateChanged(AsyncResult ar)
- {
+ private void onRestrictedStateChanged(AsyncResult ar) {
Log.d(LOG_TAG, "[DSAC DEB] " + "onRestrictedStateChanged");
RestrictedState newRs = new RestrictedState();
@@ -1207,8 +1186,7 @@
}
/** code is registration state 0-5 from TS 27.007 7.2 */
- private int
- regCodeToServiceState(int code) {
+ private int regCodeToServiceState(int code) {
switch (code) {
case 0:
case 2: // 2 is "searching"
@@ -1234,8 +1212,7 @@
* code is registration state 0-5 from TS 27.007 7.2
* returns true if registered roam, false otherwise
*/
- private boolean
- regCodeIsRoaming (int code) {
+ private boolean regCodeIsRoaming (int code) {
// 5 is "in service -- roam"
return 5 == code;
}
@@ -1247,9 +1224,8 @@
* @param s ServiceState hold current ons
* @return true for roaming state set
*/
- private
- boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) {
- String spn = SystemProperties.get(PROPERTY_ICC_OPERATOR_ALPHA, "empty");
+ private boolean isRoamingBetweenOperators(boolean gsmRoaming, ServiceState s) {
+ String spn = SystemProperties.get(TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, "empty");
String onsl = s.getOperatorAlphaLong();
String onss = s.getOperatorAlphaShort();
@@ -1257,7 +1233,8 @@
boolean equalsOnsl = onsl != null && spn.equals(onsl);
boolean equalsOnss = onss != null && spn.equals(onss);
- String simNumeric = SystemProperties.get(PROPERTY_ICC_OPERATOR_NUMERIC, "");
+ String simNumeric = SystemProperties.get(
+ TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, "");
String operatorNumeric = s.getOperatorNumeric();
boolean equalsMcc = true;
@@ -1270,8 +1247,7 @@
return gsmRoaming && !(equalsMcc && (equalsOnsl || equalsOnss));
}
- private static
- int twoDigitsAt(String s, int offset) {
+ private static int twoDigitsAt(String s, int offset) {
int a, b;
a = Character.digit(s.charAt(offset), 10);
@@ -1289,7 +1265,7 @@
* @return The current GPRS state. IN_SERVICE is the same as "attached"
* and OUT_OF_SERVICE is the same as detached.
*/
- /*package*/ int getCurrentGprsState() {
+ int getCurrentGprsState() {
return gprsState;
}
@@ -1337,10 +1313,7 @@
/**
* nitzReceiveTime is time_t that the NITZ time was posted
*/
-
- private
- void setTimeFromNITZString (String nitz, long nitzReceiveTime)
- {
+ private void setTimeFromNITZString (String nitz, long nitzReceiveTime) {
// "yy/mm/dd,hh:mm:ss(+/-)tz"
// tz is in number of quarter-hours
@@ -1404,7 +1377,7 @@
zone = TimeZone.getTimeZone( tzname );
}
- String iso = SystemProperties.get(PROPERTY_OPERATOR_ISO_COUNTRY);
+ String iso = SystemProperties.get(TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY);
if (zone == null) {
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
index 93721ff..569cf25 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsMessage.java
@@ -337,7 +337,7 @@
* Returns null on encode error.
*/
public static SubmitPdu getSubmitPdu(String scAddress,
- String destinationAddress, short destinationPort, byte[] data,
+ String destinationAddress, int destinationPort, byte[] data,
boolean statusReportRequested) {
SmsHeader.PortAddrs portAddrs = new SmsHeader.PortAddrs();
diff --git a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
index 02af547..98d4c25 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
@@ -32,12 +32,10 @@
import android.util.Log;
-import java.util.Iterator;
-
-import java.lang.Integer;
+import java.util.ArrayList;
public class CdmaSmsTest extends AndroidTestCase {
- private final static String LOG_TAG = "CDMA";
+ private final static String LOG_TAG = "XXX CdmaSmsTest XXX";
@SmallTest
public void testCdmaSmsAddrParsing() throws Exception {
@@ -530,29 +528,19 @@
@SmallTest
public void testNumberOfMessages() throws Exception {
+ // Note that the message text below does not properly reflect
+ // the message count. The author of these messages was
+ // apparently unaware that the values are bcd encoded, and the
+ // values being tested against (not the ones in the message
+ // text) are actually correct.
String pdu1 = "000310409001124896a794e07595f69f199540ea759a0dc8e00b0163";
BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
assertEquals("Test Voice mail 99", bd1.userData.payloadStr);
- assertEquals(99, bd1.numberOfMessages);
+ assertEquals(63, bd1.numberOfMessages);
String pdu2 = "00031040900113489ea794e07595f69f199540ea759a0988c0600b0164";
BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
assertEquals("Test Voice mail 100", bd2.userData.payloadStr);
- assertEquals(100, bd2.numberOfMessages);
- }
-
- @SmallTest
- public void testNumberOfMessagesFeedback() throws Exception {
- BearerData bearerData = new BearerData();
- bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
- bearerData.messageId = 0;
- bearerData.hasUserDataHeader = false;
- UserData userData = new UserData();
- userData.payloadStr = "test message count";
- bearerData.userData = userData;
- bearerData.numberOfMessages = 27;
- byte []encodedSms = BearerData.encode(bearerData);
- BearerData revBearerData = BearerData.decode(encodedSms);
- assertEquals(bearerData.numberOfMessages, revBearerData.numberOfMessages);
+ assertEquals(64, bd2.numberOfMessages);
}
@SmallTest
@@ -766,7 +754,6 @@
public void testDisplayMode() throws Exception {
String pdu1 = "0003104090010c485f4194dfea34becf61b8400f0100";
BearerData bd1 = BearerData.decode(HexDump.hexStringToByteArray(pdu1));
- //Log.d(LOG_TAG, "bd1 = " + bd1);
assertEquals(bd1.displayMode, BearerData.DISPLAY_MODE_IMMEDIATE);
String pdu2 = "0003104090010c485f4194dfea34becf61b8400f0140";
BearerData bd2 = BearerData.decode(HexDump.hexStringToByteArray(pdu2));
@@ -830,4 +817,30 @@
BearerData revBearerData = BearerData.decode(encodedSms);
assertEquals(userData.payloadStr, revBearerData.userData.payloadStr);
}
+
+ @SmallTest
+ public void testFragmentText() throws Exception {
+ // Valid 160 character ASCII text.
+ String text1 = "123456789012345678901234567890123456789012345678901234567890" +
+ "1234567890123456789012345678901234567890123456789012345678901234567890" +
+ "12345678901234567890123456789[";
+ TextEncodingDetails ted = SmsMessage.calculateLength(text1, false);
+ assertEquals(ted.msgCount, 1);
+ assertEquals(ted.codeUnitCount, 160);
+ assertEquals(ted.codeUnitSize, 1);
+ ArrayList<String> fragments = android.telephony.SmsMessage.fragmentText(text1);
+ assertEquals(fragments.size(), 1);
+ // Valid 160 character GSM text -- the last character is
+ // non-ASCII, and so this will currently generate a singleton
+ // EMS message, which is not necessarily supported by Verizon.
+ String text2 = "123456789012345678901234567890123456789012345678901234567890" +
+ "1234567890123456789012345678901234567890123456789012345678901234567890" +
+ "12345678901234567890123456789\u00a3"; // Trailing pound-currency sign.
+ ted = SmsMessage.calculateLength(text2, false);
+ assertEquals(ted.msgCount, 1);
+ assertEquals(ted.codeUnitCount, 160);
+ assertEquals(ted.codeUnitSize, 1);
+ fragments = android.telephony.SmsMessage.fragmentText(text2);
+ assertEquals(fragments.size(), 1);
+ }
}
diff --git a/tests/DumpRenderTree/assets/run_layout_tests.py b/tests/DumpRenderTree/assets/run_layout_tests.py
index c056de5..c3e6b5b 100755
--- a/tests/DumpRenderTree/assets/run_layout_tests.py
+++ b/tests/DumpRenderTree/assets/run_layout_tests.py
@@ -175,7 +175,7 @@
# Count crashed tests.
crashed_tests = []
- timeout_ms = '5000'
+ timeout_ms = '30000'
if options.time_out_ms:
timeout_ms = options.time_out_ms
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoTest.java
index 2eecef8..b980710 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 void timedOut(String url) {
+ Log.v(LOGTAG, "layout timeout: " + url);
}
});
@@ -398,7 +400,8 @@
if (resume)
resumeTestList();
- TestShellActivity activity = (TestShellActivity) getActivity();
+ TestShellActivity activity = getActivity();
+ activity.setDefaultDumpDataType(DumpDataType.DUMP_AS_TEXT);
// Run tests.
int addr = -1;
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index 4c9853d..10849921 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -428,10 +428,15 @@
}
}
-static bool applyFileOverlay(const sp<AaptAssets>& assets,
+static bool applyFileOverlay(Bundle *bundle,
+ const sp<AaptAssets>& assets,
const sp<ResourceTypeSet>& baseSet,
const char *resType)
{
+ if (bundle->getVerbose()) {
+ printf("applyFileOverlay for %s\n", resType);
+ }
+
// Replace any base level files in this category with any found from the overlay
// Also add any found only in the overlay.
sp<AaptAssets> overlay = assets->getOverlay();
@@ -450,6 +455,9 @@
// non-overlay "baseset".
size_t overlayCount = overlaySet->size();
for (size_t overlayIndex=0; overlayIndex<overlayCount; overlayIndex++) {
+ if (bundle->getVerbose()) {
+ printf("trying overlaySet Key=%s\n",overlaySet->keyAt(overlayIndex).string());
+ }
size_t baseIndex = baseSet->indexOfKey(overlaySet->keyAt(overlayIndex));
if (baseIndex < UNKNOWN_ERROR) {
// look for same flavor. For a given file (strings.xml, for example)
@@ -457,18 +465,36 @@
// the same flavor.
sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
sp<AaptGroup> baseGroup = baseSet->valueAt(baseIndex);
-
- DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles =
- baseGroup->getFiles();
- DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
+
+ DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
overlayGroup->getFiles();
+ if (bundle->getVerbose()) {
+ DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles =
+ baseGroup->getFiles();
+ for (size_t i=0; i < baseFiles.size(); i++) {
+ printf("baseFile %d has flavor %s\n", i,
+ baseFiles.keyAt(i).toString().string());
+ }
+ for (size_t i=0; i < overlayFiles.size(); i++) {
+ printf("overlayFile %d has flavor %s\n", i,
+ overlayFiles.keyAt(i).toString().string());
+ }
+ }
+
size_t overlayGroupSize = overlayFiles.size();
- for (size_t overlayGroupIndex = 0;
- overlayGroupIndex<overlayGroupSize;
+ for (size_t overlayGroupIndex = 0;
+ overlayGroupIndex<overlayGroupSize;
overlayGroupIndex++) {
- size_t baseFileIndex =
- baseFiles.indexOfKey(overlayFiles.keyAt(overlayGroupIndex));
+ size_t baseFileIndex =
+ baseGroup->getFiles().indexOfKey(overlayFiles.
+ keyAt(overlayGroupIndex));
if(baseFileIndex < UNKNOWN_ERROR) {
+ if (bundle->getVerbose()) {
+ printf("found a match (%d) for overlay file %s, for flavor %s\n",
+ baseFileIndex,
+ overlayGroup->getLeaf().string(),
+ overlayFiles.keyAt(overlayGroupIndex).toString().string());
+ }
baseGroup->removeFile(baseFileIndex);
} else {
// didn't find a match fall through and add it..
@@ -482,11 +508,11 @@
overlaySet->valueAt(overlayIndex));
// make sure all flavors are defined in the resources.
sp<AaptGroup> overlayGroup = overlaySet->valueAt(overlayIndex);
- DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
+ DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > overlayFiles =
overlayGroup->getFiles();
size_t overlayGroupSize = overlayFiles.size();
- for (size_t overlayGroupIndex = 0;
- overlayGroupIndex<overlayGroupSize;
+ for (size_t overlayGroupIndex = 0;
+ overlayGroupIndex<overlayGroupSize;
overlayGroupIndex++) {
assets->addGroupEntry(overlayFiles.keyAt(overlayGroupIndex));
}
@@ -623,13 +649,13 @@
current = current->getOverlay();
}
// apply the overlay files to the base set
- if (!applyFileOverlay(assets, drawables, "drawable") ||
- !applyFileOverlay(assets, layouts, "layout") ||
- !applyFileOverlay(assets, anims, "anim") ||
- !applyFileOverlay(assets, xmls, "xml") ||
- !applyFileOverlay(assets, raws, "raw") ||
- !applyFileOverlay(assets, colors, "color") ||
- !applyFileOverlay(assets, menus, "menu")) {
+ if (!applyFileOverlay(bundle, assets, drawables, "drawable") ||
+ !applyFileOverlay(bundle, assets, layouts, "layout") ||
+ !applyFileOverlay(bundle, assets, anims, "anim") ||
+ !applyFileOverlay(bundle, assets, xmls, "xml") ||
+ !applyFileOverlay(bundle, assets, raws, "raw") ||
+ !applyFileOverlay(bundle, assets, colors, "color") ||
+ !applyFileOverlay(bundle, assets, menus, "menu")) {
return UNKNOWN_ERROR;
}