Merge change I20d77880 into eclair-mr2
* changes:
Make Gservices setting constants public.
diff --git a/api/current.xml b/api/current.xml
index 7057866..027bc1b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -34032,6 +34032,17 @@
<parameter name="defaultValue" type="short">
</parameter>
</method>
+<method name="getSourceBounds"
+ return="android.graphics.Rect"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getStringArrayExtra"
return="java.lang.String[]"
abstract="false"
@@ -34843,6 +34854,19 @@
<parameter name="packageName" type="java.lang.String">
</parameter>
</method>
+<method name="setSourceBounds"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="r" type="android.graphics.Rect">
+</parameter>
+</method>
<method name="setType"
return="android.content.Intent"
abstract="false"
@@ -36423,6 +36447,17 @@
visibility="public"
>
</field>
+<field name="FILL_IN_SOURCE_BOUNDS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="32"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="FLAG_ACTIVITY_BROUGHT_TO_FRONT"
type="int"
transient="false"
@@ -62109,6 +62144,17 @@
visibility="public"
>
</method>
+<method name="flattenToString"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="height"
return="int"
abstract="false"
@@ -62335,6 +62381,19 @@
visibility="public"
>
</method>
+<method name="unflattenFromString"
+ return="android.graphics.Rect"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="str" type="java.lang.String">
+</parameter>
+</method>
<method name="union"
return="void"
abstract="false"
diff --git a/calendar/Android.mk b/calendar/Android.mk
new file mode 100644
index 0000000..fd20dfa
--- /dev/null
+++ b/calendar/Android.mk
@@ -0,0 +1,18 @@
+# Copyright 2009 Google, Inc.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := calendar
+LOCAL_SRC_FILES := \
+ ../core/java/android/provider/Calendar.java \
+ ../core/java/android/pim/EventRecurrence.java \
+ ../core/java/android/pim/ICalendar.java \
+ ../core/java/android/pim/RecurrenceSet.java \
+ ../core/java/android/pim/ContactsAsyncHelper.java \
+ ../core/java/android/pim/DateException.java
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Include this library in the build server's output directory
+$(call dist-for-goals, droid, $(LOCAL_BUILT_MODULE):calendar.jar)
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 6cb9770..cf9c58f 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -624,6 +624,14 @@
return false;
}
+ /** @hide */
+ public boolean isBluetoothDock() {
+ try {
+ return sService.isBluetoothDock(mAddress);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return false;
+ }
+
/**
* Create an RFCOMM {@link BluetoothSocket} ready to start a secure
* outgoing connection to this remote device on given channel.
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 7e752af..0868779 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -64,6 +64,7 @@
boolean setTrust(in String address, in boolean value);
boolean getTrustState(in String address);
+ boolean isBluetoothDock(in String address);
int addRfcommServiceRecord(in String serviceName, in ParcelUuid uuid, int channel, IBinder b);
void removeServiceRecord(int handle);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 6ba79b4..8d69814 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -26,6 +26,7 @@
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.graphics.Rect;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
@@ -2417,6 +2418,7 @@
private int mFlags;
private HashSet<String> mCategories;
private Bundle mExtras;
+ private Rect mSourceBounds;
// ---------------------------------------------------------------------
@@ -2442,6 +2444,9 @@
if (o.mExtras != null) {
this.mExtras = new Bundle(o.mExtras);
}
+ if (o.mSourceBounds != null) {
+ this.mSourceBounds = new Rect(o.mSourceBounds);
+ }
}
@Override
@@ -2635,7 +2640,7 @@
intent.mType = value;
}
- // launch flags
+ // launch flags
else if (uri.startsWith("launchFlags=", i)) {
intent.mFlags = Integer.decode(value).intValue();
}
@@ -2655,6 +2660,11 @@
scheme = value;
}
+ // source bounds
+ else if (uri.startsWith("sourceBounds=", i)) {
+ intent.mSourceBounds = Rect.unflattenFromString(value);
+ }
+
// extra
else {
String key = Uri.decode(uri.substring(i + 2, eq));
@@ -3547,6 +3557,15 @@
}
/**
+ * Get the bounds of the sender of this intent, in screen coordinates. This can be
+ * used as a hint to the receiver for animations and the like. Null means that there
+ * is no source bounds.
+ */
+ public Rect getSourceBounds() {
+ return mSourceBounds;
+ }
+
+ /**
* Return the Activity component that should be used to handle this intent.
* The appropriate component is determined based on the information in the
* intent, evaluated as follows:
@@ -4648,6 +4667,19 @@
}
/**
+ * Set the bounds of the sender of this intent, in screen coordinates. This can be
+ * used as a hint to the receiver for animations and the like. Null means that there
+ * is no source bounds.
+ */
+ public void setSourceBounds(Rect r) {
+ if (r != null) {
+ mSourceBounds = new Rect(r);
+ } else {
+ r = null;
+ }
+ }
+
+ /**
* Use with {@link #fillIn} to allow the current action value to be
* overwritten, even if it is already set.
*/
@@ -4678,6 +4710,12 @@
public static final int FILL_IN_PACKAGE = 1<<4;
/**
+ * Use with {@link #fillIn} to allow the current package value to be
+ * overwritten, even if it is already set.
+ */
+ public static final int FILL_IN_SOURCE_BOUNDS = 1<<5;
+
+ /**
* Copy the contents of <var>other</var> in to this object, but only
* where fields are not defined by this object. For purposes of a field
* being defined, the following pieces of data in the Intent are
@@ -4691,6 +4729,7 @@
* <li> package, as set by {@link #setPackage}.
* <li> component, as set by {@link #setComponent(ComponentName)} or
* related methods.
+ * <li> source bounds, as set by {@link #setSourceBounds}
* <li> each top-level name in the associated extras.
* </ul>
*
@@ -4752,6 +4791,11 @@
changes |= FILL_IN_COMPONENT;
}
mFlags |= other.mFlags;
+ if (other.mSourceBounds != null
+ && (mSourceBounds == null || (flags&FILL_IN_SOURCE_BOUNDS) != 0)) {
+ mSourceBounds = new Rect(other.mSourceBounds);
+ changes |= FILL_IN_SOURCE_BOUNDS;
+ }
if (mExtras == null) {
if (other.mExtras != null) {
mExtras = new Bundle(other.mExtras);
@@ -5005,6 +5049,13 @@
first = false;
b.append("cmp=").append(mComponent.flattenToShortString());
}
+ if (mSourceBounds != null) {
+ if (!first) {
+ b.append(' ');
+ }
+ first = false;
+ b.append("bnds=").append(mSourceBounds.toShortString());
+ }
if (extras && mExtras != null) {
if (!first) {
b.append(' ');
@@ -5096,6 +5147,11 @@
uri.append("component=").append(Uri.encode(
mComponent.flattenToShortString(), "/")).append(';');
}
+ if (mSourceBounds != null) {
+ uri.append("sourceBounds=")
+ .append(Uri.encode(mSourceBounds.flattenToString()))
+ .append(';');
+ }
if (mExtras != null) {
for (String key : mExtras.keySet()) {
final Object value = mExtras.get(key);
@@ -5139,6 +5195,13 @@
out.writeString(mPackage);
ComponentName.writeToParcel(mComponent, out);
+ if (mSourceBounds != null) {
+ out.writeInt(1);
+ mSourceBounds.writeToParcel(out, flags);
+ } else {
+ out.writeInt(0);
+ }
+
if (mCategories != null) {
out.writeInt(mCategories.size());
for (String category : mCategories) {
@@ -5174,6 +5237,10 @@
mPackage = in.readString();
mComponent = ComponentName.readFromParcel(in);
+ if (in.readInt() != 0) {
+ mSourceBounds = Rect.CREATOR.createFromParcel(in);
+ }
+
int N = in.readInt();
if (N > 0) {
mCategories = new HashSet<String>();
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 657bbcc..d9003a3 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -827,6 +827,15 @@
}
private void closeClosable() {
+ /* deallocate all compiled sql statement objects in compiledQueries cache.
+ * this should be done before de-referencing all {@link SQLiteClosable} objects
+ * from this database object because calling
+ * {@link SQLiteClosable#onAllReferencesReleasedFromContainer()} could cause the database
+ * to be closed. sqlite doesn't let a database close if there are
+ * any unfinalized statements - such as the compiled-sql objects in mCompiledQueries.
+ */
+ resetCompiledSqlCache();
+
Iterator<Map.Entry<SQLiteClosable, Object>> iter = mPrograms.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<SQLiteClosable, Object> entry = iter.next();
@@ -835,13 +844,6 @@
program.onAllReferencesReleasedFromContainer();
}
}
-
- // finalize all compiled sql statement objects in compiledQueries cache
- synchronized (mCompiledQueries) {
- for (SQLiteCompiledSql compiledStatement : mCompiledQueries.values()) {
- compiledStatement.releaseSqlStatement();
- }
- }
}
/**
@@ -1789,7 +1791,9 @@
*/
public void setMaxSqlCacheSize(int cacheSize) {
synchronized(mCompiledQueries) {
- resetCompiledSqlCache();
+ if (mMaxSqlCacheSize > 0) {
+ resetCompiledSqlCache();
+ }
mMaxSqlCacheSize = (cacheSize > MAX_SQL_CACHE_SIZE) ? MAX_SQL_CACHE_SIZE
: (cacheSize < 0) ? 0 : cacheSize;
}
@@ -1800,6 +1804,9 @@
*/
public void resetCompiledSqlCache() {
synchronized(mCompiledQueries) {
+ for (SQLiteCompiledSql compiledStatement : mCompiledQueries.values()) {
+ compiledStatement.releaseSqlStatement();
+ }
mCompiledQueries.clear();
}
}
@@ -1835,7 +1842,7 @@
/* reached max cachesize. before adding new entry, remove an entry from the
* cache. we don't want to wipe out the entire cache because of this:
* GCing {@link SQLiteCompiledSql} requires call to sqlite3_finalize
- * JNI method. If entire cache is wiped out, it could be cause a big GC activity
+ * JNI method. If entire cache is wiped out, it could cause a big GC activity
* just because a (rogue) process is using the cache incorrectly.
*/
Set<String> keySet = mCompiledQueries.keySet();
@@ -1844,8 +1851,7 @@
break;
}
}
- compiledSql = new SQLiteCompiledSql(this, sql);
- mCompiledQueries.put(sql, compiledSql);
+ mCompiledQueries.put(sql, compiledStatement);
}
if (SQLiteDebug.DEBUG_SQL_CACHE) {
Log.v(TAG, "|adding_sql_to_cache|" + getPath() + "|" + mCompiledQueries.size() + "|" +
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index edc15cb..5ee2f1e 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -100,7 +100,7 @@
* @return a unique identifier for this program
*/
public final int getUniqueId() {
- return compiledSql.nStatement;
+ return (compiledSql != null) ? compiledSql.nStatement : 0;
}
/* package */ String getSqlString() {
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 4b733ef..ac159f4 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -477,6 +477,10 @@
* application does not need a particular callback, a null can be passed
* instead of a callback method.
*
+ * This method will stop the preview. Applications should not call {@link
+ * #stopPreview()} before this. After jpeg callback is received,
+ * applications can call {@link #startPreview()} to restart the preview.
+ *
* @param shutter callback after the image is captured, may be null
* @param raw callback with raw image data, may be null
* @param jpeg callback with jpeg image data, may be null
@@ -500,6 +504,10 @@
* application does not need a particular callback, a null can be passed
* instead of a callback method.
*
+ * This method will stop the preview. Applications should not call {@link
+ * #stopPreview()} before this. After jpeg callback is received,
+ * applications can call {@link #startPreview()} to restart the preview.
+ *
* @param shutter callback after the image is captured, may be null
* @param raw callback with raw image data, may be null
* @param postview callback with postview image data, may be null
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index c3b0f1c..30c73d7 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -293,6 +293,13 @@
public static final String DISPLAY_NAME = "display_name";
/**
+ * Reference to the row in the RawContacts table holding the contact name.
+ * <P>Type: INTEGER REFERENCES raw_contacts(_id)</P>
+ * @hide
+ */
+ public static final String NAME_RAW_CONTACT_ID = "name_raw_contact_id";
+
+ /**
* Reference to the row in the data table holding the photo.
* <P>Type: INTEGER REFERENCES data(_id)</P>
*/
@@ -423,13 +430,21 @@
* row id changed as a result of a sync or aggregation.</td>
* </tr>
* <tr>
+ * <td>long</td>
+ * <td>NAME_RAW_CONTACT_ID</td>
+ * <td>read-only</td>
+ * <td>The ID of the raw contact that contributes the display name
+ * to the aggregate contact. During aggregation one of the constituent
+ * raw contacts is chosen using a heuristic: a longer name or a name
+ * with more diacritic marks or more upper case characters is chosen.</td>
+ * </tr>
+ * <tr>
* <td>String</td>
* <td>{@link #DISPLAY_NAME}</td>
* <td>read-only</td>
- * <td>The display name for the contact. During aggregation display name is
- * computed from display names of constituent raw contacts using a
- * heuristic: a longer name or a name with more diacritic marks or more
- * upper case characters is chosen.</td>
+ * <td>The display name for the contact. It is the display name
+ * contributed by the raw contact referred to by the NAME_RAW_CONTACT_ID
+ * column.</td>
* </tr>
* <tr>
* <td>long</td>
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 6380a8d..4860cbd 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -553,7 +553,8 @@
* <li><em>transactionId (Integer)</em> - The WAP transaction
* ID</li>
* <li><em>pduType (Integer)</em> - The WAP PDU type</li>
- * <li><em>data</em> - The data payload of the message</li>
+ * <li><em>header (byte[])</em> - The header of the message</li>
+ * <li><em>data (byte[])</em> - The data payload of the message</li>
* </ul>
*
* <p>If a BroadcastReceiver encounters an error while processing
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index cb3b6ee..e960491 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -492,6 +492,14 @@
mBluetoothService.getBondState().getPendingOutgoingBonding();
if (address.equals(pendingOutgoingAddress)) {
// we initiated the bonding
+
+ // Check if its a dock
+ if (mBluetoothService.isBluetoothDock(address)) {
+ String pin = mBluetoothService.getDockPin();
+ mBluetoothService.setPin(address, BluetoothDevice.convertPinToBytes(pin));
+ return;
+ }
+
BluetoothClass btClass = new BluetoothClass(mBluetoothService.getRemoteClass(address));
// try 0000 once if the device looks dumb
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index f8592e2..5dd016f 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -32,16 +32,16 @@
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetooth;
import android.bluetooth.IBluetoothCallback;
-import android.os.ParcelUuid;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
-import android.os.IBinder;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
+import android.os.ParcelUuid;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemService;
@@ -50,7 +50,13 @@
import com.android.internal.app.IBatteryStats;
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
@@ -58,6 +64,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
+import java.util.Random;
public class BluetoothService extends IBluetooth.Stub {
private static final String TAG = "BluetoothService";
@@ -79,6 +86,9 @@
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
+ private static final String DOCK_ADDRESS_PATH = "/sys/class/switch/dock/bt_addr";
+ private static final String DOCK_PIN_PATH = "/sys/class/switch/dock/bt_pin";
+
private static final int MESSAGE_REGISTER_SDP_RECORDS = 1;
private static final int MESSAGE_FINISH_DISABLE = 2;
private static final int MESSAGE_UUID_INTENT = 3;
@@ -104,6 +114,9 @@
private final HashMap<Integer, Integer> mServiceRecordToPid;
+ private static String mDockAddress;
+ private String mDockPin;
+
private static class RemoteService {
public String address;
public ParcelUuid uuid;
@@ -151,6 +164,96 @@
mUuidCallbackTracker = new HashMap<RemoteService, IBluetoothCallback>();
mServiceRecordToPid = new HashMap<Integer, Integer>();
registerForAirplaneMode();
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_DOCK_EVENT);
+ mContext.registerReceiver(mBroadcastReceiver, filter);
+ }
+
+ private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent != null) {
+ String action = intent.getAction();
+
+ if (Intent.ACTION_DOCK_EVENT.equals(action)) {
+ int state = intent.getIntExtra(Intent.EXTRA_DOCK_STATE,
+ Intent.EXTRA_DOCK_STATE_UNDOCKED);
+ if (DBG) Log.v(TAG, "Received ACTION_DOCK_EVENT with State:" + state);
+ if (state == Intent.EXTRA_DOCK_STATE_UNDOCKED) {
+ mDockAddress = null;
+ mDockPin = null;
+ }
+ }
+ }
+ }
+ };
+
+ public static synchronized String readDockBluetoothAddress() {
+ if (mDockAddress != null) return mDockAddress;
+
+ BufferedInputStream file = null;
+ String dockAddress;
+ try {
+ file = new BufferedInputStream(new FileInputStream(DOCK_ADDRESS_PATH));
+ byte[] address = new byte[17];
+ file.read(address);
+ dockAddress = new String(address);
+ dockAddress = dockAddress.toUpperCase();
+ if (BluetoothAdapter.checkBluetoothAddress(dockAddress)) {
+ mDockAddress = dockAddress;
+ return mDockAddress;
+ } else {
+ log("CheckBluetoothAddress failed for car dock address:" + dockAddress);
+ }
+ } catch (FileNotFoundException e) {
+ log("FileNotFoundException while trying to read dock address");
+ } catch (IOException e) {
+ log("IOException while trying to read dock address");
+ } finally {
+ if (file != null) {
+ try {
+ file.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+ mDockAddress = null;
+ return null;
+ }
+
+ private synchronized boolean writeDockPin() {
+ BufferedWriter out = null;
+ try {
+ out = new BufferedWriter(new FileWriter(DOCK_PIN_PATH));
+
+ // Generate a random 4 digit pin between 0000 and 9999
+ // This is not truly random but good enough for our purposes.
+ int pin = (int) Math.floor(Math.random() * 10000);
+
+ mDockPin = String.format("%04d", pin);
+ out.write(mDockPin);
+ return true;
+ } catch (FileNotFoundException e) {
+ log("FileNotFoundException while trying to write dock pairing pin");
+ } catch (IOException e) {
+ log("IOException while while trying to write dock pairing pin");
+ } finally {
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e) {
+ // Ignore
+ }
+ }
+ }
+ mDockPin = null;
+ return false;
+ }
+
+ /*package*/ synchronized String getDockPin() {
+ return mDockPin;
}
public synchronized void initAfterRegistration() {
@@ -922,6 +1025,13 @@
return false;
}
+ if (address.equals(mDockAddress)) {
+ if (!writeDockPin()) {
+ log("Error while writing Pin for the dock");
+ return false;
+ }
+ }
+
if (!createPairedDeviceNative(address, 60000 /* 1 minute */)) {
return false;
}
@@ -975,6 +1085,11 @@
return mBondState.getBondState(address.toUpperCase());
}
+ public synchronized boolean isBluetoothDock(String address) {
+ if (address.equals(mDockAddress)) return true;
+ return false;
+ }
+
/*package*/ boolean isRemoteDeviceInCache(String address) {
return (mDeviceProperties.get(address) != null);
}
diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java
index 6995107..aa8d979 100644
--- a/core/java/android/text/method/Touch.java
+++ b/core/java/android/text/method/Touch.java
@@ -20,6 +20,7 @@
import android.text.NoCopySpan;
import android.text.Layout.Alignment;
import android.text.Spannable;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.TextView;
@@ -156,8 +157,17 @@
padding));
ny = Math.max(ny, 0);
+ int oldX = widget.getScrollX();
+ int oldY = widget.getScrollY();
+
scrollTo(widget, layout, nx, ny);
- widget.cancelLongPress();
+
+ // If we actually scrolled, then cancel the up action.
+ if (oldX != widget.getScrollX()
+ || oldY != widget.getScrollY()) {
+ widget.cancelLongPress();
+ }
+
return true;
}
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index b8bd6a0..5d3840a 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -361,6 +361,8 @@
public final int OFF_BECAUSE_OF_USER = 1;
/** Screen turned off because of timeout */
public final int OFF_BECAUSE_OF_TIMEOUT = 2;
+ /** Screen turned off because of proximity sensor */
+ public final int OFF_BECAUSE_OF_PROX_SENSOR = 3;
/**
* Magic constant to {@link IWindowManager#setRotation} to not actually
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6f15c12..7885b8a 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3241,24 +3241,29 @@
mWebTextView.setNodePointer(nodePointer);
int maxLength = -1;
boolean isTextField = nativeFocusCandidateIsTextField();
+ boolean isPassword;
if (isTextField) {
maxLength = nativeFocusCandidateMaxLength();
String name = nativeFocusCandidateName();
- if (mWebViewCore.getSettings().getSaveFormData()
- && name != null) {
+ isPassword = nativeFocusCandidateIsPassword();
+ if (!isPassword && mWebViewCore.getSettings().getSaveFormData()
+ && name != null && name.length() > 0) {
Message update = mPrivateHandler.obtainMessage(
- REQUEST_FORM_DATA, nodePointer);
+ REQUEST_FORM_DATA);
+ update.arg1 = nodePointer;
RequestFormData updater = new RequestFormData(name,
getUrl(), update);
Thread t = new Thread(updater);
t.start();
}
+ } else {
+ isPassword = false;
}
mWebTextView.setMaxLength(maxLength);
AutoCompleteAdapter adapter = null;
mWebTextView.setAdapterCustom(adapter);
mWebTextView.setSingleLine(isTextField);
- mWebTextView.setInPassword(nativeFocusCandidateIsPassword());
+ mWebTextView.setInPassword(isPassword);
if (null == text) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "rebuildWebTextView null == text");
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 3b1f7a0..b847e57 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -23,6 +23,7 @@
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.PorterDuff;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Parcel;
@@ -136,10 +137,15 @@
if (target != null && pendingIntent != null) {
OnClickListener listener = new OnClickListener() {
public void onClick(View v) {
+ int[] pos = new int[2];
+ v.getLocationOnScreen(pos);
+ Intent intent = new Intent();
+ intent.setSourceBounds(new Rect(pos[0], pos[1],
+ pos[0]+v.getWidth(), pos[1]+v.getHeight()));
try {
// TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
v.getContext().startIntentSender(
- pendingIntent.getIntentSender(), null,
+ pendingIntent.getIntentSender(), intent,
Intent.FLAG_ACTIVITY_NEW_TASK,
Intent.FLAG_ACTIVITY_NEW_TASK, 0);
} catch (IntentSender.SendIntentException e) {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f55ca3f..201cc0c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -6529,6 +6529,7 @@
// Reset this state; it will be re-set if super.onTouchEvent
// causes focus to move to the view.
mTouchFocusSelected = false;
+ mScrolled = false;
}
final boolean superResult = super.onTouchEvent(event);
@@ -6545,10 +6546,6 @@
if ((mMovement != null || onCheckIsTextEditor()) && mText instanceof Spannable && mLayout != null) {
- if (action == MotionEvent.ACTION_DOWN) {
- mScrolled = false;
- }
-
boolean handled = false;
int oldSelStart = Selection.getSelectionStart(mText);
diff --git a/core/res/res/drawable-hdpi/btn_default_transparent_normal.9.png b/core/res/res/drawable-hdpi/btn_default_transparent_normal.9.png
new file mode 100644
index 0000000..617dba3
--- /dev/null
+++ b/core/res/res/drawable-hdpi/btn_default_transparent_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_lock_normal.9.png b/core/res/res/drawable-hdpi/btn_lock_normal.9.png
deleted file mode 100644
index f1dac62..0000000
--- a/core/res/res/drawable-hdpi/btn_lock_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_big_half.png b/core/res/res/drawable-hdpi/rate_star_big_half.png
index 61906a5..4a91e87 100644
--- a/core/res/res/drawable-hdpi/rate_star_big_half.png
+++ b/core/res/res/drawable-hdpi/rate_star_big_half.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_big_off.png b/core/res/res/drawable-hdpi/rate_star_big_off.png
index a688a45..ae5883e 100644
--- a/core/res/res/drawable-hdpi/rate_star_big_off.png
+++ b/core/res/res/drawable-hdpi/rate_star_big_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_big_on.png b/core/res/res/drawable-hdpi/rate_star_big_on.png
index 77cb067..65c136e 100644
--- a/core/res/res/drawable-hdpi/rate_star_big_on.png
+++ b/core/res/res/drawable-hdpi/rate_star_big_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_med_half.png b/core/res/res/drawable-hdpi/rate_star_med_half.png
new file mode 100644
index 0000000..a436980
--- /dev/null
+++ b/core/res/res/drawable-hdpi/rate_star_med_half.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_med_off.png b/core/res/res/drawable-hdpi/rate_star_med_off.png
new file mode 100644
index 0000000..981aabe
--- /dev/null
+++ b/core/res/res/drawable-hdpi/rate_star_med_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_med_on.png b/core/res/res/drawable-hdpi/rate_star_med_on.png
new file mode 100644
index 0000000..320c14f
--- /dev/null
+++ b/core/res/res/drawable-hdpi/rate_star_med_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_small_half.png b/core/res/res/drawable-hdpi/rate_star_small_half.png
index 6b2efd9..0b8974e1 100644
--- a/core/res/res/drawable-hdpi/rate_star_small_half.png
+++ b/core/res/res/drawable-hdpi/rate_star_small_half.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_small_off.png b/core/res/res/drawable-hdpi/rate_star_small_off.png
index 8422919..7ae305f 100644
--- a/core/res/res/drawable-hdpi/rate_star_small_off.png
+++ b/core/res/res/drawable-hdpi/rate_star_small_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/rate_star_small_on.png b/core/res/res/drawable-hdpi/rate_star_small_on.png
index 45e2324..ffa5258 100644
--- a/core/res/res/drawable-hdpi/rate_star_small_on.png
+++ b/core/res/res/drawable-hdpi/rate_star_small_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_default_transparent_normal.9.png b/core/res/res/drawable-mdpi/btn_default_transparent_normal.9.png
new file mode 100644
index 0000000..3b3dea9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/btn_default_transparent_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_lock_normal.9.png b/core/res/res/drawable-mdpi/btn_lock_normal.9.png
deleted file mode 100644
index 6bdc2c6..0000000
--- a/core/res/res/drawable-mdpi/btn_lock_normal.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable/btn_default_transparent.xml b/core/res/res/drawable/btn_default_transparent.xml
new file mode 100644
index 0000000..f8e03ee
--- /dev/null
+++ b/core/res/res/drawable/btn_default_transparent.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@drawable/btn_default_pressed" />
+ <item android:state_focused="true" android:state_enabled="true"
+ android:drawable="@drawable/btn_default_selected" />
+ <item android:state_enabled="true"
+ android:drawable="@drawable/btn_default_transparent_normal" />
+</selector>
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock.xml b/core/res/res/layout/keyguard_screen_tab_unlock.xml
index 26b77bb..f8944b5 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock.xml
@@ -136,8 +136,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/screenLocked"
- android:layout_marginTop="24dip"
+ android:layout_marginTop="8dip"
+ android:layout_marginLeft="24dip"
android:drawableLeft="@drawable/ic_emergency"
+ style="@style/Widget.Button.Transparent"
android:drawablePadding="8dip"
/>
diff --git a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
index 5c80235..22c0b8e 100644
--- a/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
+++ b/core/res/res/layout/keyguard_screen_tab_unlock_land.xml
@@ -128,8 +128,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/screenLocked"
- android:layout_marginTop="24dip"
+ android:layout_marginTop="8dip"
android:drawableLeft="@drawable/ic_emergency"
+ style="@style/Widget.Button.Transparent"
android:drawablePadding="8dip"
/>
</RelativeLayout>
diff --git a/core/res/res/layout/keyguard_screen_unlock_landscape.xml b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
index 6da82e9..602a37c 100644
--- a/core/res/res/layout/keyguard_screen_unlock_landscape.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_landscape.xml
@@ -155,10 +155,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lockscreen_emergency_call"
- android:textSize="14sp"
- android:background="@drawable/btn_lock_normal"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/Widget.Button.Transparent"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
/>
@@ -174,20 +171,14 @@
<Button android:id="@+id/forgotPattern"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:textSize="14sp"
- android:background="@drawable/btn_lock_normal"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/Widget.Button.Transparent"
android:visibility="invisible"
/>
<Button android:id="@+id/emergencyCallTogether"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/lockscreen_emergency_call"
- android:textSize="14sp"
- android:background="@drawable/btn_lock_normal"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/Widget.Button.Transparent"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
/>
diff --git a/core/res/res/layout/keyguard_screen_unlock_portrait.xml b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
index 5916786..9ce5a25 100644
--- a/core/res/res/layout/keyguard_screen_unlock_portrait.xml
+++ b/core/res/res/layout/keyguard_screen_unlock_portrait.xml
@@ -165,9 +165,7 @@
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="@string/lockscreen_emergency_call"
- android:background="@drawable/btn_lock_normal"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/Widget.Button.Transparent"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
/>
@@ -190,9 +188,7 @@
android:layout_marginLeft="4dip"
android:layout_marginRight="2dip"
android:text="@string/lockscreen_emergency_call"
- android:background="@drawable/btn_lock_normal"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/Widget.Button.Transparent"
android:drawableLeft="@drawable/ic_emergency"
android:drawablePadding="8dip"
/>
@@ -204,9 +200,7 @@
android:layout_marginBottom="4dip"
android:layout_marginLeft="2dip"
android:layout_marginRight="4dip"
- android:background="@drawable/btn_lock_normal"
- android:textAppearance="?android:attr/textAppearanceSmall"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/Widget.Button.Transparent"
android:visibility="invisible"
/>
</LinearLayout>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index a629bb2..c95ede7 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -237,6 +237,12 @@
<item name="android:background">@android:drawable/button_inset</item>
</style>
+ <style name="Widget.Button.Transparent">
+ <item name="android:background">@android:drawable/btn_default_transparent</item>
+ <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+ <item name="android:textColor">@android:color/white</item>
+ </style>
+
<style name="Widget.CompoundButton">
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
diff --git a/docs/html/guide/samples/images/BluetoothChat1.png b/docs/html/guide/samples/images/BluetoothChat1.png
new file mode 100644
index 0000000..f87da6a
--- /dev/null
+++ b/docs/html/guide/samples/images/BluetoothChat1.png
Binary files differ
diff --git a/docs/html/guide/samples/images/BluetoothChat2.png b/docs/html/guide/samples/images/BluetoothChat2.png
new file mode 100644
index 0000000..6218eff
--- /dev/null
+++ b/docs/html/guide/samples/images/BluetoothChat2.png
Binary files differ
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index fc0061d..c9df3ba 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -124,9 +124,9 @@
<pre>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
- android:minWidth="294dp" <!-- density-independent pixels -->
+ android:minWidth="294dp"
android:minHeight="72dp"
- android:updatePeriodMillis="86400000" <!-- once per day -->
+ android:updatePeriodMillis="86400000"
android:initialLayout="@layout/example_appwidget"
android:configure="com.example.android.ExampleAppWidgetConfigure" >
</appwidget-provider>
diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java
index 42a14ce..98ffb8b 100644
--- a/graphics/java/android/graphics/Rect.java
+++ b/graphics/java/android/graphics/Rect.java
@@ -20,6 +20,8 @@
import android.os.Parcelable;
import java.io.PrintWriter;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* Rect holds four integer coordinates for a rectangle. The rectangle is
@@ -34,6 +36,9 @@
public int right;
public int bottom;
+ private static final Pattern FLATTENED_PATTERN = Pattern.compile(
+ "(-?\\d+) (-?\\d+) (-?\\d+) (-?\\d+)");
+
/**
* Create a new empty Rect. All coordinates are initialized to 0.
*/
@@ -105,6 +110,43 @@
sb.append(','); sb.append(bottom); sb.append(']');
return sb.toString();
}
+
+ /**
+ * Return a string representation of the rectangle in a well-defined format.
+ *
+ * <p>You can later recover the Rect from this string through
+ * {@link #unflattenFromString(String)}.
+ *
+ * @return Returns a new String of the form "left top right bottom"
+ */
+ public String flattenToString() {
+ StringBuilder sb = new StringBuilder(32);
+ // WARNING: Do not change the format of this string, it must be
+ // preserved because Rects are saved in this flattened format.
+ sb.append(left);
+ sb.append(' ');
+ sb.append(top);
+ sb.append(' ');
+ sb.append(right);
+ sb.append(' ');
+ sb.append(bottom);
+ return sb.toString();
+ }
+
+ /**
+ * Returns a Rect from a string of the form returned by {@link #flattenToString},
+ * or null if the string is not of that form.
+ */
+ public static Rect unflattenFromString(String str) {
+ Matcher matcher = FLATTENED_PATTERN.matcher(str);
+ if (!matcher.matches()) {
+ return null;
+ }
+ return new Rect(Integer.parseInt(matcher.group(1)),
+ Integer.parseInt(matcher.group(2)),
+ Integer.parseInt(matcher.group(3)),
+ Integer.parseInt(matcher.group(4)));
+ }
/**
* Print short representation to given writer.
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
index 88ef7e4..eb017bf 100644
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ b/libs/surfaceflinger/LayerBuffer.cpp
@@ -266,7 +266,16 @@
: mBufferHeap(buffers)
{
NativeBuffer& src(mNativeBuffer);
- src.img.handle = 0;
+ src.crop.l = 0;
+ src.crop.t = 0;
+ src.crop.r = buffers.w;
+ src.crop.b = buffers.h;
+
+ src.img.w = buffers.hor_stride ?: buffers.w;
+ src.img.h = buffers.ver_stride ?: buffers.h;
+ src.img.format = buffers.format;
+ src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset);
+ src.img.handle = 0;
gralloc_module_t const * module = LayerBuffer::getGrallocModule();
if (module && module->perform) {
@@ -276,19 +285,12 @@
offset, buffers.heap->base(),
&src.img.handle);
- if (err == NO_ERROR) {
- src.crop.l = 0;
- src.crop.t = 0;
- src.crop.r = buffers.w;
- src.crop.b = buffers.h;
-
- src.img.w = buffers.hor_stride ?: buffers.w;
- src.img.h = buffers.ver_stride ?: buffers.h;
- src.img.format = buffers.format;
- src.img.base = (void*)(intptr_t(buffers.heap->base()) + offset);
- }
+ LOGE_IF(err, "CREATE_HANDLE_FROM_BUFFER (heapId=%d, size=%d, "
+ "offset=%ld, base=%p) failed (%s)",
+ buffers.heap->heapID(), buffers.heap->getSize(),
+ offset, buffers.heap->base(), strerror(-err));
}
-}
+ }
LayerBuffer::Buffer::~Buffer()
{
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 6cd4b92..c49ad5c 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -22,6 +22,7 @@
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
+import java.util.TimeZone;
/**
* This is a class for reading and writing Exif tags in a JPEG file.
@@ -56,9 +57,12 @@
// Constants used for white balance
public static final int WHITEBALANCE_AUTO = 0;
public static final int WHITEBALANCE_MANUAL = 1;
+ private static SimpleDateFormat sFormatter;
static {
System.loadLibrary("exif");
+ sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
+ sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
}
private String mFilename;
@@ -242,9 +246,6 @@
}
}
- private static SimpleDateFormat sFormatter =
- new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
-
/**
* Returns number of milliseconds since Jan. 1, 1970, midnight GMT.
* Returns -1 if the date time information if not available.
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index b81684b..a4e3601 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -202,7 +202,6 @@
};
// TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround
-/* static */ const uint32_t MediaPlayerService::AudioOutput::kAudioVideoDelayMs = 0;
/* static */ int MediaPlayerService::AudioOutput::mMinBufferCount = 4;
/* static */ bool MediaPlayerService::AudioOutput::mIsOnEmulator = false;
@@ -1485,7 +1484,7 @@
LOGV("setVolume");
t->setVolume(mLeftVolume, mRightVolume);
mMsecsPerFrame = 1.e3 / (float) sampleRate;
- mLatency = t->latency() + kAudioVideoDelayMs;
+ mLatency = t->latency();
mTrack = t;
return NO_ERROR;
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index b00f5b7..1c90cf9 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -108,8 +108,6 @@
float mMsecsPerFrame;
uint32_t mLatency;
- // TODO: Find real cause of Audio/Video delay in PV framework and remove this workaround
- static const uint32_t kAudioVideoDelayMs;
static bool mIsOnEmulator;
static int mMinBufferCount; // 12 for emulator; otherwise 4
diff --git a/opengl/java/android/opengl/GLLogWrapper.java b/opengl/java/android/opengl/GLLogWrapper.java
index 4119bf8..f332448 100644
--- a/opengl/java/android/opengl/GLLogWrapper.java
+++ b/opengl/java/android/opengl/GLLogWrapper.java
@@ -1517,7 +1517,7 @@
arg("count", count);
startLogIndices();
for (int i = 0; i < count; i++) {
- doElement(mStringBuilder, i, first + count);
+ doElement(mStringBuilder, i, first + i);
}
endLogIndices();
end();
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index c2b1b96..2fff54c 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -18,6 +18,8 @@
import android.app.Activity;
import android.app.KeyguardManager;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -27,12 +29,13 @@
import android.os.SystemClock;
import android.os.UEventObserver;
import android.provider.Settings;
+import android.server.BluetoothService;
import android.util.Log;
import com.android.internal.widget.LockPatternUtils;
-import java.io.FileReader;
import java.io.FileNotFoundException;
+import java.io.FileReader;
/**
* <p>DockObserver monitors for a docking station.
@@ -65,7 +68,7 @@
if (getResultCode() != Activity.RESULT_OK) {
return;
}
-
+
// Launch a dock activity
String category;
switch (mDockState) {
@@ -177,7 +180,13 @@
// Pack up the values and broadcast them to everyone
Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
-
+
+ // Check if this is Bluetooth Dock
+ String address = BluetoothService.readDockBluetoothAddress();
+ if (address != null)
+ intent.putExtra(BluetoothDevice.EXTRA_DEVICE,
+ BluetoothAdapter.getDefaultAdapter().getRemoteDevice(address));
+
// Send the ordered broadcast; the result receiver will receive after all
// broadcasts have been sent. If any broadcast receiver changes the result
// code from the initial value of RESULT_OK, then the result receiver will
diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java
index 7c19f24..6f207e0 100644
--- a/services/java/com/android/server/InputDevice.java
+++ b/services/java/com/android/server/InputDevice.java
@@ -313,14 +313,17 @@
long bestDistance = -1;
int bestIndex = -1;
for (int j=0; j<lastNumPointers; j++) {
- if (!allowOverlap && last2Next[j] < 0) {
+ // If we are not allowing multiple new points to be assigned
+ // to the same old pointer, then skip this one if it is already
+ // detected as a conflict (-2).
+ if (!allowOverlap && last2Next[j] < -1) {
continue;
}
final int jd = j * MotionEvent.NUM_SAMPLE_DATA;
final int xd = lastData[jd + MotionEvent.SAMPLE_X] - x1;
final int yd = lastData[jd + MotionEvent.SAMPLE_Y] - y1;
final long distance = xd*(long)xd + yd*(long)yd;
- if (j == 0 || distance < bestDistance) {
+ if (bestDistance == -1 || distance < bestDistance) {
bestDistance = distance;
bestIndex = j;
}
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index cb8cb7f..147580b 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -99,7 +99,11 @@
private NotificationRecord mVibrateNotification;
private Vibrator mVibrator = new Vibrator();
- // adb
+ // for enabling and disabling notification pulse behavior
+ private boolean mScreenOn = true;
+ private boolean mNotificationPulseEnabled;
+
+ // for adb connected notifications
private boolean mUsbConnected;
private boolean mAdbEnabled = false;
private boolean mAdbNotificationShown = false;
@@ -336,6 +340,12 @@
return;
}
cancelAllNotificationsInt(pkgName, 0, 0);
+ } else if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ mScreenOn = true;
+ updateNotificationPulse();
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ mScreenOn = false;
+ updateNotificationPulse();
}
}
};
@@ -349,6 +359,8 @@
ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.ADB_ENABLED), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.NOTIFICATION_LIGHT_PULSE), false, this);
update();
}
@@ -358,13 +370,21 @@
public void update() {
ContentResolver resolver = mContext.getContentResolver();
- mAdbEnabled = Settings.Secure.getInt(resolver,
+ boolean adbEnabled = Settings.Secure.getInt(resolver,
Settings.Secure.ADB_ENABLED, 0) != 0;
- updateAdbNotification();
+ if (mAdbEnabled != adbEnabled) {
+ mAdbEnabled = adbEnabled;
+ updateAdbNotification();
+ }
+ boolean pulseEnabled = Settings.System.getInt(resolver,
+ Settings.System.NOTIFICATION_LIGHT_PULSE, 0) != 0;
+ if (mNotificationPulseEnabled != pulseEnabled) {
+ mNotificationPulseEnabled = pulseEnabled;
+ updateNotificationPulse();
+ }
}
}
- private final SettingsObserver mSettingsObserver;
-
+
NotificationManagerService(Context context, StatusBarService statusBar,
LightsService lights)
{
@@ -399,10 +419,12 @@
filter.addAction(Intent.ACTION_UMS_DISCONNECTED);
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
filter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
mContext.registerReceiver(mIntentReceiver, filter);
- mSettingsObserver = new SettingsObserver(mHandler);
- mSettingsObserver.observe();
+ SettingsObserver observer = new SettingsObserver(mHandler);
+ observer.observe();
}
void systemReady() {
@@ -1005,7 +1027,9 @@
mLedNotification = mLights.get(n-1);
}
}
- if (mLedNotification == null) {
+
+ // we only flash if screen is off and persistent pulsing is enabled
+ if (mLedNotification == null || mScreenOn || !mNotificationPulseEnabled) {
mNotificationLight.turnOff();
} else {
mNotificationLight.setFlashing(
@@ -1097,7 +1121,13 @@
}
}
}
-
+
+ private void updateNotificationPulse() {
+ synchronized (mNotificationList) {
+ updateLightsLocked();
+ }
+ }
+
// ======================================================================
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 8584d74..6e769c7 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -161,7 +161,9 @@
private int[] mBroadcastWhy = new int[3];
private int mPartialCount = 0;
private int mPowerState;
- private boolean mOffBecauseOfUser;
+ // mScreenOffReason can be WindowManagerPolicy.OFF_BECAUSE_OF_USER,
+ // WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT or WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR
+ private int mScreenOffReason;
private int mUserState;
private boolean mKeyboardVisible = false;
private boolean mUserActivityAllowed = true;
@@ -919,7 +921,7 @@
+ " " + ((mNextTimeout-now)/1000) + "s from now");
pw.println(" mDimScreen=" + mDimScreen
+ " mStayOnConditions=" + mStayOnConditions);
- pw.println(" mOffBecauseOfUser=" + mOffBecauseOfUser
+ pw.println(" mScreenOffReason=" + mScreenOffReason
+ " mUserState=" + mUserState);
pw.println(" mBroadcastQueue={" + mBroadcastQueue[0] + ',' + mBroadcastQueue[1]
+ ',' + mBroadcastQueue[2] + "}");
@@ -1384,10 +1386,10 @@
private void setPowerState(int state)
{
- setPowerState(state, false, false);
+ setPowerState(state, false, WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT);
}
- private void setPowerState(int newState, boolean noChangeLights, boolean becauseOfUser)
+ private void setPowerState(int newState, boolean noChangeLights, int reason)
{
synchronized (mLocks) {
int err;
@@ -1395,7 +1397,8 @@
if (mSpew) {
Log.d(TAG, "setPowerState: mPowerState=0x" + Integer.toHexString(mPowerState)
+ " newState=0x" + Integer.toHexString(newState)
- + " noChangeLights=" + noChangeLights);
+ + " noChangeLights=" + noChangeLights
+ + " reason=" + reason);
}
if (noChangeLights) {
@@ -1489,7 +1492,7 @@
mLastTouchDown = 0;
mTotalTouchDownTime = 0;
mTouchCycles = 0;
- EventLog.writeEvent(LOG_POWER_SCREEN_STATE, 1, becauseOfUser ? 1 : 0,
+ EventLog.writeEvent(LOG_POWER_SCREEN_STATE, 1, reason,
mTotalTouchDownTime, mTouchCycles);
if (err == 0) {
mPowerState |= SCREEN_ON_BIT;
@@ -1508,10 +1511,10 @@
Binder.restoreCallingIdentity(identity);
}
mPowerState &= ~SCREEN_ON_BIT;
+ mScreenOffReason = reason;
if (!mScreenBrightness.animating) {
- err = screenOffFinishedAnimatingLocked(becauseOfUser);
+ err = screenOffFinishedAnimatingLocked(reason);
} else {
- mOffBecauseOfUser = becauseOfUser;
err = 0;
mLastTouchDown = 0;
}
@@ -1520,19 +1523,16 @@
}
}
- private int screenOffFinishedAnimatingLocked(boolean becauseOfUser) {
+ private int screenOffFinishedAnimatingLocked(int reason) {
// I don't think we need to check the current state here because all of these
// Power.setScreenState and sendNotificationLocked can both handle being
// called multiple times in the same state. -joeo
- EventLog.writeEvent(LOG_POWER_SCREEN_STATE, 0, becauseOfUser ? 1 : 0,
- mTotalTouchDownTime, mTouchCycles);
+ EventLog.writeEvent(LOG_POWER_SCREEN_STATE, 0, reason, mTotalTouchDownTime, mTouchCycles);
mLastTouchDown = 0;
int err = setScreenStateLocked(false);
if (err == 0) {
- int why = becauseOfUser
- ? WindowManagerPolicy.OFF_BECAUSE_OF_USER
- : WindowManagerPolicy.OFF_BECAUSE_OF_TIMEOUT;
- sendNotificationLocked(false, why);
+ mScreenOffReason = reason;
+ sendNotificationLocked(false, reason);
}
return err;
}
@@ -1808,7 +1808,7 @@
animating = more;
if (!more) {
if (mask == SCREEN_BRIGHT_BIT && curIntValue == Power.BRIGHTNESS_OFF) {
- screenOffFinishedAnimatingLocked(mOffBecauseOfUser);
+ screenOffFinishedAnimatingLocked(mScreenOffReason);
}
}
return more;
@@ -1994,7 +1994,8 @@
}
mWakeLockState = mLocks.reactivateScreenLocksLocked();
- setPowerState(mUserState | mWakeLockState, noChangeLights, true);
+ setPowerState(mUserState | mWakeLockState, noChangeLights,
+ WindowManagerPolicy.OFF_BECAUSE_OF_USER);
setTimeoutLocked(time, SCREEN_BRIGHT);
}
}
@@ -2125,7 +2126,7 @@
{
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
synchronized (mLocks) {
- goToSleepLocked(time);
+ goToSleepLocked(time, WindowManagerPolicy.OFF_BECAUSE_OF_USER);
}
}
@@ -2143,7 +2144,7 @@
}
}
- private void goToSleepLocked(long time) {
+ private void goToSleepLocked(long time, int reason) {
if (mLastEventTime <= time) {
mLastEventTime = time;
@@ -2161,7 +2162,7 @@
EventLog.writeEvent(LOG_POWER_SLEEP_REQUESTED, numCleared);
mStillNeedSleepNotification = true;
mUserState = SCREEN_OFF;
- setPowerState(SCREEN_OFF, false, true);
+ setPowerState(SCREEN_OFF, false, reason);
cancelTimerLocked();
}
}
@@ -2517,7 +2518,8 @@
return;
}
if (active) {
- goToSleepLocked(SystemClock.uptimeMillis());
+ goToSleepLocked(SystemClock.uptimeMillis(),
+ WindowManagerPolicy.OFF_BECAUSE_OF_PROX_SENSOR);
mProximitySensorActive = true;
} else {
// proximity sensor negative events trigger as user activity.
diff --git a/services/java/com/android/server/status/StatusBarService.java b/services/java/com/android/server/status/StatusBarService.java
index 1db20df..a103dcb 100644
--- a/services/java/com/android/server/status/StatusBarService.java
+++ b/services/java/com/android/server/status/StatusBarService.java
@@ -31,6 +31,7 @@
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.PixelFormat;
+import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.IBinder;
@@ -1277,8 +1278,13 @@
ActivityManagerNative.getDefault().resumeAppSwitches();
} catch (RemoteException e) {
}
+ int[] pos = new int[2];
+ v.getLocationOnScreen(pos);
+ Intent overlay = new Intent();
+ overlay.setSourceBounds(
+ new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight()));
try {
- mIntent.send();
+ mIntent.send(mContext, 0, overlay);
mNotificationCallbacks.onNotificationClick(mPkg, mTag, mId);
} catch (PendingIntent.CanceledException e) {
// the stack trace isn't very helpful here. Just log the exception message.
diff --git a/telephony/java/com/android/internal/telephony/MccTable.java b/telephony/java/com/android/internal/telephony/MccTable.java
index c4877cb..e25eb7b 100644
--- a/telephony/java/com/android/internal/telephony/MccTable.java
+++ b/telephony/java/com/android/internal/telephony/MccTable.java
@@ -24,6 +24,7 @@
import android.os.RemoteException;
import android.os.SystemProperties;
import android.provider.Settings;
+import android.text.TextUtils;
import android.util.Log;
import java.util.Arrays;
@@ -573,34 +574,36 @@
* @param mccmnc truncated imsi with just the MCC and MNC - MNC assumed to be from 4th to end
*/
public static void updateMccMncConfiguration(PhoneBase phone, String mccmnc) {
- int mcc, mnc;
+ if (!TextUtils.isEmpty(mccmnc)) {
+ int mcc, mnc;
- try {
- mcc = Integer.parseInt(mccmnc.substring(0,3));
- mnc = Integer.parseInt(mccmnc.substring(3));
- } catch (NumberFormatException e) {
- Log.e(LOG_TAG, "Error parsing IMSI");
- return;
- }
+ try {
+ mcc = Integer.parseInt(mccmnc.substring(0,3));
+ mnc = Integer.parseInt(mccmnc.substring(3));
+ } catch (NumberFormatException e) {
+ Log.e(LOG_TAG, "Error parsing IMSI");
+ return;
+ }
- Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
+ Log.d(LOG_TAG, "updateMccMncConfiguration: mcc=" + mcc + ", mnc=" + mnc);
- if (mcc != 0) {
- setTimezoneFromMccIfNeeded(phone, mcc);
- setLocaleFromMccIfNeeded(phone, mcc);
- setWifiChannelsFromMccIfNeeded(phone, mcc);
- }
- try {
- Configuration config = ActivityManagerNative.getDefault().getConfiguration();
if (mcc != 0) {
- config.mcc = mcc;
+ setTimezoneFromMccIfNeeded(phone, mcc);
+ setLocaleFromMccIfNeeded(phone, mcc);
+ setWifiChannelsFromMccIfNeeded(phone, mcc);
}
- if (mnc != 0) {
- config.mnc = mnc;
+ try {
+ Configuration config = ActivityManagerNative.getDefault().getConfiguration();
+ if (mcc != 0) {
+ config.mcc = mcc;
+ }
+ if (mnc != 0) {
+ config.mnc = mnc;
+ }
+ ActivityManagerNative.getDefault().updateConfiguration(config);
+ } catch (RemoteException e) {
+ Log.e(LOG_TAG, "Can't update configuration", e);
}
- ActivityManagerNative.getDefault().updateConfiguration(config);
- } catch (RemoteException e) {
- Log.e(LOG_TAG, "Can't update configuration", e);
}
}
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index e47f799..279f57f 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2191,6 +2191,7 @@
case RIL_REQUEST_SET_SMSC_ADDRESS: ret = responseVoid(p); break;
case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE: ret = responseVoid(p); break;
case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS: ret = responseVoid(p); break;
+ case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING: ret = responseVoid(p); break;
default:
throw new RuntimeException("Unrecognized solicited response: " + rr.mRequest);
//break;
diff --git a/telephony/java/com/android/internal/telephony/WapPushOverSms.java b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
index 99709406..a636a4b 100644
--- a/telephony/java/com/android/internal/telephony/WapPushOverSms.java
+++ b/telephony/java/com/android/internal/telephony/WapPushOverSms.java
@@ -109,6 +109,7 @@
String mimeType = pduDecoder.getValueString();
if (mimeType == null) {
binaryContentType = (int)pduDecoder.getValue32();
+ // TODO we should have more generic way to map binaryContentType code to mimeType.
switch (binaryContentType) {
case WspTypeDecoder.CONTENT_TYPE_B_DRM_RIGHTS_XML:
mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML;
@@ -128,6 +129,9 @@
case WspTypeDecoder.CONTENT_TYPE_B_MMS:
mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS;
break;
+ case WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF:
+ mimeType = WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF;
+ break;
default:
if (Config.LOGD) {
Log.w(LOG_TAG,
@@ -148,6 +152,8 @@
binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO;
} else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS)) {
binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_MMS;
+ } else if (mimeType.equals(WspTypeDecoder.CONTENT_MIME_TYPE_B_VND_DOCOMO_PF)) {
+ binaryContentType = WspTypeDecoder.CONTENT_TYPE_B_VND_DOCOMO_PF;
} else {
if (Config.LOGD) Log.w(LOG_TAG, "Received PDU. Unknown Content-Type = " + mimeType);
return Intents.RESULT_SMS_HANDLED;
@@ -155,28 +161,31 @@
}
index += pduDecoder.getDecodedDataLength();
- int dataIndex = headerStartIndex + headerLength;
boolean dispatchedByApplication = false;
switch (binaryContentType) {
case WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO:
- dispatchWapPdu_PushCO(pdu, transactionId, pduType);
+ dispatchWapPdu_PushCO(pdu, transactionId, pduType, headerStartIndex, headerLength);
dispatchedByApplication = true;
break;
case WspTypeDecoder.CONTENT_TYPE_B_MMS:
- dispatchWapPdu_MMS(pdu, transactionId, pduType, dataIndex);
+ dispatchWapPdu_MMS(pdu, transactionId, pduType, headerStartIndex, headerLength);
dispatchedByApplication = true;
break;
default:
break;
}
if (dispatchedByApplication == false) {
- dispatchWapPdu_default(pdu, transactionId, pduType, mimeType, dataIndex);
+ dispatchWapPdu_default(pdu, transactionId, pduType, mimeType,
+ headerStartIndex, headerLength);
}
return Activity.RESULT_OK;
}
- private void dispatchWapPdu_default(
- byte[] pdu, int transactionId, int pduType, String mimeType, int dataIndex) {
+ private void dispatchWapPdu_default(byte[] pdu, int transactionId, int pduType,
+ String mimeType, int headerStartIndex, int headerLength) {
+ byte[] header = new byte[headerLength];
+ System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
+ int dataIndex = headerStartIndex + headerLength;
byte[] data;
data = new byte[pdu.length - dataIndex];
@@ -186,31 +195,40 @@
intent.setType(mimeType);
intent.putExtra("transactionId", transactionId);
intent.putExtra("pduType", pduType);
+ intent.putExtra("header", header);
intent.putExtra("data", data);
mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
}
- private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType) {
+ private void dispatchWapPdu_PushCO(byte[] pdu, int transactionId, int pduType,
+ int headerStartIndex, int headerLength) {
+ byte[] header = new byte[headerLength];
+ System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
+
Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_PUSH_CO);
intent.putExtra("transactionId", transactionId);
intent.putExtra("pduType", pduType);
+ intent.putExtra("header", header);
intent.putExtra("data", pdu);
mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_WAP_PUSH");
}
- private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType, int dataIndex) {
- byte[] data;
-
- data = new byte[pdu.length - dataIndex];
+ private void dispatchWapPdu_MMS(byte[] pdu, int transactionId, int pduType,
+ int headerStartIndex, int headerLength) {
+ byte[] header = new byte[headerLength];
+ System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
+ int dataIndex = headerStartIndex + headerLength;
+ byte[] data = new byte[pdu.length - dataIndex];
System.arraycopy(pdu, dataIndex, data, 0, data.length);
Intent intent = new Intent(Intents.WAP_PUSH_RECEIVED_ACTION);
intent.setType(WspTypeDecoder.CONTENT_MIME_TYPE_B_MMS);
intent.putExtra("transactionId", transactionId);
intent.putExtra("pduType", pduType);
+ intent.putExtra("header", header);
intent.putExtra("data", data);
mSmsDispatcher.dispatch(intent, "android.permission.RECEIVE_MMS");
diff --git a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
index 3bbe0e1..336bc82 100644
--- a/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
+++ b/telephony/java/com/android/internal/telephony/WspTypeDecoder.java
@@ -30,12 +30,16 @@
public static final int PDU_TYPE_PUSH = 0x06;
public static final int PDU_TYPE_CONFIRMED_PUSH = 0x07;
+ // TODO we should have mapping between those binary code and mime type string.
+ // see http://www.openmobilealliance.org/tech/omna/omna-wsp-content-type.aspx
+
public static final int CONTENT_TYPE_B_DRM_RIGHTS_XML = 0x4a;
public static final int CONTENT_TYPE_B_DRM_RIGHTS_WBXML = 0x4b;
public static final int CONTENT_TYPE_B_PUSH_SI = 0x2e;
public static final int CONTENT_TYPE_B_PUSH_SL = 0x30;
public static final int CONTENT_TYPE_B_PUSH_CO = 0x32;
public static final int CONTENT_TYPE_B_MMS = 0x3e;
+ public static final int CONTENT_TYPE_B_VND_DOCOMO_PF = 0x0310;
public static final String CONTENT_MIME_TYPE_B_DRM_RIGHTS_XML =
"application/vnd.oma.drm.rights+xml";
@@ -45,6 +49,7 @@
public static final String CONTENT_MIME_TYPE_B_PUSH_SL = "application/vnd.wap.slc";
public static final String CONTENT_MIME_TYPE_B_PUSH_CO = "application/vnd.wap.coc";
public static final String CONTENT_MIME_TYPE_B_MMS = "application/vnd.wap.mms-message";
+ public static final String CONTENT_MIME_TYPE_B_VND_DOCOMO_PF = "application/vnd.docomo.pf";
public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
index 04a03b2..422cc19 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CDMAPhone.java
@@ -202,10 +202,6 @@
// Sets current entry in the telephony carrier table
updateCurrentCarrierInProvider(operatorNumeric);
- // Updates MCC MNC device configuration information
- MccTable.updateMccMncConfiguration(this, operatorNumeric);
-
-
// Notify voicemails.
notifier.notifyMessageWaitingChanged(this);
}
@@ -1401,20 +1397,22 @@
}
/**
- * Sets the "current" field in the telephony provider according to the build-time
- * operator numeric property
+ * Sets the "current" field in the telephony provider according to the
+ * build-time operator numeric property
*
* @return true for success; false otherwise.
*/
- // TODO(Moto): move this method into PhoneBase, since it looks identical to
- // the one in GsmPhone
- private boolean updateCurrentCarrierInProvider(String operatorNumeric) {
+ boolean updateCurrentCarrierInProvider(String operatorNumeric) {
if (!TextUtils.isEmpty(operatorNumeric)) {
try {
Uri uri = Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current");
ContentValues map = new ContentValues();
map.put(Telephony.Carriers.NUMERIC, operatorNumeric);
getContext().getContentResolver().insert(uri, map);
+
+ // Updates MCC MNC device configuration information
+ MccTable.updateMccMncConfiguration(this, operatorNumeric);
+
return true;
} catch (SQLException e) {
Log.e(LOG_TAG, "Can't store current operator", e);
diff --git a/tests/DumpRenderTree/assets/run_page_cycler.py b/tests/DumpRenderTree/assets/run_page_cycler.py
index 7dd4a88..8b8fb38 100755
--- a/tests/DumpRenderTree/assets/run_page_cycler.py
+++ b/tests/DumpRenderTree/assets/run_page_cycler.py
@@ -20,7 +20,7 @@
def main(options, args):
"""Run the tests. Will call sys.exit when complete.
-
+
"""
# Set up logging format.
@@ -56,7 +56,15 @@
run_load_test_cmd_postfix = " -w com.android.dumprendertree/.LayoutTestsAutoRunner"
# Call LoadTestsAutoTest::runTest.
- run_load_test_cmd = run_load_test_cmd_prefix + " -e class com.android.dumprendertree.LoadTestsAutoTest#runPageCyclerTest -e path \"" + path + "\" -e timeout " + timeout_ms + run_load_test_cmd_postfix
+ run_load_test_cmd = run_load_test_cmd_prefix + " -e class com.android.dumprendertree.LoadTestsAutoTest#runPageCyclerTest -e path \"" + path + "\" -e timeout " + timeout_ms
+
+ if options.drawtime:
+ run_load_test_cmd += " -e drawtime true "
+
+ if options.save_image:
+ run_load_test_cmd += " -e saveimage \"%s\"" % options.save_image
+
+ run_load_test_cmd += run_load_test_cmd_postfix
(adb_output, adb_error) = subprocess.Popen(run_load_test_cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
fail_flag = False
@@ -101,18 +109,26 @@
if '__main__' == __name__:
option_parser = optparse.OptionParser()
- option_parser.add_option("", "--time-out-ms",
+ option_parser.add_option("-t", "--time-out-ms",
default=None,
help="set the timeout for each test")
- option_parser.add_option("", "--verbose", action="store_true",
+ option_parser.add_option("-v", "--verbose", action="store_true",
default=False,
help="include debug-level logging")
- option_parser.add_option("", "--adb-options",
+ option_parser.add_option("-a", "--adb-options",
default=None,
help="pass options to adb, such as -d -e, etc");
- option_parser.add_option("", "--results-directory",
+ option_parser.add_option("-r", "--results-directory",
default="layout-test-results",
help="directory which results are stored.")
+ option_parser.add_option("-d", "--drawtime", action="store_true",
+ default=False,
+ help="log draw time for each page rendered.")
+
+ option_parser.add_option("-s", "--save-image",
+ default=None,
+ help="stores rendered page to a location on device.")
+
options, args = option_parser.parse_args();
main(options, args)
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
index fea366c..1a265e8 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FsUtils.java
@@ -25,6 +25,7 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
+import java.io.FileWriter;
import java.io.IOException;
import java.util.regex.Pattern;
@@ -156,4 +157,43 @@
return same;
}
+ public static boolean isTestPageUrl(String url) {
+ int qmPostion = url.indexOf('?');
+ int slashPostion = url.lastIndexOf('/');
+ if (slashPostion < qmPostion) {
+ String fileName = url.substring(slashPostion + 1, qmPostion);
+ if ("index.html".equals(fileName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static String getLastSegmentInPath(String path) {
+ int endPos = path.lastIndexOf('/');
+ path = path.substring(0, endPos);
+ endPos = path.lastIndexOf('/');
+ return path.substring(endPos + 1);
+ }
+
+ public static void writeDrawTime(String fileName, String url, long[] times) {
+ StringBuffer lineBuffer = new StringBuffer();
+ // grab the last segment of path in url
+ lineBuffer.append(getLastSegmentInPath(url));
+ for (long time : times) {
+ lineBuffer.append('\t');
+ lineBuffer.append(time);
+ }
+ lineBuffer.append('\n');
+ String line = lineBuffer.toString();
+ Log.v(LOGTAG, "logging draw times: " + line);
+ try {
+ FileWriter fw = new FileWriter(fileName, true);
+ fw.write(line);
+ fw.close();
+ } catch (IOException ioe) {
+ Log.e(LOGTAG, "Failed to log draw times", ioe);
+ }
+ }
+
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
index 283b98c..539d551 100755
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LayoutTestsAutoRunner.java
@@ -73,13 +73,20 @@
this.mLogtime = (logtime != null
&& logtime.toLowerCase().equals("true"));
+ String drawTime = (String) icicle.get("drawtime");
+ this.mGetDrawTime = (drawTime != null
+ && drawTime.toLowerCase().equals("true"));
+
+ mSaveImagePath = (String) icicle.get("saveimage");
+
super.onCreate(icicle);
}
public String mTestPath = null;
+ public String mSaveImagePath = null;
public int mTimeoutInMillis = 0;
public int mDelay = 0;
public boolean mRebaseline = false;
public boolean mLogtime = false;
+ public boolean mGetDrawTime = false;
}
-
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
index ba46197..2ef342f 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/LoadTestsAutoTest.java
@@ -70,7 +70,8 @@
freeMem();
// Run tests
- runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis);
+ runTestAndWaitUntilDone(activity, runner.mTestPath, runner.mTimeoutInMillis,
+ runner.mGetDrawTime, runner.mSaveImagePath);
activity.clearCache();
try {
@@ -161,7 +162,8 @@
}
// A convenient method to be called by another activity.
- private void runTestAndWaitUntilDone(TestShellActivity activity, String url, int timeout) {
+ private void runTestAndWaitUntilDone(TestShellActivity activity, String url, int timeout,
+ boolean getDrawTime, String saveImagePath) {
activity.setCallback(new TestShellCallback() {
public void finished() {
synchronized (LoadTestsAutoTest.this) {
@@ -181,6 +183,9 @@
intent.putExtra(TestShellActivity.TEST_URL, url);
intent.putExtra(TestShellActivity.TIMEOUT_IN_MILLIS, timeout);
intent.putExtra(TestShellActivity.RESULT_FILE, LOAD_TEST_RESULT);
+ intent.putExtra(TestShellActivity.GET_DRAW_TIME, getDrawTime);
+ if (saveImagePath != null)
+ intent.putExtra(TestShellActivity.SAVE_IMAGE, saveImagePath);
activity.startActivity(intent);
// Wait until done.
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index aeb55b4..b6b1661 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -25,6 +25,9 @@
import android.content.Intent;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Bitmap.CompressFormat;
+import android.graphics.Bitmap.Config;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Handler;
@@ -163,6 +166,8 @@
mResultFile = intent.getStringExtra(RESULT_FILE);
mTimeoutInMillis = intent.getIntExtra(TIMEOUT_IN_MILLIS, 0);
+ mGetDrawtime = intent.getBooleanExtra(GET_DRAW_TIME, false);
+ mSaveImagePath = intent.getStringExtra(SAVE_IMAGE);
Log.v(LOGTAG, " Loading " + mTestUrl);
mWebView.loadUrl(mTestUrl);
@@ -459,6 +464,18 @@
public void onPageFinished(WebView view, String url) {
Log.v(LOGTAG, "onPageFinished, url=" + url);
mPageFinished = true;
+ // get page draw time
+ if (FsUtils.isTestPageUrl(url)) {
+ if (mGetDrawtime) {
+ long[] times = new long[DRAW_RUNS];
+ times = getDrawWebViewTime(mWebView, DRAW_RUNS);
+ FsUtils.writeDrawTime(DRAW_TIME_LOG, url, times);
+ }
+ if (mSaveImagePath != null) {
+ String name = FsUtils.getLastSegmentInPath(url);
+ drawPageToFile(mSaveImagePath + "/" + name + ".png", mWebView);
+ }
+ }
// Calling finished() will check if we've met all the conditions for completing
// this test and move to the next one if we are ready.
if (finished()) {
@@ -691,6 +708,41 @@
mPageFinished = false;
mOneHundredPercentComplete = false;
mDumpWebKitData = false;
+ mGetDrawtime = false;
+ mSaveImagePath = null;
+ }
+
+ private long[] getDrawWebViewTime(WebView view, int count) {
+ if (count == 0)
+ return null;
+ long[] ret = new long[count];
+ long start;
+ Canvas canvas = new Canvas();
+ Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Config.ARGB_8888);
+ canvas.setBitmap(bitmap);
+ for (int i = 0; i < count; i++) {
+ start = System.currentTimeMillis();
+ view.draw(canvas);
+ ret[i] = System.currentTimeMillis() - start;
+ }
+ return ret;
+ }
+
+ private void drawPageToFile(String fileName, WebView view) {
+ Canvas canvas = new Canvas();
+ Bitmap bitmap = Bitmap.createBitmap(view.getContentWidth(), view.getContentHeight(),
+ Config.ARGB_8888);
+ canvas.setBitmap(bitmap);
+ view.drawPage(canvas);
+ try {
+ FileOutputStream fos = new FileOutputStream(fileName);
+ if(!bitmap.compress(CompressFormat.PNG, 90, fos)) {
+ Log.w(LOGTAG, "Failed to compress and save image.");
+ }
+ } catch (IOException ioe) {
+ Log.e(LOGTAG, "", ioe);
+ }
+ bitmap.recycle();
}
private boolean canMoveToNextTest() {
@@ -730,7 +782,9 @@
private String mResultFile;
private int mTimeoutInMillis;
private String mUiAutoTestPath;
+ private String mSaveImagePath;
private BufferedReader mTestListReader;
+ private boolean mGetDrawtime;
// States
private boolean mTimedOut;
@@ -766,6 +820,11 @@
static final String RESULT_FILE = "ResultFile";
static final String TIMEOUT_IN_MILLIS = "TimeoutInMillis";
static final String UI_AUTO_TEST = "UiAutoTest";
+ static final String GET_DRAW_TIME = "GetDrawTime";
+ static final String SAVE_IMAGE = "SaveImage";
+
+ static final int DRAW_RUNS = 5;
+ static final String DRAW_TIME_LOG = "/sdcard/android/page_draw_time.txt";
private boolean mGeolocationPermissionSet;
private boolean mGeolocationPermission;
diff --git a/tests/backup/test_backup.sh b/tests/backup/test_backup.sh
index 10b809d..113a26d 100755
--- a/tests/backup/test_backup.sh
+++ b/tests/backup/test_backup.sh
@@ -18,10 +18,12 @@
#export DRY_RUN="echo"
source test_backup_common.sh
-# wipe prior backup data for packages
+# figure out what packages are participating in backup
b_pkgs=$(a shell dumpsys backup | \
- ruby -ne 'print($1+" ") if $_ =~ /^\s*ApplicationInfo\S+ (.+?)\}/')
+ ruby -e 'p_stanza = STDIN.read.match(/Participants:.*?(?=Ever)/m)[0]
+ puts p_stanza.scan(/^ (.+?)\s*$/).flatten.join(" ")')
+# wipe data for the package participating in backup
for pkg in $b_pkgs; do
a shell bmgr wipe "$pkg"
done
@@ -36,7 +38,7 @@
set -x
# set the transport
-a shell bmgr transport com.google.android.backup/.BackupTransportService
+#a shell bmgr transport com.google.android.backup/.BackupTransportService
# load up the three files
a shell \
diff --git a/tests/backup/test_restore.sh b/tests/backup/test_restore.sh
index 46b46e4..48e5c66 100755
--- a/tests/backup/test_restore.sh
+++ b/tests/backup/test_restore.sh
@@ -45,7 +45,7 @@
fi
}
-# run adb as root so we can poke at com.android.backuptest's data
+# Make sure adb is root so we can poke at com.android.backuptest's data
adb_root
# delete the old data