Merge change 25853 into eclair
* changes:
Don't back up / restore certain sync-related settings
diff --git a/api/current.xml b/api/current.xml
index b38176d..0495764 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -7841,6 +7841,28 @@
visibility="public"
>
</field>
+<field name="textAppearanceSearchResultSubtitle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843424"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="textAppearanceSearchResultTitle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843425"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="textAppearanceSmall"
type="int"
transient="false"
@@ -31692,6 +31714,29 @@
<parameter name="intent" type="android.content.Intent">
</parameter>
</method>
+<method name="sendStickyOrderedBroadcast"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultReceiver" type="android.content.BroadcastReceiver">
+</parameter>
+<parameter name="scheduler" type="android.os.Handler">
+</parameter>
+<parameter name="initialCode" type="int">
+</parameter>
+<parameter name="initialData" type="java.lang.String">
+</parameter>
+<parameter name="initialExtras" type="android.os.Bundle">
+</parameter>
+</method>
<method name="setTheme"
return="void"
abstract="true"
@@ -33028,6 +33073,29 @@
<parameter name="intent" type="android.content.Intent">
</parameter>
</method>
+<method name="sendStickyOrderedBroadcast"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultReceiver" type="android.content.BroadcastReceiver">
+</parameter>
+<parameter name="scheduler" type="android.os.Handler">
+</parameter>
+<parameter name="initialCode" type="int">
+</parameter>
+<parameter name="initialData" type="java.lang.String">
+</parameter>
+<parameter name="initialExtras" type="android.os.Bundle">
+</parameter>
+</method>
<method name="setTheme"
return="void"
abstract="false"
@@ -35761,17 +35829,6 @@
visibility="public"
>
</field>
-<field name="ACTION_REMOTE_INTENT"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""android.intent.action.REMOTE_INTENT""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="ACTION_RUN"
type="java.lang.String"
transient="false"
@@ -98695,6 +98752,116 @@
visibility="public"
>
</field>
+<field name="EXTRA_HEALTH"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""health""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ICON_SMALL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""icon-small""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_LEVEL"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""level""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PLUGGED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""plugged""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_PRESENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""present""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_SCALE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""scale""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_STATUS"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""status""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_TECHNOLOGY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""technology""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_TEMPERATURE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""temperature""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_VOLTAGE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""voltage""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="Binder"
extends="java.lang.Object"
@@ -126684,6 +126851,29 @@
<parameter name="intent" type="android.content.Intent">
</parameter>
</method>
+<method name="sendStickyOrderedBroadcast"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.content.Intent">
+</parameter>
+<parameter name="resultReceiver" type="android.content.BroadcastReceiver">
+</parameter>
+<parameter name="scheduler" type="android.os.Handler">
+</parameter>
+<parameter name="initialCode" type="int">
+</parameter>
+<parameter name="initialData" type="java.lang.String">
+</parameter>
+<parameter name="initialExtras" type="android.os.Bundle">
+</parameter>
+</method>
<method name="setTheme"
return="void"
abstract="false"
diff --git a/core/java/android/app/ApplicationContext.java b/core/java/android/app/ApplicationContext.java
index dc8d873..afafe64 100644
--- a/core/java/android/app/ApplicationContext.java
+++ b/core/java/android/app/ApplicationContext.java
@@ -659,6 +659,38 @@
}
@Override
+ public void sendStickyOrderedBroadcast(Intent intent,
+ BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData,
+ Bundle initialExtras) {
+ IIntentReceiver rd = null;
+ if (resultReceiver != null) {
+ if (mPackageInfo != null) {
+ if (scheduler == null) {
+ scheduler = mMainThread.getHandler();
+ }
+ rd = mPackageInfo.getReceiverDispatcher(
+ resultReceiver, getOuterContext(), scheduler,
+ mMainThread.getInstrumentation(), false);
+ } else {
+ if (scheduler == null) {
+ scheduler = mMainThread.getHandler();
+ }
+ rd = new ActivityThread.PackageInfo.ReceiverDispatcher(
+ resultReceiver, getOuterContext(), scheduler, null, false).getIIntentReceiver();
+ }
+ }
+ String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ try {
+ ActivityManagerNative.getDefault().broadcastIntent(
+ mMainThread.getApplicationThread(), intent, resolvedType, rd,
+ initialCode, initialData, initialExtras, null,
+ true, true);
+ } catch (RemoteException e) {
+ }
+ }
+
+ @Override
public void removeStickyBroadcast(Intent intent) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
if (resolvedType != null) {
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index f81ba73..b52a822 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -28,6 +28,7 @@
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.util.UUID;
/**
* Represents a remote Bluetooth device.
@@ -226,6 +227,20 @@
public static final String EXTRA_PASSKEY = "android.bluetooth.device.extra.PASSKEY";
/**
+ * Broadcast Action: This intent is used to broadcast the {@link UUID}
+ * wrapped as a {@link ParcelUuid} of the remote device after it has been
+ * fetched. This intent is sent only when the UUIDs of the remote device
+ * are requested to be fetched using Service Discovery Protocol
+ * <p> Always contains the extra field {@link #EXTRA_DEVICE}
+ * <p> Always contains the extra filed {@link #EXTRA_UUID}
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_UUID =
+ "android.bleutooth.device.action.UUID";
+
+ /**
* Broadcast Action: Indicates a failure to retrieve the name of a remote
* device.
* <p>Always contains the extra field {@link #EXTRA_DEVICE}.
@@ -292,6 +307,15 @@
* @hide */
public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
+ /**
+ * Used as an extra field in {@link #ACTION_UUID} intents,
+ * Contains the {@link ParcelUuid}s of the remote device which is a parcelable
+ * version of {@link UUID}.
+ * @hide
+ */
+ public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
+
+
private static IBluetooth sService; /* Guarenteed constant after first object constructed */
private final String mAddress;
@@ -507,6 +531,27 @@
return null;
}
+ /**
+ * Perform a SDP query on the remote device to get the UUIDs
+ * supported. This API is asynchronous and an Intent is sent,
+ * with the UUIDs supported by the remote end. If there is an error
+ * in getting the SDP records or if the process takes a long time,
+ * an Intent is sent with the UUIDs that is currently present in the
+ * cache. Clients should use the {@link getUuids} to get UUIDs
+ * is SDP is not to be performed.
+ *
+ * @return False if the sanity check fails, True if the process
+ * of initiating an ACL connection to the remote device
+ * was started.
+ * @hide
+ */
+ public boolean fetchUuidsWithSdp() {
+ try {
+ return sService.fetchRemoteUuidsWithSdp(mAddress);
+ } catch (RemoteException e) {Log.e(TAG, "", e);}
+ return false;
+ }
+
/** @hide */
public int getServiceChannel(ParcelUuid uuid) {
try {
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index 04c8ec9..203a61d 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -53,6 +53,7 @@
String getRemoteName(in String address);
int getRemoteClass(in String address);
ParcelUuid[] getRemoteUuids(in String address);
+ boolean fetchRemoteUuidsWithSdp(in String address);
int getRemoteServiceChannel(in String address,in ParcelUuid uuid);
boolean setPin(in String address, in byte[] pin);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index a3c4f9a..fe4665e 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -657,8 +657,7 @@
* supplying your own BroadcastReceiver when calling, which will be
* treated as a final receiver at the end of the broadcast -- its
* {@link BroadcastReceiver#onReceive} method will be called with
- * the result values collected from the other receivers. If you use
- * an <var>resultReceiver</var> with this method, then the broadcast will
+ * the result values collected from the other receivers. The broadcast will
* be serialized in the same way as calling
* {@link #sendOrderedBroadcast(Intent, String)}.
*
@@ -689,6 +688,7 @@
* @see #sendBroadcast(Intent, String)
* @see #sendOrderedBroadcast(Intent, String)
* @see #sendStickyBroadcast(Intent)
+ * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
* @see android.content.BroadcastReceiver
* @see #registerReceiver
* @see android.app.Activity#RESULT_OK
@@ -715,8 +715,55 @@
* be re-broadcast to future receivers.
*
* @see #sendBroadcast(Intent)
+ * @see #sendStickyOrderedBroadcast(Intent, BroadcastReceiver, Handler, int, String, Bundle)
*/
public abstract void sendStickyBroadcast(Intent intent);
+
+ /**
+ * Version of {@link #sendStickyBroadcast} that allows you to
+ * receive data back from the broadcast. This is accomplished by
+ * supplying your own BroadcastReceiver when calling, which will be
+ * treated as a final receiver at the end of the broadcast -- its
+ * {@link BroadcastReceiver#onReceive} method will be called with
+ * the result values collected from the other receivers. The broadcast will
+ * be serialized in the same way as calling
+ * {@link #sendOrderedBroadcast(Intent, String)}.
+ *
+ * <p>Like {@link #sendBroadcast(Intent)}, this method is
+ * asynchronous; it will return before
+ * resultReceiver.onReceive() is called. Note that the sticky data
+ * stored is only the data you initially supply to the broadcast, not
+ * the result of any changes made by the receivers.
+ *
+ * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
+ *
+ * @param intent The Intent to broadcast; all receivers matching this
+ * Intent will receive the broadcast.
+ * @param resultReceiver Your own BroadcastReceiver to treat as the final
+ * receiver of the broadcast.
+ * @param scheduler A custom Handler with which to schedule the
+ * resultReceiver callback; if null it will be
+ * scheduled in the Context's main thread.
+ * @param initialCode An initial value for the result code. Often
+ * Activity.RESULT_OK.
+ * @param initialData An initial value for the result data. Often
+ * null.
+ * @param initialExtras An initial value for the result extras. Often
+ * null.
+ *
+ * @see #sendBroadcast(Intent)
+ * @see #sendBroadcast(Intent, String)
+ * @see #sendOrderedBroadcast(Intent, String)
+ * @see #sendStickyBroadcast(Intent)
+ * @see android.content.BroadcastReceiver
+ * @see #registerReceiver
+ * @see android.app.Activity#RESULT_OK
+ */
+ public abstract void sendStickyOrderedBroadcast(Intent intent,
+ BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData,
+ Bundle initialExtras);
+
/**
* Remove the data previously sent with {@link #sendStickyBroadcast},
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index d580c47..1b34320 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -288,6 +288,16 @@
}
@Override
+ public void sendStickyOrderedBroadcast(
+ Intent intent, BroadcastReceiver resultReceiver,
+ Handler scheduler, int initialCode, String initialData,
+ Bundle initialExtras) {
+ mBase.sendStickyOrderedBroadcast(intent,
+ resultReceiver, scheduler, initialCode,
+ initialData, initialExtras);
+ }
+
+ @Override
public void removeStickyBroadcast(Intent intent) {
mBase.removeStickyBroadcast(intent);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 1359761..c1b9f28 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1352,14 +1352,20 @@
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String ACTION_CONFIGURATION_CHANGED = "android.intent.action.CONFIGURATION_CHANGED";
/**
- * Broadcast Action: The charging state, or charge level of the battery has
- * changed.
+ * Broadcast Action: This is a <em>sticky broadcast</em> containing the
+ * charging state, level, and other information about the battery.
+ * See {@link android.os.BatteryManager} for documentation on the
+ * contents of the Intent.
*
* <p class="note">
* You can <em>not</em> receive this through components declared
* in manifests, only by explicitly registering for it with
* {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
- * Context.registerReceiver()}.
+ * Context.registerReceiver()}. See {@link #ACTION_BATTERY_LOW},
+ * {@link #ACTION_BATTERY_OKAY}, {@link #ACTION_POWER_CONNECTED},
+ * and {@link #ACTION_POWER_DISCONNECTED} for distinct battery-related
+ * broadcasts that are sent and can be received through manifest
+ * receivers.
*
* <p class="note">This is a protected intent that can only be sent
* by the system.
@@ -1434,7 +1440,8 @@
*/
public static final String ACTION_REQUEST_SHUTDOWN = "android.intent.action.ACTION_REQUEST_SHUTDOWN";
/**
- * Broadcast Action: Indicates low memory condition on the device
+ * Broadcast Action: A sticky broadcast that indicates low memory
+ * condition on the device
*
* <p class="note">This is a protected intent that can only be sent
* by the system.
@@ -1711,6 +1718,18 @@
"android.intent.action.REBOOT";
/**
+ * Broadcast Action: A sticky broadcast indicating the phone was docked
+ * or undocked. Includes the extra
+ * field {@link #EXTRA_DOCK_STATE}, containing the current dock state.
+ * This is intended for monitoring the current dock state.
+ * To launch an activity from a dock state change, use {@link #CATEGORY_CAR_DOCK}
+ * or {@link #CATEGORY_DESK_DOCK} instead.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_DOCK_EVENT =
+ "android.intent.action.DOCK_EVENT";
+
+ /**
* Broadcast Action: a remote intent is to be broadcasted.
*
* A remote intent is used for remote RPC between devices. The remote intent
@@ -1720,6 +1739,7 @@
* does not trust intent broadcasts from arbitrary intent senders, it should require
* the sender to hold certain permissions so only trusted sender's broadcast will be
* let through.
+ * @hide
*/
public static final String ACTION_REMOTE_INTENT =
"android.intent.action.REMOTE_INTENT";
@@ -1878,16 +1898,6 @@
@SdkConstant(SdkConstantType.INTENT_CATEGORY)
public static final String CATEGORY_DESK_DOCK = "android.intent.category.DESK_DOCK";
- /**
- * Broadcast Action: The phone was docked or undocked. Includes the extra
- * field {@link #EXTRA_DOCK_STATE}, containing the current dock state.
- * This is intended for monitoring the current dock state.
- * To launch an activity from a dock state change, use {@link #CATEGORY_CAR_DOCK}
- * or {@link #CATEGORY_DESK_DOCK} instead.
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_DOCK_EVENT = "android.intent.action.DOCK_EVENT";
-
// ---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Standard extra data keys.
diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java
index 8f1a756..44b73c5 100644
--- a/core/java/android/os/BatteryManager.java
+++ b/core/java/android/os/BatteryManager.java
@@ -18,10 +18,73 @@
/**
* The BatteryManager class contains strings and constants used for values
- * in the ACTION_BATTERY_CHANGED Intent.
+ * in the {@link android.content.Intent#ACTION_BATTERY_CHANGED} Intent.
*/
public class BatteryManager {
-
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the current status constant.
+ */
+ public static final String EXTRA_STATUS = "status";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the current health constant.
+ */
+ public static final String EXTRA_HEALTH = "health";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * boolean indicating whether a battery is present.
+ */
+ public static final String EXTRA_PRESENT = "present";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer field containing the current battery level, from 0 to
+ * {@link #EXTRA_SCALE}.
+ */
+ public static final String EXTRA_LEVEL = "level";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the maximum battery level.
+ */
+ public static final String EXTRA_SCALE = "scale";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the resource ID of a small status bar icon
+ * indicating the current battery state.
+ */
+ public static final String EXTRA_ICON_SMALL = "icon-small";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer indicating whether the device is plugged in to a power
+ * source; 0 means it is on battery, other constants are different
+ * types of power sources.
+ */
+ public static final String EXTRA_PLUGGED = "plugged";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the current battery voltage level.
+ */
+ public static final String EXTRA_VOLTAGE = "voltage";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * integer containing the current battery temperature.
+ */
+ public static final String EXTRA_TEMPERATURE = "temperature";
+
+ /**
+ * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}:
+ * String describing the technology of the current battery.
+ */
+ public static final String EXTRA_TECHNOLOGY = "technology";
+
// values for "status" field in the ACTION_BATTERY_CHANGED Intent
public static final int BATTERY_STATUS_UNKNOWN = 1;
public static final int BATTERY_STATUS_CHARGING = 2;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 93ee3ba..0e72aaf 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -677,12 +677,20 @@
}
/**
+ * Combines all columns returned by {@link Data} table queries.
+ */
+ private interface DataColumnsWithJoins extends BaseColumns, DataColumns, RawContactsColumns,
+ ContactsColumns, ContactOptionsColumns {
+
+ }
+
+ /**
* Constants for the data table, which contains data points tied to a raw contact.
* For example, a phone number or email address. Each row in this table contains a type
* definition and some generic columns. Each data type can define the meaning for each of
* the generic columns.
*/
- public static final class Data implements BaseColumns, DataColumns {
+ public final static class Data implements DataColumnsWithJoins {
/**
* This utility class cannot be instantiated
*/
@@ -950,7 +958,7 @@
/**
* Parts of the name.
*/
- public static final class StructuredName implements BaseCommonColumns {
+ public static final class StructuredName implements DataColumnsWithJoins {
private StructuredName() {}
/** MIME type used when storing this in data table. */
@@ -1016,7 +1024,7 @@
/**
* A nickname.
*/
- public static final class Nickname implements CommonColumns, BaseCommonColumns {
+ public static final class Nickname implements DataColumnsWithJoins, CommonColumns {
private Nickname() {}
/** MIME type used when storing this in data table. */
@@ -1037,7 +1045,7 @@
/**
* Common data definition for telephone numbers.
*/
- public static final class Phone implements BaseCommonColumns, CommonColumns {
+ public static final class Phone implements DataColumnsWithJoins, CommonColumns {
private Phone() {}
/** MIME type used when storing this in data table. */
@@ -1123,13 +1131,18 @@
/**
* Common data definition for email addresses.
*/
- public static final class Email implements BaseCommonColumns, CommonColumns {
+ public static final class Email implements DataColumnsWithJoins, CommonColumns {
private Email() {}
/** MIME type used when storing this in data table. */
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/email_v2";
/**
+ * The MIME type of {@link #CONTENT_URI} providing a directory of email addresses.
+ */
+ public static final String CONTENT_TYPE = "vnd.android.cursor.dir/email_v2";
+
+ /**
* The content:// style URI for all data records of the
* {@link Email#CONTENT_ITEM_TYPE} MIME type, combined with the
* associated raw contact and aggregate contact data.
@@ -1145,9 +1158,6 @@
public static final Uri CONTENT_LOOKUP_URI = Uri.withAppendedPath(CONTENT_URI,
"lookup");
- @Deprecated
- public static final Uri CONTENT_FILTER_EMAIL_URI = CONTENT_LOOKUP_URI;
-
/**
* The content:// style URL for email lookup using a filter. The filter returns
* records of MIME type {@link Email#CONTENT_ITEM_TYPE}. The filter is applied
@@ -1172,7 +1182,7 @@
/**
* Common data definition for postal addresses.
*/
- public static final class StructuredPostal implements BaseCommonColumns, CommonColumns {
+ public static final class StructuredPostal implements DataColumnsWithJoins, CommonColumns {
private StructuredPostal() {
}
@@ -1266,7 +1276,7 @@
/**
* Common data definition for IM addresses.
*/
- public static final class Im implements BaseCommonColumns, CommonColumns {
+ public static final class Im implements DataColumnsWithJoins, CommonColumns {
private Im() {}
/** MIME type used when storing this in data table. */
@@ -1304,7 +1314,7 @@
/**
* Common data definition for organizations.
*/
- public static final class Organization implements BaseCommonColumns, CommonColumns {
+ public static final class Organization implements DataColumnsWithJoins, CommonColumns {
private Organization() {}
/** MIME type used when storing this in data table. */
@@ -1353,7 +1363,7 @@
/**
* Common data definition for miscellaneous information.
*/
- public static final class Miscellaneous implements BaseCommonColumns {
+ public static final class Miscellaneous implements DataColumnsWithJoins {
private Miscellaneous() {}
/** MIME type used when storing this in data table. */
@@ -1375,7 +1385,7 @@
/**
* Common data definition for relations.
*/
- public static final class Relation implements BaseCommonColumns, CommonColumns {
+ public static final class Relation implements DataColumnsWithJoins, CommonColumns {
private Relation() {}
/** MIME type used when storing this in data table. */
@@ -1406,7 +1416,7 @@
/**
* Common data definition for events.
*/
- public static final class Event implements BaseCommonColumns, CommonColumns {
+ public static final class Event implements DataColumnsWithJoins, CommonColumns {
private Event() {}
/** MIME type used when storing this in data table. */
@@ -1425,7 +1435,7 @@
/**
* Photo of the contact.
*/
- public static final class Photo implements BaseCommonColumns {
+ public static final class Photo implements DataColumnsWithJoins {
private Photo() {}
/** MIME type used when storing this in data table. */
@@ -1443,7 +1453,7 @@
/**
* Notes about the contact.
*/
- public static final class Note implements BaseCommonColumns {
+ public static final class Note implements DataColumnsWithJoins {
private Note() {}
/** MIME type used when storing this in data table. */
@@ -1459,7 +1469,7 @@
/**
* Group Membership.
*/
- public static final class GroupMembership implements BaseCommonColumns {
+ public static final class GroupMembership implements DataColumnsWithJoins {
private GroupMembership() {}
/** MIME type used when storing this in data table. */
@@ -1484,7 +1494,7 @@
/**
* Website related to the contact.
*/
- public static final class Website implements BaseCommonColumns, CommonColumns {
+ public static final class Website implements DataColumnsWithJoins, CommonColumns {
private Website() {}
/** MIME type used when storing this in data table. */
@@ -1672,24 +1682,12 @@
*/
public static final int TYPE_KEEP_TOGETHER = 1;
- @Deprecated
- public static final int TYPE_KEEP_IN = 1;
-
/**
* Makes sure that the specified raw contacts are NOT included in the same
* aggregate contact.
*/
public static final int TYPE_KEEP_SEPARATE = 2;
- @Deprecated
- public static final int TYPE_KEEP_OUT = 2;
-
- @Deprecated
- public static final String CONTACT_ID = "contact_id";
-
- @Deprecated
- public static final String RAW_CONTACT_ID = "raw_contact_id";
-
/**
* A reference to the {@link RawContacts#_ID} of the raw contact that the rule applies to.
*/
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index ba53307..ba0a0d4 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -330,6 +330,9 @@
Log.e(TAG, "onDevicePropertyChanged: Address of the remote device in null");
return;
}
+ if (DBG) {
+ log("Device property changed:" + address + "property:" + name);
+ }
BluetoothDevice device = mAdapter.getRemoteDevice(address);
if (name.equals("Name")) {
Intent intent = new Intent(BluetoothDevice.ACTION_NAME_CHANGED);
@@ -366,6 +369,7 @@
uuid = str.toString();
}
mBluetoothService.setRemoteDeviceProperty(address, name, uuid);
+ mBluetoothService.sendUuidIntent(address);
} else if (name.equals("Paired")) {
if (propValues[1].equals("true")) {
mBluetoothService.getBondState().setBondState(address, BluetoothDevice.BOND_BONDED);
@@ -528,6 +532,25 @@
return;
}
+ private void onDiscoverServicesResult(String deviceObjectPath, boolean result) {
+ String address = mBluetoothService.getAddressFromObjectPath(deviceObjectPath);
+ // We don't parse the xml here, instead just query Bluez for the properties.
+ if (result) {
+ String[] properties = mBluetoothService.getRemoteDeviceProperties(address);
+ mBluetoothService.addRemoteDeviceProperties(address, properties);
+ }
+ mBluetoothService.sendUuidIntent(address);
+ }
+
+ private void onCreateDeviceResult(String address, boolean result) {
+ if (DBG) {
+ log("Result of onCreateDeviceResult:" + result);
+ }
+ if (!result) {
+ mBluetoothService.sendUuidIntent(address);
+ }
+ }
+
private void onRestartRequired() {
if (mBluetoothService.isEnabled()) {
Log.e(TAG, "*** A serious error occured (did bluetoothd crash?) - " +
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index c0e4f34..ce62f07 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -76,10 +76,17 @@
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;
+
+ // The timeout used to sent the UUIDs Intent
+ // This timeout should be greater than the page timeout
+ private static final int UUID_INTENT_DELAY = 6000;
private final Map<String, String> mAdapterProperties;
private final HashMap <String, Map<String, String>> mDeviceProperties;
+ private final ArrayList <String> mUuidIntentTracker;
+
static {
classInitNative();
}
@@ -104,6 +111,7 @@
mIsDiscovering = false;
mAdapterProperties = new HashMap<String, String>();
mDeviceProperties = new HashMap<String, Map<String,String>>();
+ mUuidIntentTracker = new ArrayList<String>();
registerForAirplaneMode();
}
@@ -291,6 +299,11 @@
case MESSAGE_FINISH_DISABLE:
finishDisable(msg.arg1 != 0);
break;
+ case MESSAGE_UUID_INTENT:
+ String address = (String)msg.obj;
+ if (address != null)
+ sendUuidIntent(address);
+ break;
}
}
};
@@ -976,6 +989,10 @@
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
return null;
}
+ return getUuidFromCache(address);
+ }
+
+ private ParcelUuid[] getUuidFromCache(String address) {
String value = getRemoteDeviceProperty(address, "UUIDs");
if (value == null) return null;
@@ -990,6 +1007,36 @@
return uuids;
}
+ public synchronized boolean fetchRemoteUuidsWithSdp(String address) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ if (!BluetoothAdapter.checkBluetoothAddress(address)) {
+ return false;
+ }
+
+ if (mUuidIntentTracker.contains(address)) {
+ // An SDP query for this address is already in progress
+ return true;
+ }
+
+ boolean ret;
+ if (getBondState(address) == BluetoothDevice.BOND_BONDED) {
+ String path = getObjectPathFromAddress(address);
+ if (path == null) return false;
+
+ // Use an empty string for the UUID pattern
+ ret = discoverServicesNative(path, "");
+ } else {
+ ret = createDeviceNative(address);
+ }
+
+ mUuidIntentTracker.add(address);
+
+ Message message = mHandler.obtainMessage(MESSAGE_UUID_INTENT);
+ message.obj = address;
+ mHandler.sendMessageDelayed(message, UUID_INTENT_DELAY);
+ return ret;
+ }
+
/**
* Gets the rfcomm channel associated with the UUID.
*
@@ -1121,6 +1168,18 @@
Settings.System.AIRPLANE_MODE_ON, 0) == 1;
}
+ /* Broadcast the Uuid intent */
+ /*package*/ synchronized void sendUuidIntent(String address) {
+ if (mUuidIntentTracker.contains(address)) {
+ ParcelUuid[] uuid = getUuidFromCache(address);
+ Intent intent = new Intent(BluetoothDevice.ACTION_UUID);
+ intent.putExtra(BluetoothDevice.EXTRA_UUID, uuid);
+ mContext.sendBroadcast(intent, BLUETOOTH_ADMIN_PERM);
+
+ mUuidIntentTracker.remove(address);
+ }
+ }
+
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("\nmIsAirplaneSensitive = " + mIsAirplaneSensitive + "\n");
@@ -1284,4 +1343,6 @@
private native boolean setPairingConfirmationNative(String address, boolean confirm,
int nativeData);
private native boolean setDevicePropertyBooleanNative(String objectPath, String key, int value);
+ private native boolean createDeviceNative(String address);
+ private native boolean discoverServicesNative(String objectPath, String pattern);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7e8ba8f..fb33561 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4517,6 +4517,8 @@
}
}
if (mInZoomOverview) {
+ // Force the titlebar fully reveal in overview mode
+ if (mScrollY < getTitleHeight()) mScrollY = 0;
zoomWithPreview((float) getViewWidth() / mZoomOverviewWidth);
} else {
// mLastTouchX and mLastTouchY are the point in the current viewport
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 4ec597c..ed375f7 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -248,7 +248,9 @@
PHONE_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
bindFromContactUri(Contacts.getLookupUri(contactId, lookupKey));
} else {
- setDisplayName((String) cookie, null);
+ String phoneNumber = (String) cookie;
+ setDisplayName(phoneNumber, null);
+ mPhotoView.assignContactFromPhone(phoneNumber, true);
}
break;
}
@@ -259,7 +261,9 @@
EMAIL_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
bindFromContactUri(Contacts.getLookupUri(contactId, lookupKey));
} else {
- setDisplayName((String) cookie, null);
+ String emailAddress = (String) cookie;
+ setDisplayName(emailAddress, null);
+ mPhotoView.assignContactFromEmail(emailAddress, true);
}
break;
}
diff --git a/core/java/com/android/internal/widget/RotarySelector.java b/core/java/com/android/internal/widget/RotarySelector.java
index 712f1bf..750b2a9 100644
--- a/core/java/com/android/internal/widget/RotarySelector.java
+++ b/core/java/com/android/internal/widget/RotarySelector.java
@@ -70,12 +70,6 @@
private AccelerateInterpolator mInterpolator;
/**
- * True after triggering an action if the user of {@link OnDialTriggerListener} wants to
- * freeze the UI (until they transition to another screen).
- */
- private boolean mFrozen = false;
-
- /**
* If the user is currently dragging something.
*/
private int mGrabbedState = NOTHING_GRABBED;
@@ -119,6 +113,9 @@
private static final boolean DRAW_CENTER_DIMPLE = false;
private int mEdgeTriggerThresh;
+ private int mDimpleWidth;
+ private int mBackgroundWidth;
+ private int mBackgroundHeight;
public RotarySelector(Context context) {
this(context, null);
@@ -155,6 +152,11 @@
mInterpolator = new AccelerateInterpolator();
mEdgeTriggerThresh = (int) (mDensity * EDGE_TRIGGER_DIP);
+
+ mDimpleWidth = mDimple.getIntrinsicWidth();
+
+ mBackgroundWidth = mBackground.getIntrinsicWidth();
+ mBackgroundHeight = mBackground.getIntrinsicHeight();
}
/**
@@ -214,7 +216,7 @@
final int width = MeasureSpec.getSize(widthMeasureSpec); // screen width
final int arrowH = mArrowShortLeftAndRight.getIntrinsicHeight();
- final int backgroundH = mBackground.getIntrinsicHeight();
+ final int backgroundH = mBackgroundHeight;
// by making the height less than arrow + bg, arrow and bg will be scrunched together,
// overlaying somewhat (though on transparent portions of the drawable).
@@ -228,9 +230,9 @@
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- mLeftHandleX = (int) (EDGE_PADDING_DIP * mDensity) + mDimple.getIntrinsicWidth() / 2;
+ mLeftHandleX = (int) (EDGE_PADDING_DIP * mDensity) + mDimpleWidth / 2;
mRightHandleX =
- getWidth() - (int) (EDGE_PADDING_DIP * mDensity) - mDimple.getIntrinsicWidth() / 2;
+ getWidth() - (int) (EDGE_PADDING_DIP * mDensity) - mDimpleWidth / 2;
}
// private Paint mPaint = new Paint();
@@ -239,15 +241,14 @@
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (DBG) {
- log(String.format("onDraw: mAnimating=%s, mTouchDragOffset=%d, mGrabbedState=%d," +
- "mFrozen=%s",
- mAnimating, mTouchDragOffset, mGrabbedState, mFrozen));
+ log(String.format("onDraw: mAnimating=%s, mTouchDragOffset=%d, mGrabbedState=%d",
+ mAnimating, mTouchDragOffset, mGrabbedState));
}
final int height = getHeight();
// update animating state before we draw anything
- if (mAnimating && !mFrozen) {
+ if (mAnimating) {
long millisLeft = mAnimationEndTime - currentAnimationTimeMillis();
if (DBG) log("millisleft for animating: " + millisLeft);
if (millisLeft <= 0) {
@@ -260,8 +261,8 @@
}
// Background:
- final int backgroundW = mBackground.getIntrinsicWidth();
- final int backgroundH = mBackground.getIntrinsicHeight();
+ final int backgroundW = mBackgroundWidth;
+ final int backgroundH = mBackgroundHeight;
final int backgroundY = height - backgroundH;
if (DBG) log("- Background INTRINSIC: " + backgroundW + " x " + backgroundH);
mBackground.setBounds(0, backgroundY,
@@ -383,12 +384,12 @@
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
- if (mAnimating || mFrozen) {
+ if (mAnimating) {
return true;
}
final int eventX = (int) event.getX();
- final int hitWindow = mDimple.getIntrinsicWidth();
+ final int hitWindow = mDimpleWidth;
final int action = event.getAction();
switch (action) {
@@ -419,14 +420,29 @@
invalidate();
if (eventX >= getRight() - mEdgeTriggerThresh && !mTriggered) {
mTriggered = true;
- mFrozen = dispatchTriggerEvent(OnDialTriggerListener.LEFT_HANDLE);
+ dispatchTriggerEvent(OnDialTriggerListener.LEFT_HANDLE);
+ // set up "spin around animation"
+ mAnimating = true;
+ mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
+ mAnimatingDelta = -mBackgroundWidth;
+ mTouchDragOffset = 0;
+ mGrabbedState = NOTHING_GRABBED;
+ invalidate();
+
}
} else if (mGrabbedState == RIGHT_HANDLE_GRABBED) {
mTouchDragOffset = eventX - mRightHandleX;
invalidate();
if (eventX <= mEdgeTriggerThresh && !mTriggered) {
mTriggered = true;
- mFrozen = dispatchTriggerEvent(OnDialTriggerListener.RIGHT_HANDLE);
+ dispatchTriggerEvent(OnDialTriggerListener.RIGHT_HANDLE);
+ // set up "spin around animation"
+ mAnimating = true;
+ mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
+ mAnimatingDelta = mBackgroundWidth;
+ mTouchDragOffset = 0;
+ mGrabbedState = NOTHING_GRABBED;
+ invalidate();
}
}
break;
@@ -435,11 +451,13 @@
// handle animating back to start if they didn't trigger
if (mGrabbedState == LEFT_HANDLE_GRABBED
&& Math.abs(eventX - mLeftHandleX) > 5) {
+ // set up "snap back" animation
mAnimating = true;
mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
mAnimatingDelta = eventX - mLeftHandleX;
} else if (mGrabbedState == RIGHT_HANDLE_GRABBED
&& Math.abs(eventX - mRightHandleX) > 5) {
+ // set up "snap back" animation
mAnimating = true;
mAnimationEndTime = currentAnimationTimeMillis() + ANIMATION_DURATION_MILLIS;
mAnimatingDelta = eventX - mRightHandleX;
@@ -504,12 +522,11 @@
/**
* Dispatches a trigger event to our listener.
*/
- private boolean dispatchTriggerEvent(int whichHandle) {
+ private void dispatchTriggerEvent(int whichHandle) {
vibrate(VIBRATE_LONG);
if (mOnDialTriggerListener != null) {
- return mOnDialTriggerListener.onDialTrigger(this, whichHandle);
+ mOnDialTriggerListener.onDialTrigger(this, whichHandle);
}
- return false;
}
/**
@@ -530,22 +547,13 @@
public static final int RIGHT_HANDLE = 2;
/**
- * @hide
- * The center handle is currently unused.
- */
- public static final int CENTER_HANDLE = 3;
-
- /**
* Called when the dial is triggered.
*
* @param v The view that was triggered
* @param whichHandle Which "dial handle" the user grabbed,
- * either {@link #LEFT_HANDLE}, {@link #RIGHT_HANDLE}, or
- * {@link #CENTER_HANDLE}.
- * @return Whether the widget should freeze (e.g when the action goes to another screen,
- * you want the UI to stay put until the transition occurs).
+ * either {@link #LEFT_HANDLE}, {@link #RIGHT_HANDLE}.
*/
- boolean onDialTrigger(View v, int whichHandle);
+ void onDialTrigger(View v, int whichHandle);
}
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index e703ed8..e37e832 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -48,6 +48,8 @@
static jmethodID method_onDeviceDisconnectRequested;
static jmethodID method_onCreatePairedDeviceResult;
+static jmethodID method_onCreateDeviceResult;
+static jmethodID method_onDiscoverServicesResult;
static jmethodID method_onGetDeviceServiceChannelResult;
static jmethodID method_onRequestPinCode;
@@ -92,6 +94,10 @@
method_onCreatePairedDeviceResult = env->GetMethodID(clazz, "onCreatePairedDeviceResult",
"(Ljava/lang/String;I)V");
+ method_onCreateDeviceResult = env->GetMethodID(clazz, "onCreateDeviceResult",
+ "(Ljava/lang/String;Z)V");
+ method_onDiscoverServicesResult = env->GetMethodID(clazz, "onDiscoverServicesResult",
+ "(Ljava/lang/String;Z)V");
method_onAgentAuthorize = env->GetMethodID(clazz, "onAgentAuthorize",
"(Ljava/lang/String;Ljava/lang/String;)Z");
@@ -1097,6 +1103,54 @@
free(user);
}
+void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
+ LOGV(__FUNCTION__);
+
+ native_data_t *nat = (native_data_t *)n;
+ const char *address= (const char *)user;
+ DBusError err;
+ dbus_error_init(&err);
+ JNIEnv *env;
+ nat->vm->GetEnv((void**)&env, nat->envVer);
+
+ LOGV("... Address = %s", address);
+
+ bool result = JNI_TRUE;
+ if (dbus_set_error_from_message(&err, msg)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ result = JNI_FALSE;
+ }
+ env->CallVoidMethod(nat->me,
+ method_onCreateDeviceResult,
+ env->NewStringUTF(address),
+ result);
+ free(user);
+}
+
+void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
+ LOGV(__FUNCTION__);
+
+ native_data_t *nat = (native_data_t *)n;
+ const char *path = (const char *)user;
+ DBusError err;
+ dbus_error_init(&err);
+ JNIEnv *env;
+ nat->vm->GetEnv((void**)&env, nat->envVer);
+
+ LOGV("... Device Path = %s", path);
+
+ bool result = JNI_TRUE;
+ if (dbus_set_error_from_message(&err, msg)) {
+ LOG_AND_FREE_DBUS_ERROR(&err);
+ result = JNI_FALSE;
+ }
+ env->CallVoidMethod(nat->me,
+ method_onDiscoverServicesResult,
+ env->NewStringUTF(path),
+ result);
+ free(user);
+}
+
void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
LOGV(__FUNCTION__);
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index 0b71acb..c432ed9 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -66,6 +66,8 @@
DBusMessage *msg,
void *data);
void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *nat);
+void onDiscoverServicesResult(DBusMessage *msg, void *user, void *nat);
+void onCreateDeviceResult(DBusMessage *msg, void *user, void *nat);
/** Get native data stored in the opaque (Java code maintained) pointer mNativeData
@@ -757,6 +759,75 @@
#endif
}
+
+static jboolean createDeviceNative(JNIEnv *env, jobject object,
+ jstring address) {
+ LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+ native_data_t *nat = get_native_data(env, object);
+ jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
+ struct event_loop_native_data_t *eventLoopNat =
+ get_EventLoop_native_data(env, eventLoop);
+
+ if (nat && eventLoopNat) {
+ const char *c_address = env->GetStringUTFChars(address, NULL);
+ LOGV("... address = %s", c_address);
+ char *context_address = (char *)calloc(BTADDR_SIZE, sizeof(char));
+ strlcpy(context_address, c_address, BTADDR_SIZE); // for callback
+
+ bool ret = dbus_func_args_async(env, nat->conn, -1,
+ onCreateDeviceResult,
+ context_address,
+ eventLoopNat,
+ get_adapter_path(env, object),
+ DBUS_ADAPTER_IFACE,
+ "CreateDevice",
+ DBUS_TYPE_STRING, &c_address,
+ DBUS_TYPE_INVALID);
+ env->ReleaseStringUTFChars(address, c_address);
+ return ret ? JNI_TRUE : JNI_FALSE;
+ }
+#endif
+ return JNI_FALSE;
+}
+
+static jboolean discoverServicesNative(JNIEnv *env, jobject object,
+ jstring path, jstring pattern) {
+ LOGV(__FUNCTION__);
+#ifdef HAVE_BLUETOOTH
+ native_data_t *nat = get_native_data(env, object);
+ jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
+ struct event_loop_native_data_t *eventLoopNat =
+ get_EventLoop_native_data(env, eventLoop);
+
+ if (nat && eventLoopNat) {
+ const char *c_path = env->GetStringUTFChars(path, NULL);
+ const char *c_pattern = env->GetStringUTFChars(pattern, NULL);
+ int len = env->GetStringLength(path) + 1;
+ char *context_path = (char *)calloc(len, sizeof(char));
+ strlcpy(context_path, c_path, len); // for callback
+
+ LOGV("... Object Path = %s", c_path);
+ LOGV("... Pattern = %s, strlen = %d", c_pattern, strlen(c_pattern));
+
+ bool ret = dbus_func_args_async(env, nat->conn, -1,
+ onDiscoverServicesResult,
+ context_path,
+ eventLoopNat,
+ c_path,
+ DBUS_DEVICE_IFACE,
+ "DiscoverServices",
+ DBUS_TYPE_STRING, &c_pattern,
+ DBUS_TYPE_INVALID);
+ env->ReleaseStringUTFChars(path, c_path);
+ env->ReleaseStringUTFChars(pattern, c_pattern);
+ return ret ? JNI_TRUE : JNI_FALSE;
+ }
+#endif
+ return JNI_FALSE;
+}
+
+
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"classInitNative", "()V", (void*)classInitNative},
@@ -797,6 +868,8 @@
(void *)cancelPairingUserInputNative},
{"setDevicePropertyBooleanNative", "(Ljava/lang/String;Ljava/lang/String;I)Z",
(void *)setDevicePropertyBooleanNative},
+ {"createDeviceNative", "(Ljava/lang/String;)Z", (void *)createDeviceNative},
+ {"discoverServicesNative", "(Ljava/lang/String;Ljava/lang/String;)Z", (void *)discoverServicesNative},
};
int register_android_server_BluetoothService(JNIEnv *env) {
diff --git a/core/res/res/anim/dialog_enter.xml b/core/res/res/anim/dialog_enter.xml
index 167f4bc..cc409e8 100644
--- a/core/res/res/anim/dialog_enter.xml
+++ b/core/res/res/anim/dialog_enter.xml
@@ -22,7 +22,7 @@
android:interpolator="@anim/decelerate_interpolator">
<scale android:fromXScale="0.9" android:toXScale="1.0"
android:fromYScale="0.9" android:toYScale="1.0"
- android:pivotX="50%p" android:pivotY="50%p"
+ android:pivotX="50%" android:pivotY="50%"
android:duration="@android:integer/config_shortAnimTime" />
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_shortAnimTime" />
diff --git a/core/res/res/anim/dialog_exit.xml b/core/res/res/anim/dialog_exit.xml
index d412cfb..8bf8082 100644
--- a/core/res/res/anim/dialog_exit.xml
+++ b/core/res/res/anim/dialog_exit.xml
@@ -21,7 +21,7 @@
android:interpolator="@anim/accelerate_interpolator">
<scale android:fromXScale="1.0" android:toXScale="0.9"
android:fromYScale="1.0" android:toYScale="0.9"
- android:pivotX="50%p" android:pivotY="50%p"
+ android:pivotX="50%" android:pivotY="50%"
android:duration="@android:integer/config_shortAnimTime" />
<alpha android:fromAlpha="1.0" android:toAlpha="0.0"
android:duration="@android:integer/config_shortAnimTime"/>
diff --git a/core/res/res/anim/recent_enter.xml b/core/res/res/anim/recent_enter.xml
index deeb96b..54ae73b 100644
--- a/core/res/res/anim/recent_enter.xml
+++ b/core/res/res/anim/recent_enter.xml
@@ -21,7 +21,7 @@
android:interpolator="@anim/decelerate_interpolator">
<scale android:fromXScale="2.0" android:toXScale="1.0"
android:fromYScale="2.0" android:toYScale="1.0"
- android:pivotX="50%p" android:pivotY="50%p"
+ android:pivotX="50%" android:pivotY="50%"
android:duration="@android:integer/config_mediumAnimTime" />
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="@android:integer/config_mediumAnimTime"/>
diff --git a/core/res/res/anim/recent_exit.xml b/core/res/res/anim/recent_exit.xml
index fed7014..32d64a4 100644
--- a/core/res/res/anim/recent_exit.xml
+++ b/core/res/res/anim/recent_exit.xml
@@ -22,7 +22,7 @@
android:zAdjustment="top">
<scale android:fromXScale="1.0" android:toXScale="2.0"
android:fromYScale="1.0" android:toYScale="2.0"
- android:pivotX="50%p" android:pivotY="50%p"
+ android:pivotX="50%" android:pivotY="50%"
android:duration="@android:integer/config_mediumAnimTime" />
<alpha android:fromAlpha="1.0" android:toAlpha="0"
android:duration="@android:integer/config_mediumAnimTime"/>
diff --git a/core/res/res/drawable-hdpi/ic_lock_ringer_off.png b/core/res/res/drawable-hdpi/ic_lock_ringer_off.png
new file mode 100644
index 0000000..e7cb234
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_ringer_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/ic_lock_ringer_on.png b/core/res/res/drawable-hdpi/ic_lock_ringer_on.png
new file mode 100644
index 0000000..ce0cfab
--- /dev/null
+++ b/core/res/res/drawable-hdpi/ic_lock_ringer_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_ringer_off.png b/core/res/res/drawable-mdpi/ic_lock_ringer_off.png
new file mode 100644
index 0000000..98cfb11
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_ringer_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_lock_ringer_on.png b/core/res/res/drawable-mdpi/ic_lock_ringer_on.png
new file mode 100644
index 0000000..691b99e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/ic_lock_ringer_on.png
Binary files differ
diff --git a/core/res/res/layout/keyguard_screen_rotary_unlock.xml b/core/res/res/layout/keyguard_screen_rotary_unlock.xml
index cf97d04..9f18124 100644
--- a/core/res/res/layout/keyguard_screen_rotary_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_rotary_unlock.xml
@@ -83,6 +83,7 @@
android:layout_marginTop="6dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorSecondary"
+ android:drawablePadding="4dip"
/>
<TextView
@@ -94,6 +95,7 @@
android:layout_marginTop="6dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?android:attr/textColorSecondary"
+ android:drawablePadding="4dip"
/>
<TextView
@@ -108,15 +110,15 @@
android:layout_marginTop="12dip"
/>
- <!-- By having the rotary selector hang below "screen locked" text, we get a layout more
- robust for different screen sizes. On wvga, the widget should be flush with the bottom.-->
+ <!-- By having the rotary selector hang from the top, we get a layout more
+ robust for different screen sizes. On hvga, the widget should be flush with the bottom.-->
<com.android.internal.widget.RotarySelector
android:id="@+id/rotary"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_below="@id/screenLocked"
android:layout_centerHorizontal="true"
- android:layout_marginTop="24dip"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="286dip"
/>
<!-- emergency call button shown when sim is missing or PUKd -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index eae838a..e7b379a 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -102,9 +102,9 @@
<!-- Text color, typeface, size, and style for "small" inverse text. Defaults to secondary inverse text color. -->
<attr name="textAppearanceSmallInverse" format="reference" />
- <!-- Text color, typeface, size, and style for system search result title. Defaults to primary inverse text color. @hide -->
+ <!-- Text color, typeface, size, and style for system search result title. Defaults to primary inverse text color. -->
<attr name="textAppearanceSearchResultTitle" format="reference" />
- <!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. @hide -->
+ <!-- Text color, typeface, size, and style for system search result subtitle. Defaults to primary inverse text color. -->
<attr name="textAppearanceSearchResultSubtitle" format="reference" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index b710acb..7695503 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -78,6 +78,20 @@
A value of -1 means no change in orientation by default. -->
<integer name="config_carDockRotation">-1</integer>
+ <!-- Control whether being in the desk dock (and powered) always
+ keeps the screen on. By default it doesn't. Set to true to make it. -->
+ <bool name="config_deskDockKeepsScreenOn">false</bool>
+
+ <!-- Control whether being in the car dock (and powered) always
+ keeps the screen on. By default it does. Set to false to not keep on. -->
+ <bool name="config_carDockKeepsScreenOn">true</bool>
+
+ <!-- Control whether being in the desk dock should enable accelerometer based screen orientation -->
+ <bool name="config_deskDockEnablesAccelerometer">false</bool>
+
+ <!-- Control whether being in the car dock should enable accelerometer based screen orientation -->
+ <bool name="config_carDockEnablesAccelerometer">false</bool>
+
<!-- Indicate whether the lid state impacts the accessibility of
the physical keyboard. 0 means it doesn't, 1 means it is accessible
when the lid is open, 2 means it is accessible when the lid is
@@ -105,5 +119,7 @@
<item>20</item>
<item>30</item>
</integer-array>
-
+
+ <bool name="config_use_strict_phone_number_comparation">false</bool>
+
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 2bc2a0f..71c6ff5 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1164,6 +1164,8 @@
<public type="attr" name="restoreNeedsApplication" />
<public type="attr" name="smallIcon" />
<public type="attr" name="accountPreferences" />
+ <public type="attr" name="textAppearanceSearchResultSubtitle" />
+ <public type="attr" name="textAppearanceSearchResultTitle" />
<public type="style" name="Theme.Wallpaper" />
<public type="style" name="Theme.Wallpaper.NoTitleBar" />
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
index 4a4ad6f..b4d265d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/MediaRecorderTest.java
@@ -214,6 +214,7 @@
Log.v(TAG, "before getduration");
mOutputDuration = mediaPlayer.getDuration();
Log.v(TAG, "get video dimension");
+ Thread.sleep(1000);
mOutputVideoHeight = mediaPlayer.getVideoHeight();
mOutputVideoWidth = mediaPlayer.getVideoWidth();
//mOutputVideoHeight = CodecTest.videoHeight(outputFilePath);
@@ -416,7 +417,8 @@
MediaRecorder.OutputFormat.THREE_GPP, MediaNames.RECORDED_VIDEO_3GP, false);
assertTrue("Invalid video Size", isTestInvalidVideoSizeSuccessful);
}
-
+
+ @Suppress
@LargeTest
public void testInvalidFrameRate() throws Exception {
boolean isTestInvalidFrameRateSuccessful = false;
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index d4887ba..f97d347 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -21,8 +21,8 @@
#include <sys/resource.h>
#include <EGL/egl.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#include <utils/Timers.h>
@@ -31,144 +31,267 @@
using namespace android;
-static void printGLString(const char *name, GLenum s)
-{
- fprintf(stderr, "printGLString %s, %d\n", name, s);
-#if 0 // causes hangs
- const char *v = (const char *)glGetString(s);
- int error = glGetError();
- fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
- (unsigned int)v);
- if ((v < (const char*) 0) || (v > (const char*) 0x10000))
- fprintf(stderr, "GL %s = %s\n", name, v);
- else
- fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
-#endif
+static void printGLString(const char *name, GLenum s) {
+ // fprintf(stderr, "printGLString %s, %d\n", name, s);
+ const char *v = (const char *) glGetString(s);
+ // int error = glGetError();
+ // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
+ // (unsigned int) v);
+ // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
+ // fprintf(stderr, "GL %s = %s\n", name, v);
+ // else
+ // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+ fprintf(stderr, "GL %s = %s\n", name, v);
}
static const char* eglErrorToString[] = {
- "EGL_SUCCESS", // 0x3000 12288
- "EGL_NOT_INITIALIZED",
- "EGL_BAD_ACCESS", // 0x3002 12290
- "EGL_BAD_ALLOC",
- "EGL_BAD_ATTRIBUTE",
- "EGL_BAD_CONFIG",
- "EGL_BAD_CONTEXT", // 0x3006 12294
- "EGL_BAD_CURRENT_SURFACE",
- "EGL_BAD_DISPLAY",
- "EGL_BAD_MATCH",
- "EGL_BAD_NATIVE_PIXMAP",
- "EGL_BAD_NATIVE_WINDOW",
- "EGL_BAD_PARAMETER", // 0x300c 12300
- "EGL_BAD_SURFACE"
-};
+ "EGL_SUCCESS", // 0x3000 12288
+ "EGL_NOT_INITIALIZED",
+ "EGL_BAD_ACCESS", // 0x3002 12290
+ "EGL_BAD_ALLOC", "EGL_BAD_ATTRIBUTE",
+ "EGL_BAD_CONFIG",
+ "EGL_BAD_CONTEXT", // 0x3006 12294
+ "EGL_BAD_CURRENT_SURFACE", "EGL_BAD_DISPLAY", "EGL_BAD_MATCH",
+ "EGL_BAD_NATIVE_PIXMAP", "EGL_BAD_NATIVE_WINDOW", "EGL_BAD_PARAMETER", // 0x300c 12300
+ "EGL_BAD_SURFACE" };
static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
if (returnVal != EGL_TRUE) {
fprintf(stderr, "%s() returned %d\n", op, returnVal);
}
- for(EGLint error = eglGetError();
- error != EGL_SUCCESS;
- error = eglGetError()) {
+ for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+ = eglGetError()) {
const char* errorString = "unknown";
if (error >= EGL_SUCCESS && error <= EGL_BAD_SURFACE) {
errorString = eglErrorToString[error - EGL_SUCCESS];
}
- fprintf(stderr, "after %s() eglError %s (0x%x)\n", op,
- errorString, error);
+ fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, errorString,
+ error);
}
}
-int main(int argc, char** argv)
-{
+static void checkGlError(const char* op) {
+ for (GLint error = glGetError(); error; error
+ = glGetError()) {
+ fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
+ }
+}
+
+static const char gVertexShader[] = "attribute vec4 vPosition;\n"
+ "void main() {\n"
+ " gl_Position = vPosition;\n"
+ "}\n";
+
+static const char gFragmentShader[] = "precision mediump float;\n"
+ "void main() {\n"
+ " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ "}\n";
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+ GLuint shader = glCreateShader(shaderType);
+ if (shader) {
+ glShaderSource(shader, 1, &pSource, NULL);
+ glCompileShader(shader);
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf) {
+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ fprintf(stderr, "Could not compile shader %d:\n%s\n",
+ shaderType, buf);
+ free(buf);
+ }
+ glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ }
+ return shader;
+}
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+ if (!vertexShader) {
+ return 0;
+ }
+
+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+ if (!pixelShader) {
+ return 0;
+ }
+
+ GLuint program = glCreateProgram();
+ if (program) {
+ glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader");
+ glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader");
+ glLinkProgram(program);
+ GLint linkStatus = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus != GL_TRUE) {
+ GLint bufLength = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+ if (bufLength) {
+ char* buf = (char*) malloc(bufLength);
+ if (buf) {
+ glGetProgramInfoLog(program, bufLength, NULL, buf);
+ fprintf(stderr, "Could not link program:\n%s\n", buf);
+ free(buf);
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+}
+
+GLuint gProgram;
+GLuint gvPositionHandle;
+
+bool setupGraphics(int w, int h) {
+ gProgram = createProgram(gVertexShader, gFragmentShader);
+ if (!gProgram) {
+ return false;
+ }
+ gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+ checkGlError("glGetAttribLocation");
+ fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n",
+ gvPositionHandle);
+
+ glViewport(0, 0, w, h);
+ checkGlError("glViewport");
+ return true;
+}
+
+const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f };
+
+void renderFrame() {
+ glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+ checkGlError("glClearColor");
+ glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ checkGlError("glClear");
+
+ glUseProgram(gProgram);
+ checkGlError("glUseProgram");
+
+ glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+ checkGlError("glVertexAttribPointer");
+ glEnableVertexAttribArray(gvPositionHandle);
+ checkGlError("glEnableVertexAttribArray");
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ checkGlError("glDrawArrays");
+}
+
+int main(int argc, char** argv) {
EGLBoolean returnValue;
EGLConfig configs[2];
EGLint config_count;
- EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
- EGLint s_configAttribs[] = {
- EGL_BUFFER_SIZE, EGL_DONT_CARE,
- EGL_RED_SIZE, 5,
- EGL_GREEN_SIZE, 6,
- EGL_BLUE_SIZE, 5,
- EGL_DEPTH_SIZE, 8,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_NONE
- };
+ EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+ EGLint s_configAttribs[] = { EGL_BUFFER_SIZE, EGL_DONT_CARE, EGL_RED_SIZE,
+ 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
- EGLint majorVersion;
- EGLint minorVersion;
- EGLContext context;
- EGLSurface surface;
- EGLint w, h;
+ EGLint s_configAttribs2[] =
+ {
+ EGL_DEPTH_SIZE, 16,
+ EGL_NONE
+ };
- EGLDisplay dpy;
+ EGLint majorVersion;
+ EGLint minorVersion;
+ EGLContext context;
+ EGLSurface surface;
+ EGLint w, h;
- EGLNativeWindowType window = 0;
- window = android_createDisplaySurface();
+ EGLDisplay dpy;
- checkEglError("<init>");
- dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- checkEglError("eglGetDisplay");
- if (dpy == EGL_NO_DISPLAY) {
- printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
- return 0;
- }
- returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
- checkEglError("eglInitialize", returnValue);
- fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+ EGLNativeWindowType window = 0;
+ window = android_createDisplaySurface();
- returnValue = eglGetConfigs (dpy, configs, 2, &config_count);
- checkEglError("eglGetConfigs", returnValue);
- fprintf(stderr, "Config count: %d\n", config_count);
- for(int i = 0; i < config_count; i++) {
+ checkEglError("<init>");
+ dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ checkEglError("eglGetDisplay");
+ if (dpy == EGL_NO_DISPLAY) {
+ printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+ return 0;
+ }
+
+ returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+ checkEglError("eglInitialize", returnValue);
+ fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+ if (returnValue != EGL_TRUE) {
+ printf("eglInitialize failed\n");
+ return 0;
+ }
+
+ returnValue = eglGetConfigs(dpy, configs, 2, &config_count);
+ checkEglError("eglGetConfigs", returnValue);
+ fprintf(stderr, "Config count: %d\n", config_count);
+ for (int i = 0; i < config_count; i++) {
fprintf(stderr, "%d: 0x%08x\n", i, (unsigned int) configs[i]);
- }
+ }
+
#if 0
- EGLConfig config;
- EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
- checkEglError("EGLUtils::selectConfigForNativeWindow");
+ EGLConfig config;
+ EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
+ checkEglError("EGLUtils::selectConfigForNativeWindow");
#else
- int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs, configs, 2, &config_count);
+ int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs2, configs, 2,
+ &config_count);
checkEglError("eglChooseConfig", chooseConfigResult);
- if (chooseConfigResult != EGL_TRUE )
- {
+ if (chooseConfigResult != EGL_TRUE) {
printf("eglChooseConfig failed\n");
- return 0;
+ return 0;
}
#endif
- surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
- checkEglError("eglCreateWindowSurface");
- if (surface == EGL_NO_SURFACE)
- {
- printf("gelCreateWindowSurface failed.\n");
- return 0;
- }
- EGLint gl2_0Attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
+ surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
+ checkEglError("eglCreateWindowSurface");
+ if (surface == EGL_NO_SURFACE) {
+ printf("gelCreateWindowSurface failed.\n");
+ return 0;
+ }
+ EGLint gl2_0Attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
- context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
- checkEglError("eglCreateContext");
- if (context == EGL_NO_CONTEXT)
- {
+ context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
+ checkEglError("eglCreateContext");
+ if (context == EGL_NO_CONTEXT) {
printf("eglCreateContext failed\n");
return 0;
- }
- eglMakeCurrent(dpy, surface, surface, context);
- checkEglError("eglMakeCurrent");
- eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
- checkEglError("eglQuerySurface");
- eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
- checkEglError("eglQuerySurface");
- GLint dim = w<h ? w : h;
+ }
+ eglMakeCurrent(dpy, surface, surface, context);
+ checkEglError("eglMakeCurrent");
+ eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+ checkEglError("eglQuerySurface");
+ eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+ checkEglError("eglQuerySurface");
+ GLint dim = w < h ? w : h;
- fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+ fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
- printGLString("Version", GL_VERSION);
- printGLString("Vendor", GL_VENDOR);
- printGLString("Renderer", GL_RENDERER);
- printGLString("Extensions", GL_EXTENSIONS);
+ printGLString("Version", GL_VERSION);
+ printGLString("Vendor", GL_VENDOR);
+ printGLString("Renderer", GL_RENDERER);
+ printGLString("Extensions", GL_EXTENSIONS);
- return 0;
+ if(!setupGraphics(w, h)) {
+ fprintf(stderr, "Could not set up graphics.\n");
+ return 0;
+ }
+
+ for (;;) {
+ renderFrame();
+ eglSwapBuffers(dpy, surface);
+ }
+
+ return 0;
}
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 26fee89..d78d886 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -26,7 +26,6 @@
import android.content.pm.PackageManager;
import android.os.BatteryManager;
import android.os.Binder;
-import android.os.Debug;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -333,16 +332,16 @@
int icon = getIcon(mBatteryLevel);
- intent.putExtra("status", mBatteryStatus);
- intent.putExtra("health", mBatteryHealth);
- intent.putExtra("present", mBatteryPresent);
- intent.putExtra("level", mBatteryLevel);
- intent.putExtra("scale", BATTERY_SCALE);
- intent.putExtra("icon-small", icon);
- intent.putExtra("plugged", mPlugType);
- intent.putExtra("voltage", mBatteryVoltage);
- intent.putExtra("temperature", mBatteryTemperature);
- intent.putExtra("technology", mBatteryTechnology);
+ intent.putExtra(BatteryManager.EXTRA_STATUS, mBatteryStatus);
+ intent.putExtra(BatteryManager.EXTRA_HEALTH, mBatteryHealth);
+ intent.putExtra(BatteryManager.EXTRA_PRESENT, mBatteryPresent);
+ intent.putExtra(BatteryManager.EXTRA_LEVEL, mBatteryLevel);
+ intent.putExtra(BatteryManager.EXTRA_SCALE, BATTERY_SCALE);
+ intent.putExtra(BatteryManager.EXTRA_ICON_SMALL, icon);
+ intent.putExtra(BatteryManager.EXTRA_PLUGGED, mPlugType);
+ intent.putExtra(BatteryManager.EXTRA_VOLTAGE, mBatteryVoltage);
+ intent.putExtra(BatteryManager.EXTRA_TEMPERATURE, mBatteryTemperature);
+ intent.putExtra(BatteryManager.EXTRA_TECHNOLOGY, mBatteryTechnology);
if (false) {
Log.d(TAG, "updateBattery level:" + mBatteryLevel +
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 60195b9..8a4b45d 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -16,7 +16,9 @@
package com.android.server;
+import android.app.Activity;
import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
@@ -44,6 +46,43 @@
private final Context mContext;
private PowerManagerService mPowerManager;
+
+ // The broadcast receiver which receives the result of the ordered broadcast sent when
+ // the dock state changes. The original ordered broadcast is sent with an initial result
+ // code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
+ // to RESULT_CANCELED, then the intent to start a dock app will not be sent.
+ private final BroadcastReceiver mResultReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (getResultCode() != Activity.RESULT_OK) {
+ return;
+ }
+
+ // Launch a dock activity
+ String category;
+ switch (mDockState) {
+ case Intent.EXTRA_DOCK_STATE_CAR:
+ category = Intent.CATEGORY_CAR_DOCK;
+ break;
+ case Intent.EXTRA_DOCK_STATE_DESK:
+ category = Intent.CATEGORY_DESK_DOCK;
+ break;
+ default:
+ category = null;
+ break;
+ }
+ if (category != null) {
+ intent = new Intent(Intent.ACTION_MAIN);
+ intent.addCategory(category);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ try {
+ mContext.startActivity(intent);
+ } catch (ActivityNotFoundException e) {
+ Log.w(TAG, e.getCause());
+ }
+ }
+ }
+ };
public DockObserver(Context context, PowerManagerService pm) {
mContext = context;
@@ -111,31 +150,15 @@
mPowerManager.userActivityWithForce(SystemClock.uptimeMillis(), false, true);
Intent intent = new Intent(Intent.ACTION_DOCK_EVENT);
intent.putExtra(Intent.EXTRA_DOCK_STATE, mDockState);
- mContext.sendStickyBroadcast(intent);
-
- // Launch a dock activity
- String category;
- switch (mDockState) {
- case Intent.EXTRA_DOCK_STATE_CAR:
- category = Intent.CATEGORY_CAR_DOCK;
- break;
- case Intent.EXTRA_DOCK_STATE_DESK:
- category = Intent.CATEGORY_DESK_DOCK;
- break;
- default:
- category = null;
- break;
- }
- if (category != null) {
- intent = new Intent(Intent.ACTION_MAIN);
- intent.addCategory(category);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- mContext.startActivity(intent);
- } catch (ActivityNotFoundException e) {
- Log.w(TAG, e.getCause());
- }
- }
+
+ // 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
+ // not launch the corresponding dock application. This gives apps a chance
+ // to override the behavior and stay in their app even when the device is
+ // placed into a dock.
+ mContext.sendStickyOrderedBroadcast(
+ intent, mResultReceiver, null, Activity.RESULT_OK, null, null);
}
}
};
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index 84250bc..656d6ba 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -304,10 +304,7 @@
// temporarily set mUserActivityAllowed to true so this will work
// even when the keyguard is on.
synchronized (mLocks) {
- boolean savedActivityAllowed = mUserActivityAllowed;
- mUserActivityAllowed = true;
- userActivity(SystemClock.uptimeMillis(), false);
- mUserActivityAllowed = savedActivityAllowed;
+ forceUserActivityLocked();
}
}
}
@@ -1714,6 +1711,13 @@
}
}
+ private void forceUserActivityLocked() {
+ boolean savedActivityAllowed = mUserActivityAllowed;
+ mUserActivityAllowed = true;
+ userActivity(SystemClock.uptimeMillis(), false);
+ mUserActivityAllowed = savedActivityAllowed;
+ }
+
public void userActivityWithForce(long time, boolean noChangeLights, boolean force) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DEVICE_POWER, null);
userActivity(time, noChangeLights, OTHER_EVENT, force);
@@ -2114,7 +2118,12 @@
Log.d(TAG, "disableProximityLockLocked");
}
mSensorManager.unregisterListener(this);
- mProximitySensorActive = false;
+ synchronized (mLocks) {
+ if (mProximitySensorActive) {
+ mProximitySensorActive = false;
+ forceUserActivityLocked();
+ }
+ }
}
public void onSensorChanged(SensorEvent event) {
@@ -2135,10 +2144,7 @@
Log.d(TAG, "onSensorChanged: proximity inactive, distance: " + distance);
}
mProximitySensorActive = false;
- boolean savedActivityAllowed = mUserActivityAllowed;
- mUserActivityAllowed = true;
- userActivity(milliseconds, false);
- mUserActivityAllowed = savedActivityAllowed;
+ forceUserActivityLocked();
}
}
}
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 63bef54..cc1b697 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -295,7 +295,11 @@
if (mWifiHandler == null) return false;
synchronized (mWifiHandler) {
+ // caller may not have WAKE_LOCK permission - it's not required here
+ long ident = Binder.clearCallingIdentity();
sWakeLock.acquire();
+ Binder.restoreCallingIdentity(ident);
+
mLastEnableUid = Binder.getCallingUid();
// set a flag if the user is enabling Wifi while in airplane mode
mAirplaneModeOverwridden = (enable && isAirplaneModeOn() && isAirplaneToggleable());
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 0cd5949..bbf2a24 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -7319,10 +7319,11 @@
final Matrix tmpMatrix = mTmpMatrix;
// Compute the desired transformation.
- tmpMatrix.setTranslate(frame.left, frame.top);
+ tmpMatrix.setTranslate(0, 0);
if (selfTransformation) {
tmpMatrix.postConcat(mTransformation.getMatrix());
}
+ tmpMatrix.postTranslate(frame.left, frame.top);
if (attachedTransformation != null) {
tmpMatrix.postConcat(attachedTransformation.getMatrix());
}
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 2672c6d..2d8afb7 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -111,6 +111,11 @@
return c == PAUSE || c == WAIT;
}
+ /** Returns true if ch is not dialable or alpha char */
+ private static boolean isSeparator(char ch) {
+ return !isDialable(ch) && !(('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z'));
+ }
+
/** Extracts the phone number from an Intent.
*
* @param intent the intent to get the number of
@@ -293,6 +298,21 @@
}
/**
+ * Compare phone numbers a and b, return true if they're identical enough for caller ID purposes.
+ */
+ public static boolean compare(String a, String b) {
+ // We've used loose comparation at least Eclair, which may change in the future.
+ return compare(a, b, false);
+ }
+
+ /**
+ * @hide only for testing.
+ */
+ public static boolean compare(String a, String b, boolean useStrictComparation) {
+ return (useStrictComparation ? compareStrictly(a, b) : compareLoosely(a, b));
+ }
+
+ /**
* Compare phone numbers a and b, return true if they're identical
* enough for caller ID purposes.
*
@@ -301,10 +321,13 @@
* - handles common trunk prefixes and international prefixes
* (basically, everything except the Russian trunk prefix)
*
- * Tolerates nulls
+ * Note that this method does not return false even when the two phone numbers
+ * are not exactly same; rather; we can call this method "similar()", not "equals()".
+ *
+ * @hide
*/
public static boolean
- compare(String a, String b) {
+ compareLoosely(String a, String b) {
int ia, ib;
int matched;
@@ -391,6 +414,160 @@
}
/**
+ * @hide
+ */
+ public static boolean
+ compareStrictly(String a, String b) {
+ return compareStrictly(a, b, true);
+ }
+
+ /**
+ * @hide
+ */
+ public static boolean
+ compareStrictly(String a, String b, boolean acceptInvalidCCCPrefix) {
+ if (a == null || b == null) {
+ return a == b;
+ } else if (a.length() == 0 && b.length() == 0) {
+ return false;
+ }
+
+ int forwardIndexA = 0;
+ int forwardIndexB = 0;
+
+ CountryCallingCodeAndNewIndex cccA =
+ tryGetCountryCallingCodeAndNewIndex(a, acceptInvalidCCCPrefix);
+ CountryCallingCodeAndNewIndex cccB =
+ tryGetCountryCallingCodeAndNewIndex(b, acceptInvalidCCCPrefix);
+ boolean bothHasCountryCallingCode = false;
+ boolean okToIgnorePrefix = true;
+ boolean trunkPrefixIsOmittedA = false;
+ boolean trunkPrefixIsOmittedB = false;
+ if (cccA != null && cccB != null) {
+ if (cccA.countryCallingCode != cccB.countryCallingCode) {
+ // Different Country Calling Code. Must be different phone number.
+ return false;
+ }
+ // When both have ccc, do not ignore trunk prefix. Without this,
+ // "+81123123" becomes same as "+810123123" (+81 == Japan)
+ okToIgnorePrefix = false;
+ bothHasCountryCallingCode = true;
+ forwardIndexA = cccA.newIndex;
+ forwardIndexB = cccB.newIndex;
+ } else if (cccA == null && cccB == null) {
+ // When both do not have ccc, do not ignore trunk prefix. Without this,
+ // "123123" becomes same as "0123123"
+ okToIgnorePrefix = false;
+ } else {
+ if (cccA != null) {
+ forwardIndexA = cccA.newIndex;
+ } else {
+ int tmp = tryGetTrunkPrefixOmittedIndex(b, 0);
+ if (tmp >= 0) {
+ forwardIndexA = tmp;
+ trunkPrefixIsOmittedA = true;
+ }
+ }
+ if (cccB != null) {
+ forwardIndexB = cccB.newIndex;
+ } else {
+ int tmp = tryGetTrunkPrefixOmittedIndex(b, 0);
+ if (tmp >= 0) {
+ forwardIndexB = tmp;
+ trunkPrefixIsOmittedB = true;
+ }
+ }
+ }
+
+ int backwardIndexA = a.length() - 1;
+ int backwardIndexB = b.length() - 1;
+ while (backwardIndexA >= forwardIndexA && backwardIndexB >= forwardIndexB) {
+ boolean skip_compare = false;
+ final char chA = a.charAt(backwardIndexA);
+ final char chB = b.charAt(backwardIndexB);
+ if (isSeparator(chA)) {
+ backwardIndexA--;
+ skip_compare = true;
+ }
+ if (isSeparator(chB)) {
+ backwardIndexB--;
+ skip_compare = true;
+ }
+
+ if (!skip_compare) {
+ if (chA != chB) {
+ return false;
+ }
+ backwardIndexA--;
+ backwardIndexB--;
+ }
+ }
+
+ if (okToIgnorePrefix) {
+ if ((trunkPrefixIsOmittedA && forwardIndexA <= backwardIndexA) ||
+ !checkPrefixIsIgnorable(a, forwardIndexA, backwardIndexA)) {
+ if (acceptInvalidCCCPrefix) {
+ // Maybe the code handling the special case for Thailand makes the
+ // result garbled, so disable the code and try again.
+ // e.g. "16610001234" must equal to "6610001234", but with
+ // Thailand-case handling code, they become equal to each other.
+ //
+ // Note: we select simplicity rather than adding some complicated
+ // logic here for performance(like "checking whether remaining
+ // numbers are just 66 or not"), assuming inputs are small
+ // enough.
+ return compare(a, b, false);
+ } else {
+ return false;
+ }
+ }
+ if ((trunkPrefixIsOmittedB && forwardIndexB <= backwardIndexB) ||
+ !checkPrefixIsIgnorable(b, forwardIndexA, backwardIndexB)) {
+ if (acceptInvalidCCCPrefix) {
+ return compare(a, b, false);
+ } else {
+ return false;
+ }
+ }
+ } else {
+ // In the US, 1-650-555-1234 must be equal to 650-555-1234,
+ // while 090-1234-1234 must not be equalt to 90-1234-1234 in Japan.
+ // This request exists just in US (with 1 trunk (NDD) prefix).
+ // In addition, "011 11 7005554141" must not equal to "+17005554141",
+ // while "011 1 7005554141" must equal to "+17005554141"
+ //
+ // In this comparison, we ignore the prefix '1' just once, when
+ // - at least either does not have CCC, or
+ // - the remaining non-separator number is 1
+ boolean maybeNamp = !bothHasCountryCallingCode;
+ while (backwardIndexA >= forwardIndexA) {
+ final char chA = a.charAt(backwardIndexA);
+ if (isDialable(chA)) {
+ if (maybeNamp && tryGetISODigit(chA) == 1) {
+ maybeNamp = false;
+ } else {
+ return false;
+ }
+ }
+ backwardIndexA--;
+ }
+ while (backwardIndexB >= forwardIndexB) {
+ final char chB = b.charAt(backwardIndexB);
+ if (isDialable(chB)) {
+ if (maybeNamp && tryGetISODigit(chB) == 1) {
+ maybeNamp = false;
+ } else {
+ return false;
+ }
+ }
+ backwardIndexB--;
+ }
+ }
+
+ return true;
+ }
+
+ /**
* Returns the rightmost MIN_MATCH (5) characters in the network portion
* in *reversed* order
*
@@ -475,54 +652,6 @@
}
/**
- * Phone numbers are stored in "lookup" form in the database
- * as reversed strings to allow for caller ID lookup
- *
- * This method takes a phone number and makes a valid SQL "LIKE"
- * string that will match the lookup form
- *
- */
- /** all of a up to len must be an international prefix or
- * separators/non-dialing digits
- */
- private static boolean
- matchIntlPrefix(String a, int len) {
- /* '([^0-9*#+pwn]\+[^0-9*#+pwn] | [^0-9*#+pwn]0(0|11)[^0-9*#+pwn] )$' */
- /* 0 1 2 3 45 */
-
- int state = 0;
- for (int i = 0 ; i < len ; i++) {
- char c = a.charAt(i);
-
- switch (state) {
- case 0:
- if (c == '+') state = 1;
- else if (c == '0') state = 2;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 2:
- if (c == '0') state = 3;
- else if (c == '1') state = 4;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 4:
- if (c == '1') state = 5;
- else if (isNonSeparator(c)) return false;
- break;
-
- default:
- if (isNonSeparator(c)) return false;
- break;
-
- }
- }
-
- return state == 1 || state == 3 || state == 5;
- }
-
- /**
* 3GPP TS 24.008 10.5.4.7
* Called Party BCD Number
*
@@ -835,76 +964,6 @@
return result;
}
- /** all of 'a' up to len must match non-US trunk prefix ('0') */
- private static boolean
- matchTrunkPrefix(String a, int len) {
- boolean found;
-
- found = false;
-
- for (int i = 0 ; i < len ; i++) {
- char c = a.charAt(i);
-
- if (c == '0' && !found) {
- found = true;
- } else if (isNonSeparator(c)) {
- return false;
- }
- }
-
- return found;
- }
-
- /** all of 'a' up to len must be a (+|00|011)country code)
- * We're fast and loose with the country code. Any \d{1,3} matches */
- private static boolean
- matchIntlPrefixAndCC(String a, int len) {
- /* [^0-9*#+pwn]*(\+|0(0|11)\d\d?\d? [^0-9*#+pwn] $ */
- /* 0 1 2 3 45 6 7 8 */
-
- int state = 0;
- for (int i = 0 ; i < len ; i++ ) {
- char c = a.charAt(i);
-
- switch (state) {
- case 0:
- if (c == '+') state = 1;
- else if (c == '0') state = 2;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 2:
- if (c == '0') state = 3;
- else if (c == '1') state = 4;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 4:
- if (c == '1') state = 5;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 1:
- case 3:
- case 5:
- if (isISODigit(c)) state = 6;
- else if (isNonSeparator(c)) return false;
- break;
-
- case 6:
- case 7:
- if (isISODigit(c)) state++;
- else if (isNonSeparator(c)) return false;
- break;
-
- default:
- if (isNonSeparator(c)) return false;
- }
- }
-
- return state == 6 || state == 7 || state == 8;
- }
-
//================ Number formatting =========================
/** The current locale is unknown, look for a country code or don't format */
@@ -1553,4 +1612,317 @@
}
return retStr;
}
+
+ //===== Begining of utility methods used in compareLoosely() =====
+
+ /**
+ * Phone numbers are stored in "lookup" form in the database
+ * as reversed strings to allow for caller ID lookup
+ *
+ * This method takes a phone number and makes a valid SQL "LIKE"
+ * string that will match the lookup form
+ *
+ */
+ /** all of a up to len must be an international prefix or
+ * separators/non-dialing digits
+ */
+ private static boolean
+ matchIntlPrefix(String a, int len) {
+ /* '([^0-9*#+pwn]\+[^0-9*#+pwn] | [^0-9*#+pwn]0(0|11)[^0-9*#+pwn] )$' */
+ /* 0 1 2 3 45 */
+
+ int state = 0;
+ for (int i = 0 ; i < len ; i++) {
+ char c = a.charAt(i);
+
+ switch (state) {
+ case 0:
+ if (c == '+') state = 1;
+ else if (c == '0') state = 2;
+ else if (isNonSeparator(c)) return false;
+ break;
+
+ case 2:
+ if (c == '0') state = 3;
+ else if (c == '1') state = 4;
+ else if (isNonSeparator(c)) return false;
+ break;
+
+ case 4:
+ if (c == '1') state = 5;
+ else if (isNonSeparator(c)) return false;
+ break;
+
+ default:
+ if (isNonSeparator(c)) return false;
+ break;
+
+ }
+ }
+
+ return state == 1 || state == 3 || state == 5;
+ }
+
+ /** all of 'a' up to len must be a (+|00|011)country code)
+ * We're fast and loose with the country code. Any \d{1,3} matches */
+ private static boolean
+ matchIntlPrefixAndCC(String a, int len) {
+ /* [^0-9*#+pwn]*(\+|0(0|11)\d\d?\d? [^0-9*#+pwn] $ */
+ /* 0 1 2 3 45 6 7 8 */
+
+ int state = 0;
+ for (int i = 0 ; i < len ; i++ ) {
+ char c = a.charAt(i);
+
+ switch (state) {
+ case 0:
+ if (c == '+') state = 1;
+ else if (c == '0') state = 2;
+ else if (isNonSeparator(c)) return false;
+ break;
+
+ case 2:
+ if (c == '0') state = 3;
+ else if (c == '1') state = 4;
+ else if (isNonSeparator(c)) return false;
+ break;
+
+ case 4:
+ if (c == '1') state = 5;
+ else if (isNonSeparator(c)) return false;
+ break;
+
+ case 1:
+ case 3:
+ case 5:
+ if (isISODigit(c)) state = 6;
+ else if (isNonSeparator(c)) return false;
+ break;
+
+ case 6:
+ case 7:
+ if (isISODigit(c)) state++;
+ else if (isNonSeparator(c)) return false;
+ break;
+
+ default:
+ if (isNonSeparator(c)) return false;
+ }
+ }
+
+ return state == 6 || state == 7 || state == 8;
+ }
+
+ /** all of 'a' up to len must match non-US trunk prefix ('0') */
+ private static boolean
+ matchTrunkPrefix(String a, int len) {
+ boolean found;
+
+ found = false;
+
+ for (int i = 0 ; i < len ; i++) {
+ char c = a.charAt(i);
+
+ if (c == '0' && !found) {
+ found = true;
+ } else if (isNonSeparator(c)) {
+ return false;
+ }
+ }
+
+ return found;
+ }
+
+ //===== End of utility methods used only in compareLoosely() =====
+
+ //===== Beggining of utility methods used only in compareStrictly() ====
+
+ /*
+ * If true, the number is country calling code.
+ */
+ private static final boolean COUNTLY_CALLING_CALL[] = {
+ true, true, false, false, false, false, false, true, false, false,
+ false, false, false, false, false, false, false, false, false, false,
+ true, false, false, false, false, false, false, true, true, false,
+ true, true, true, true, true, false, true, false, false, true,
+ true, false, false, true, true, true, true, true, true, true,
+ false, true, true, true, true, true, true, true, true, false,
+ true, true, true, true, true, true, true, false, false, false,
+ false, false, false, false, false, false, false, false, false, false,
+ false, true, true, true, true, false, true, false, false, true,
+ true, true, true, true, true, true, false, false, true, false,
+ };
+ private static final int CCC_LENGTH = COUNTLY_CALLING_CALL.length;
+
+ /**
+ * @return true when input is valid Country Calling Code.
+ */
+ private static boolean isCountryCallingCode(int countryCallingCodeCandidate) {
+ return countryCallingCodeCandidate > 0 && countryCallingCodeCandidate < CCC_LENGTH &&
+ COUNTLY_CALLING_CALL[countryCallingCodeCandidate];
+ }
+
+ /**
+ * Returns interger corresponding to the input if input "ch" is
+ * ISO-LATIN characters 0-9.
+ * Returns -1 otherwise
+ */
+ private static int tryGetISODigit(char ch) {
+ if ('0' <= ch && ch <= '9') {
+ return ch - '0';
+ } else {
+ return -1;
+ }
+ }
+
+ private static class CountryCallingCodeAndNewIndex {
+ public final int countryCallingCode;
+ public final int newIndex;
+ public CountryCallingCodeAndNewIndex(int countryCode, int newIndex) {
+ this.countryCallingCode = countryCode;
+ this.newIndex = newIndex;
+ }
+ }
+
+ /*
+ * Note that this function does not strictly care the country calling code with
+ * 3 length (like Morocco: +212), assuming it is enough to use the first two
+ * digit to compare two phone numbers.
+ */
+ private static CountryCallingCodeAndNewIndex tryGetCountryCallingCodeAndNewIndex(
+ String str, boolean acceptThailandCase) {
+ // Rough regexp:
+ // ^[^0-9*#+]*((\+|0(0|11)\d\d?|166) [^0-9*#+] $
+ // 0 1 2 3 45 6 7 89
+ //
+ // In all the states, this function ignores separator characters.
+ // "166" is the special case for the call from Thailand to the US. Uguu!
+ int state = 0;
+ int ccc = 0;
+ final int length = str.length();
+ for (int i = 0 ; i < length ; i++ ) {
+ char ch = str.charAt(i);
+ switch (state) {
+ case 0:
+ if (ch == '+') state = 1;
+ else if (ch == '0') state = 2;
+ else if (ch == '1') {
+ if (acceptThailandCase) {
+ state = 8;
+ } else {
+ return null;
+ }
+ } else if (isDialable(ch)) {
+ return null;
+ }
+ break;
+
+ case 2:
+ if (ch == '0') state = 3;
+ else if (ch == '1') state = 4;
+ else if (isDialable(ch)) {
+ return null;
+ }
+ break;
+
+ case 4:
+ if (ch == '1') state = 5;
+ else if (isDialable(ch)) {
+ return null;
+ }
+ break;
+
+ case 1:
+ case 3:
+ case 5:
+ case 6:
+ case 7:
+ {
+ int ret = tryGetISODigit(ch);
+ if (ret > 0) {
+ ccc = ccc * 10 + ret;
+ if (ccc >= 100 || isCountryCallingCode(ccc)) {
+ return new CountryCallingCodeAndNewIndex(ccc, i + 1);
+ }
+ if (state == 1 || state == 3 || state == 5) {
+ state = 6;
+ } else {
+ state++;
+ }
+ } else if (isDialable(ch)) {
+ return null;
+ }
+ }
+ break;
+ case 8:
+ if (ch == '6') state = 9;
+ else if (isDialable(ch)) {
+ return null;
+ }
+ break;
+ case 9:
+ if (ch == '6') {
+ return new CountryCallingCodeAndNewIndex(66, i + 1);
+ } else {
+ return null;
+ }
+ default:
+ return null;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Currently this function simply ignore the first digit assuming it is
+ * trunk prefix. Actually trunk prefix is different in each country.
+ *
+ * e.g.
+ * "+79161234567" equals "89161234567" (Russian trunk digit is 8)
+ * "+33123456789" equals "0123456789" (French trunk digit is 0)
+ *
+ */
+ private static int tryGetTrunkPrefixOmittedIndex(String str, int currentIndex) {
+ int length = str.length();
+ for (int i = currentIndex ; i < length ; i++) {
+ final char ch = str.charAt(i);
+ if (tryGetISODigit(ch) >= 0) {
+ return i + 1;
+ } else if (isDialable(ch)) {
+ return -1;
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Return true if the prefix of "str" is "ignorable". Here, "ignorable" means
+ * that "str" has only one digit and separater characters. The one digit is
+ * assumed to be trunk prefix.
+ */
+ private static boolean checkPrefixIsIgnorable(final String str,
+ int forwardIndex, int backwardIndex) {
+ boolean trunk_prefix_was_read = false;
+ while (backwardIndex >= forwardIndex) {
+ if (tryGetISODigit(str.charAt(backwardIndex)) >= 0) {
+ if (trunk_prefix_was_read) {
+ // More than one digit appeared, meaning that "a" and "b"
+ // is different.
+ return false;
+ } else {
+ // Ignore just one digit, assuming it is trunk prefix.
+ trunk_prefix_was_read = true;
+ }
+ } else if (isDialable(str.charAt(backwardIndex))) {
+ // Trunk prefix is a digit, not "*", "#"...
+ return false;
+ }
+ backwardIndex--;
+ }
+
+ return true;
+ }
+
+ //==== End of utility methods used only in compareStrictly() =====
}
diff --git a/telephony/java/com/android/internal/telephony/Connection.java b/telephony/java/com/android/internal/telephony/Connection.java
index e6fd0a0..a48900a 100644
--- a/telephony/java/com/android/internal/telephony/Connection.java
+++ b/telephony/java/com/android/internal/telephony/Connection.java
@@ -15,6 +15,7 @@
*/
package com.android.internal.telephony;
+import android.util.Log;
/**
* {@hide}
@@ -27,6 +28,7 @@
public static int PRESENTATION_UNKNOWN = 3; // no specified or unknown by network
public static int PRESENTATION_PAYPHONE = 4; // show pay phone info
+ private static String LOG_TAG = "TelephonyConnection";
public enum DisconnectCause {
NOT_DISCONNECTED, /* has not yet disconnected */
@@ -269,4 +271,25 @@
*/
public abstract int getNumberPresentation();
+ /**
+ * Build a human representation of a connection instance, suitable for debugging.
+ * Don't log personal stuff unless in debug mode.
+ * @return a string representing the internal state of this connection.
+ */
+ public String toString() {
+ StringBuilder str = new StringBuilder(128);
+
+ if (Log.isLoggable(LOG_TAG, Log.DEBUG)) {
+ str.append("addr: " + getAddress())
+ .append(" pres.: " + getNumberPresentation())
+ .append(" dial: " + getOrigDialString())
+ .append(" postdial: " + getRemainingPostDialString())
+ .append(" cnap name: " + getCnapName())
+ .append("(" + getCnapNamePresentation() + ")");
+ }
+ str.append(" incoming: " + isIncoming())
+ .append(" state: " + getState())
+ .append(" post dial state: " + getPostDialState());
+ return str.toString();
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/SmsMessageBase.java b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
index 3f0213b..3c2f2ed 100644
--- a/telephony/java/com/android/internal/telephony/SmsMessageBase.java
+++ b/telephony/java/com/android/internal/telephony/SmsMessageBase.java
@@ -383,7 +383,7 @@
* 2. [x@y][ ]/[body]
*/
String[] parts = messageBody.split("( /)|( )", 2);
- if (parts.length < 1) return;
+ if (parts.length < 2) return;
emailFrom = parts[0];
emailBody = parts[1];
isEmail = true;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 2f4d238..bc04e02 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -221,10 +221,6 @@
return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
}
- public String
- toString() {
- return (isIncoming ? "incoming" : "outgoing");
- }
public String getOrigDialString(){
return dialString;
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
index 2091fb6..445be39 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmConnection.java
@@ -180,11 +180,6 @@
return isIncoming == c.isMT && equalsHandlesNulls(address, cAddress);
}
- public String
- toString() {
- return (isIncoming ? "incoming" : "outgoing");
- }
-
public String getAddress() {
return address;
}
diff --git a/test-runner/android/test/mock/MockContext.java b/test-runner/android/test/mock/MockContext.java
index 5368526..57b22f8 100644
--- a/test-runner/android/test/mock/MockContext.java
+++ b/test-runner/android/test/mock/MockContext.java
@@ -264,6 +264,13 @@
}
@Override
+ public void sendStickyOrderedBroadcast(Intent intent,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+ Bundle initialExtras) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
public void removeStickyBroadcast(Intent intent) {
throw new UnsupportedOperationException();
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
index 4e7e925..1e9f573 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
@@ -1099,6 +1099,13 @@
}
@Override
+ public void sendStickyOrderedBroadcast(Intent intent,
+ BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData,
+ Bundle initialExtras) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
public void setTheme(int arg0) {
// TODO Auto-generated method stub