Merge "Respond to RTSP server->client requests."
diff --git a/api/11.xml b/api/11.xml
index 61472a3..6a1f909 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -37266,17 +37266,6 @@
visibility="public"
>
</field>
-<field name="USES_POLICY_SETS_GLOBAL_PROXY"
- type="int"
- transient="false"
- volatile="false"
- value="5"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="USES_POLICY_WATCH_LOGIN"
type="int"
transient="false"
@@ -37592,17 +37581,6 @@
visibility="public"
>
</method>
-<method name="getGlobalProxyAdmin"
- return="android.content.ComponentName"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getMaximumFailedPasswordsForWipe"
return="int"
abstract="false"
@@ -37887,23 +37865,6 @@
<parameter name="flags" type="int">
</parameter>
</method>
-<method name="setGlobalProxy"
- return="android.content.ComponentName"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="admin" type="android.content.ComponentName">
-</parameter>
-<parameter name="proxySpec" type="java.net.Proxy">
-</parameter>
-<parameter name="exclusionList" type="java.util.List<java.lang.String>">
-</parameter>
-</method>
<method name="setMaximumFailedPasswordsForWipe"
return="void"
abstract="false"
diff --git a/api/current.xml b/api/current.xml
index 7806c24..1ce49d4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -37376,17 +37376,6 @@
visibility="public"
>
</field>
-<field name="USES_POLICY_SETS_GLOBAL_PROXY"
- type="int"
- transient="false"
- volatile="false"
- value="5"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="USES_POLICY_WATCH_LOGIN"
type="int"
transient="false"
@@ -37702,17 +37691,6 @@
visibility="public"
>
</method>
-<method name="getGlobalProxyAdmin"
- return="android.content.ComponentName"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
<method name="getMaximumFailedPasswordsForWipe"
return="int"
abstract="false"
@@ -37997,23 +37975,6 @@
<parameter name="flags" type="int">
</parameter>
</method>
-<method name="setGlobalProxy"
- return="android.content.ComponentName"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="admin" type="android.content.ComponentName">
-</parameter>
-<parameter name="proxySpec" type="java.net.Proxy">
-</parameter>
-<parameter name="exclusionList" type="java.util.List<java.lang.String>">
-</parameter>
-</method>
<method name="setMaximumFailedPasswordsForWipe"
return="void"
abstract="false"
@@ -94147,6 +94108,97 @@
>
</field>
</class>
+<class name="UsbAccessory"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getManufacturer"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getModel"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getType"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getVersion"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="parcel" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
<class name="UsbConstants"
extends="java.lang.Object"
abstract="false"
@@ -95097,6 +95149,17 @@
deprecated="not deprecated"
visibility="public"
>
+<method name="getAccessoryList"
+ return="android.hardware.UsbAccessory[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getDeviceList"
return="java.util.HashMap<java.lang.String, android.hardware.UsbDevice>"
abstract="false"
@@ -95134,6 +95197,19 @@
<parameter name="function" type="java.lang.String">
</parameter>
</method>
+<method name="openAccessory"
+ return="android.os.ParcelFileDescriptor"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="accessory" type="android.hardware.UsbAccessory">
+</parameter>
+</method>
<method name="openDevice"
return="boolean"
abstract="false"
@@ -95147,6 +95223,28 @@
<parameter name="device" type="android.hardware.UsbDevice">
</parameter>
</method>
+<field name="ACTION_USB_ACCESSORY_ATTACHED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.hardware.action.USB_ACCESSORY_ATTACHED""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ACTION_USB_ACCESSORY_DETACHED"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""android.hardware.action.USB_ACCESSORY_DETACHED""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="ACTION_USB_DEVICE_ATTACHED"
type="java.lang.String"
transient="false"
@@ -95180,6 +95278,61 @@
visibility="public"
>
</field>
+<field name="EXTRA_ACCESSORY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ACCESSORY_MANUFACTURER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory-manufacturer""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ACCESSORY_PRODUCT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory-product""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ACCESSORY_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory-type""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="EXTRA_ACCESSORY_VERSION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory-version""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="EXTRA_DEVICE"
type="java.lang.String"
transient="false"
@@ -95279,6 +95432,17 @@
visibility="public"
>
</field>
+<field name="USB_FUNCTION_ACCESSORY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""accessory""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="USB_FUNCTION_ADB"
type="java.lang.String"
transient="false"
@@ -117430,7 +117594,7 @@
type="android.net.http.SslCertificate"
static="false"
final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
visibility="public"
>
<parameter name="issuedTo" type="java.lang.String">
@@ -237424,7 +237588,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="s" type="java.lang.String">
+<parameter name="key" type="java.lang.String">
</parameter>
</method>
<method name="describeContents"
@@ -237459,7 +237623,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="s" type="java.lang.String">
+<parameter name="key" type="java.lang.String">
</parameter>
</method>
<method name="getIconResId"
@@ -265635,7 +265799,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java
index ec4ec89..1c7eb98 100644
--- a/core/java/android/app/admin/DeviceAdminInfo.java
+++ b/core/java/android/app/admin/DeviceAdminInfo.java
@@ -109,6 +109,7 @@
*
* <p>To control this policy, the device admin must have a "set-global-proxy"
* tag in the "uses-policies" section of its meta-data.
+ * @hide
*/
public static final int USES_POLICY_SETS_GLOBAL_PROXY = 5;
@@ -363,7 +364,7 @@
* the given policy control. The possible policy identifier inputs are:
* {@link #USES_POLICY_LIMIT_PASSWORD}, {@link #USES_POLICY_WATCH_LOGIN},
* {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK},
- * {@link #USES_POLICY_WIPE_DATA}, {@link #USES_POLICY_SETS_GLOBAL_PROXY},
+ * {@link #USES_POLICY_WIPE_DATA},
* {@link #USES_POLICY_EXPIRE_PASSWORD}, {@link #USES_ENCRYPTED_STORAGE}.
*/
public boolean usesPolicy(int policyIdent) {
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 3f3aa74..d71a7a3 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1028,6 +1028,7 @@
* @param exclusionList a list of domains to be excluded from the global proxy.
* @return returns null if the proxy was successfully set, or a {@link ComponentName}
* of the device admin that sets thew proxy otherwise.
+ * @hide
*/
public ComponentName setGlobalProxy(ComponentName admin, Proxy proxySpec,
List<String> exclusionList ) {
@@ -1080,6 +1081,7 @@
* Returns the component name setting the global proxy.
* @return ComponentName object of the device admin that set the global proxy, or
* null if no admin has set the proxy.
+ * @hide
*/
public ComponentName getGlobalProxyAdmin() {
if (mService != null) {
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 659b937..ebc1882 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -237,10 +237,28 @@
private BroadcastReceiver mConnectivityIntentReceiver =
new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
- sendCheckAlarmsMessage();
+ final boolean wasConnected = mDataConnectionIsConnected;
+
+ // don't use the intent to figure out if network is connected, just check
+ // ConnectivityManager directly.
+ mDataConnectionIsConnected = isNetworkConnected();
+ if (mDataConnectionIsConnected) {
+ if (!wasConnected) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Reconnection detected: clearing all backoffs");
+ }
+ mSyncStorageEngine.clearAllBackoffs(mSyncQueue);
+ }
+ sendCheckAlarmsMessage();
+ }
}
};
+ private boolean isNetworkConnected() {
+ NetworkInfo networkInfo = getConnectivityManager().getActiveNetworkInfo();
+ return (networkInfo != null) && networkInfo.isConnected();
+ }
+
private BroadcastReceiver mShutdownIntentReceiver =
new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
@@ -1411,8 +1429,7 @@
// to have the most recent value used.
try {
waitUntilReadyToRun();
- NetworkInfo networkInfo = getConnectivityManager().getActiveNetworkInfo();
- mDataConnectionIsConnected = (networkInfo != null) && networkInfo.isConnected();
+ mDataConnectionIsConnected = isNetworkConnected();
mSyncManagerWakeLock.acquire();
// Always do this first so that we be sure that any periodic syncs that
// are ready to run have been converted into pending syncs. This allows the
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index c8ca6189..a1e174b 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -525,7 +525,7 @@
}
}
- public void clearAllBackoffs() {
+ public void clearAllBackoffs(SyncQueue syncQueue) {
boolean changed = false;
synchronized (mAuthorities) {
for (AccountInfo accountInfo : mAccounts.values()) {
@@ -541,6 +541,7 @@
}
authorityInfo.backoffTime = NOT_IN_BACKOFF_MODE;
authorityInfo.backoffDelay = NOT_IN_BACKOFF_MODE;
+ syncQueue.onBackoffChanged(accountInfo.account, authorityInfo.authority, 0);
changed = true;
}
}
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index bfaeb82..3ffc714 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -133,6 +133,8 @@
result.getChars(0, result.length(), data, 0);
}
buffer.sizeCopied = result.length();
+ } else {
+ buffer.sizeCopied = 0;
}
}
diff --git a/core/java/android/hardware/IUsbManager.aidl b/core/java/android/hardware/IUsbManager.aidl
index b50b6b9..6c99ab3 100644
--- a/core/java/android/hardware/IUsbManager.aidl
+++ b/core/java/android/hardware/IUsbManager.aidl
@@ -16,6 +16,7 @@
package android.hardware;
+import android.hardware.UsbAccessory;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -25,4 +26,6 @@
/* Returns a list of all currently attached USB devices */
void getDeviceList(out Bundle devices);
ParcelFileDescriptor openDevice(String deviceName);
+ UsbAccessory getCurrentAccessory();
+ ParcelFileDescriptor openAccessory();
}
diff --git a/core/java/android/hardware/UsbAccessory.aidl b/core/java/android/hardware/UsbAccessory.aidl
new file mode 100644
index 0000000..97a777b
--- /dev/null
+++ b/core/java/android/hardware/UsbAccessory.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+parcelable UsbAccessory;
diff --git a/core/java/android/hardware/UsbAccessory.java b/core/java/android/hardware/UsbAccessory.java
new file mode 100644
index 0000000..71672fa
--- /dev/null
+++ b/core/java/android/hardware/UsbAccessory.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+/**
+ * A class representing a USB accessory.
+ */
+public final class UsbAccessory implements Parcelable {
+
+ private static final String TAG = "UsbAccessory";
+
+ private String mManufacturer;
+ private String mModel;
+ private String mType;
+ private String mVersion;
+
+ private UsbAccessory() {
+ }
+
+ /**
+ * UsbAccessory should only be instantiated by UsbService implementation
+ * @hide
+ */
+ public UsbAccessory(String manufacturer, String model, String type, String version) {
+ mManufacturer = manufacturer;
+ mModel = model;
+ mType = type;
+ mVersion = version;
+ }
+
+ /**
+ * UsbAccessory should only be instantiated by UsbService implementation
+ * @hide
+ */
+ public UsbAccessory(String[] strings) {
+ mManufacturer = strings[0];
+ mModel = strings[1];
+ mType = strings[2];
+ mVersion = strings[3];
+ }
+
+ /**
+ * Returns the manufacturer of the accessory.
+ *
+ * @return the accessory manufacturer
+ */
+ public String getManufacturer() {
+ return mManufacturer;
+ }
+
+ /**
+ * Returns the model name of the accessory.
+ *
+ * @return the accessory model
+ */
+ public String getModel() {
+ return mModel;
+ }
+
+ /**
+ * Returns the type of the accessory.
+ *
+ * @return the accessory type
+ */
+ public String getType() {
+ return mType;
+ }
+
+ /**
+ * Returns the version of the accessory.
+ *
+ * @return the accessory version
+ */
+ public String getVersion() {
+ return mVersion;
+ }
+
+ @Override
+ public String toString() {
+ return "UsbAccessory[mManufacturer=" + mManufacturer +
+ ", mModel=" + mModel +
+ ", mType=" + mType +
+ ", mVersion=" + mVersion + "]";
+ }
+
+ public static final Parcelable.Creator<UsbAccessory> CREATOR =
+ new Parcelable.Creator<UsbAccessory>() {
+ public UsbAccessory createFromParcel(Parcel in) {
+ String manufacturer = in.readString();
+ String model = in.readString();
+ String type = in.readString();
+ String version = in.readString();
+ return new UsbAccessory(manufacturer, model, type, version);
+ }
+
+ public UsbAccessory[] newArray(int size) {
+ return new UsbAccessory[size];
+ }
+ };
+
+ public int describeContents() {
+ return 0;
+ }
+
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeString(mManufacturer);
+ parcel.writeString(mModel);
+ parcel.writeString(mType);
+ parcel.writeString(mVersion);
+ }
+}
diff --git a/core/java/android/hardware/UsbManager.java b/core/java/android/hardware/UsbManager.java
index 8fad210..0f616ff 100644
--- a/core/java/android/hardware/UsbManager.java
+++ b/core/java/android/hardware/UsbManager.java
@@ -24,6 +24,7 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
@@ -44,11 +45,14 @@
* Broadcast Action: A sticky broadcast for USB state change events when in device mode.
*
* This is a sticky broadcast for clients that includes USB connected/disconnected state,
- * the USB configuration that is currently set and a bundle containing name/value pairs
- * with the names of the functions and a value of either {@link #USB_FUNCTION_ENABLED}
- * or {@link #USB_FUNCTION_DISABLED}.
- * Possible USB function names include {@link #USB_FUNCTION_MASS_STORAGE},
- * {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS} and {@link #USB_FUNCTION_MTP}.
+ * <ul>
+ * <li> {@link #USB_CONNECTED} boolean indicating whether USB is connected or disconnected.
+ * <li> {@link #USB_CONFIGURATION} a Bundle containing name/value pairs where the name
+ * is the name of a USB function and the value is either {@link #USB_FUNCTION_ENABLED}
+ * or {@link #USB_FUNCTION_DISABLED}. The possible function names include
+ * {@link #USB_FUNCTION_MASS_STORAGE}, {@link #USB_FUNCTION_ADB}, {@link #USB_FUNCTION_RNDIS},
+ * {@link #USB_FUNCTION_MTP} and {@link #USB_FUNCTION_ACCESSORY}.
+ * </ul>
*/
public static final String ACTION_USB_STATE =
"android.hardware.action.USB_STATE";
@@ -57,6 +61,16 @@
* Broadcast Action: A broadcast for USB device attached event.
*
* This intent is sent when a USB device is attached to the USB bus when in host mode.
+ * <ul>
+ * <li> {@link #EXTRA_DEVICE_NAME} containing the device's name (String)
+ * <li> {@link #EXTRA_VENDOR_ID} containing the device's vendor ID (Integer)
+ * <li> {@link #EXTRA_PRODUCT_ID} containing the device's product ID (Integer)
+ * <li> {@link #EXTRA_DEVICE_CLASS} } containing the device class (Integer)
+ * <li> {@link #EXTRA_DEVICE_SUBCLASS} containing the device subclass (Integer)
+ * <li> {@link #EXTRA_DEVICE_PROTOCOL} containing the device protocol (Integer)
+ * <li> {@link #EXTRA_DEVICE} containing the {@link android.hardware.UsbDevice}
+ * for the attached device
+ * </ul>
*/
public static final String ACTION_USB_DEVICE_ATTACHED =
"android.hardware.action.USB_DEVICE_ATTACHED";
@@ -65,10 +79,41 @@
* Broadcast Action: A broadcast for USB device detached event.
*
* This intent is sent when a USB device is detached from the USB bus when in host mode.
+ * <ul>
+ * <li> {@link #EXTRA_DEVICE_NAME} containing the device's name (String)
+ * </ul>
*/
public static final String ACTION_USB_DEVICE_DETACHED =
"android.hardware.action.USB_DEVICE_DETACHED";
+ /**
+ * Broadcast Action: A broadcast for USB accessory attached event.
+ *
+ * This intent is sent when a USB accessory is attached.
+ * <ul>
+ * <li> {@link #EXTRA_ACCESSORY_MANUFACTURER} containing the accessory's manufacturer (String)
+ * <li> {@link #EXTRA_ACCESSORY_PRODUCT} containing the accessory's product name (String)
+ * <li> {@link #EXTRA_ACCESSORY_TYPE} containing the accessory's type (String)
+ * <li> {@link #EXTRA_ACCESSORY_VERSION} containing the accessory's version (String)
+ * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.UsbAccessory}
+ * for the attached accessory
+ * </ul>
+ */
+ public static final String ACTION_USB_ACCESSORY_ATTACHED =
+ "android.hardware.action.USB_ACCESSORY_ATTACHED";
+
+ /**
+ * Broadcast Action: A broadcast for USB accessory detached event.
+ *
+ * This intent is sent when a USB accessory is detached.
+ * <ul>
+ * <li> {@link #EXTRA_ACCESSORY} containing the {@link android.hardware.UsbAccessory}
+ * for the attached accessory that was detached
+ * </ul>
+ */
+ public static final String ACTION_USB_ACCESSORY_DETACHED =
+ "android.hardware.action.USB_ACCESSORY_DETACHED";
+
/**
* Boolean extra indicating whether USB is connected or disconnected.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast.
@@ -106,14 +151,22 @@
public static final String USB_FUNCTION_MTP = "mtp";
/**
- * Value indicating that a USB function is enabled.
+ * Name of the Accessory USB function.
* Used in extras for the {@link #ACTION_USB_STATE} broadcast
*/
+ public static final String USB_FUNCTION_ACCESSORY = "accessory";
+
+ /**
+ * Value indicating that a USB function is enabled.
+ * Used in {@link #USB_CONFIGURATION} extras bundle for the
+ * {@link #ACTION_USB_STATE} broadcast
+ */
public static final String USB_FUNCTION_ENABLED = "enabled";
/**
* Value indicating that a USB function is disabled.
- * Used in extras for the {@link #ACTION_USB_STATE} broadcast
+ * Used in {@link #USB_CONFIGURATION} extras bundle for the
+ * {@link #ACTION_USB_STATE} broadcast
*/
public static final String USB_FUNCTION_DISABLED = "disabled";
@@ -158,8 +211,39 @@
* Name of extra for {@link #ACTION_USB_DEVICE_ATTACHED} broadcast
* containing the UsbDevice object for the device.
*/
+
public static final String EXTRA_DEVICE = "device";
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the UsbAccessory object for the accessory.
+ */
+ public static final String EXTRA_ACCESSORY = "accessory";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the accessory's manufacturer name.
+ */
+ public static final String EXTRA_ACCESSORY_MANUFACTURER = "accessory-manufacturer";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the accessory's product name.
+ */
+ public static final String EXTRA_ACCESSORY_PRODUCT = "accessory-product";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the accessory's type.
+ */
+ public static final String EXTRA_ACCESSORY_TYPE = "accessory-type";
+
+ /**
+ * Name of extra for {@link #ACTION_USB_ACCESSORY_ATTACHED} broadcast
+ * containing the accessory's version.
+ */
+ public static final String EXTRA_ACCESSORY_VERSION = "accessory-version";
+
private IUsbManager mService;
/**
@@ -214,6 +298,41 @@
}
}
+ /**
+ * Returns a list of currently attached USB accessories.
+ * (in the current implementation there can be at most one)
+ *
+ * @return list of USB accessories, or null if none are attached.
+ */
+ public UsbAccessory[] getAccessoryList() {
+ try {
+ UsbAccessory accessory = mService.getCurrentAccessory();
+ if (accessory == null) {
+ return null;
+ } else {
+ return new UsbAccessory[] { accessory };
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in openAccessory" , e);
+ return null;
+ }
+ }
+
+ /**
+ * Opens a file descriptor for reading and writing data to the USB accessory.
+ *
+ * @param accessory the USB accessory to open
+ * @return file descriptor, or null if the accessor could not be opened.
+ */
+ public ParcelFileDescriptor openAccessory(UsbAccessory accessory) {
+ try {
+ return mService.openAccessory();
+ } catch (RemoteException e) {
+ Log.e(TAG, "RemoteException in openAccessory" , e);
+ return null;
+ }
+ }
+
private static File getFunctionEnableFile(String function) {
return new File("/sys/class/usb_composite/" + function + "/enable");
}
@@ -245,4 +364,20 @@
return false;
}
}
+
+ /**
+ * Enables or disables a USB function.
+ *
+ * @hide
+ */
+ public static boolean setFunctionEnabled(String function, boolean enable) {
+ try {
+ FileOutputStream stream = new FileOutputStream(getFunctionEnableFile(function));
+ stream.write(enable ? '1' : '0');
+ stream.close();
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
}
diff --git a/core/java/android/net/http/SslCertificate.java b/core/java/android/net/http/SslCertificate.java
index bba11b0..5079c23 100644
--- a/core/java/android/net/http/SslCertificate.java
+++ b/core/java/android/net/http/SslCertificate.java
@@ -110,7 +110,7 @@
* @param issuedBy The entity that issued this certificate
* @param validNotBefore The not-before date from the certificate validity period in ISO 8601 format
* @param validNotAfter The not-after date from the certificate validity period in ISO 8601 format
- * @deprecated Use {@link #SslCertificate(String, String, Date, Date)}
+ * @deprecated Use {@link #SslCertificate(X509Certificate)}
*/
@Deprecated
public SslCertificate(
@@ -124,7 +124,9 @@
* @param issuedBy The entity that issued this certificate
* @param validNotBefore The not-before date from the certificate validity period
* @param validNotAfter The not-after date from the certificate validity period
+ * @deprecated Use {@link #SslCertificate(X509Certificate)}
*/
+ @Deprecated
public SslCertificate(
String issuedTo, String issuedBy, Date validNotBefore, Date validNotAfter) {
mIssuedTo = new DName(issuedTo);
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index ac3df79..a4546f0 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -36,8 +36,8 @@
* float, float, android.graphics.Paint)
* Canvas.drawText()} directly.</p>
*/
-public class StaticLayout extends Layout
-{
+public class StaticLayout extends Layout {
+
public StaticLayout(CharSequence source, TextPaint paint,
int width,
Alignment align, float spacingmult, float spacingadd,
@@ -114,8 +114,8 @@
mMeasured = MeasuredText.obtain();
}
- /* package */ void generate(CharSequence source, int bufstart, int bufend,
- TextPaint paint, int outerwidth,
+ /* package */ void generate(CharSequence source, int bufStart, int bufEnd,
+ TextPaint paint, int outerWidth,
Alignment align,
float spacingmult, float spacingadd,
boolean includepad, boolean trackpad,
@@ -126,7 +126,7 @@
boolean needMultiply = (spacingmult != 1 || spacingadd != 0);
Paint.FontMetricsInt fm = mFontMetricsInt;
- int[] choosehtv = null;
+ int[] chooseHtv = null;
MeasuredText measured = mMeasured;
@@ -137,27 +137,26 @@
int DEFAULT_DIR = DIR_LEFT_TO_RIGHT; // XXX
int paraEnd;
- for (int paraStart = bufstart; paraStart <= bufend; paraStart = paraEnd) {
- paraEnd = TextUtils.indexOf(source, '\n', paraStart, bufend);
+ for (int paraStart = bufStart; paraStart <= bufEnd; paraStart = paraEnd) {
+ paraEnd = TextUtils.indexOf(source, CHAR_NEW_LINE, paraStart, bufEnd);
if (paraEnd < 0)
- paraEnd = bufend;
+ paraEnd = bufEnd;
else
paraEnd++;
- int paraLen = paraEnd - paraStart;
int firstWidthLineLimit = mLineCount + 1;
- int firstwidth = outerwidth;
- int restwidth = outerwidth;
+ int firstWidth = outerWidth;
+ int restWidth = outerWidth;
- LineHeightSpan[] chooseht = null;
+ LineHeightSpan[] chooseHt = null;
if (spanned != null) {
LeadingMarginSpan[] sp = getParagraphSpans(spanned, paraStart, paraEnd,
LeadingMarginSpan.class);
for (int i = 0; i < sp.length; i++) {
LeadingMarginSpan lms = sp[i];
- firstwidth -= sp[i].getLeadingMargin(true);
- restwidth -= sp[i].getLeadingMargin(false);
+ firstWidth -= sp[i].getLeadingMargin(true);
+ restWidth -= sp[i].getLeadingMargin(false);
// LeadingMarginSpan2 is odd. The count affects all
// leading margin spans, not just this particular one,
@@ -166,32 +165,31 @@
if (lms instanceof LeadingMarginSpan2) {
LeadingMarginSpan2 lms2 = (LeadingMarginSpan2) lms;
int lmsFirstLine = getLineForOffset(spanned.getSpanStart(lms2));
- firstWidthLineLimit = lmsFirstLine +
- lms2.getLeadingMarginLineCount();
+ firstWidthLineLimit = lmsFirstLine + lms2.getLeadingMarginLineCount();
}
}
- chooseht = getParagraphSpans(spanned, paraStart, paraEnd, LineHeightSpan.class);
+ chooseHt = getParagraphSpans(spanned, paraStart, paraEnd, LineHeightSpan.class);
- if (chooseht.length != 0) {
- if (choosehtv == null ||
- choosehtv.length < chooseht.length) {
- choosehtv = new int[ArrayUtils.idealIntArraySize(
- chooseht.length)];
+ if (chooseHt.length != 0) {
+ if (chooseHtv == null ||
+ chooseHtv.length < chooseHt.length) {
+ chooseHtv = new int[ArrayUtils.idealIntArraySize(
+ chooseHt.length)];
}
- for (int i = 0; i < chooseht.length; i++) {
- int o = spanned.getSpanStart(chooseht[i]);
+ for (int i = 0; i < chooseHt.length; i++) {
+ int o = spanned.getSpanStart(chooseHt[i]);
if (o < paraStart) {
// starts in this layout, before the
// current paragraph
- choosehtv[i] = getLineTop(getLineForOffset(o));
+ chooseHtv[i] = getLineTop(getLineForOffset(o));
} else {
// starts in this paragraph
- choosehtv[i] = v;
+ chooseHtv[i] = v;
}
}
}
@@ -204,20 +202,18 @@
int dir = measured.mDir;
boolean easy = measured.mEasy;
- CharSequence sub = source;
-
- int width = firstwidth;
+ int width = firstWidth;
float w = 0;
int here = paraStart;
int ok = paraStart;
- float okwidth = w;
- int okascent = 0, okdescent = 0, oktop = 0, okbottom = 0;
+ float okWidth = w;
+ int okAscent = 0, okDescent = 0, okTop = 0, okBottom = 0;
int fit = paraStart;
- float fitwidth = w;
- int fitascent = 0, fitdescent = 0, fittop = 0, fitbottom = 0;
+ float fitWidth = w;
+ int fitAscent = 0, fitDescent = 0, fitTop = 0, fitBottom = 0;
boolean hasTabOrEmoji = false;
boolean hasTab = false;
@@ -244,21 +240,18 @@
}
nextSpanStart = spanEnd;
- int startInPara = spanStart - paraStart;
- int endInPara = spanEnd - paraStart;
- int fmtop = fm.top;
- int fmbottom = fm.bottom;
- int fmascent = fm.ascent;
- int fmdescent = fm.descent;
+ int fmTop = fm.top;
+ int fmBottom = fm.bottom;
+ int fmAscent = fm.ascent;
+ int fmDescent = fm.descent;
for (int j = spanStart; j < spanEnd; j++) {
char c = chs[j - paraStart];
- float before = w;
- if (c == '\n') {
+ if (c == CHAR_NEW_LINE) {
// intentionally left empty
- } else if (c == '\t') {
+ } else if (c == CHAR_TAB) {
if (hasTab == false) {
hasTab = true;
hasTabOrEmoji = true;
@@ -276,7 +269,8 @@
} else {
w = TabStops.nextDefaultStop(w, TAB_INCREMENT);
}
- } else if (c >= 0xD800 && c <= 0xDFFF && j + 1 < spanEnd) {
+ } else if (c >= CHAR_FIRST_HIGH_SURROGATE && c <= CHAR_LAST_LOW_SURROGATE
+ && j + 1 < spanEnd) {
int emoji = Character.codePointAt(chs, j - paraStart);
if (emoji >= MIN_EMOJI && emoji <= MAX_EMOJI) {
@@ -311,17 +305,17 @@
// Log.e("text", "was " + before + " now " + w + " after " + c + " within " + width);
if (w <= width) {
- fitwidth = w;
+ fitWidth = w;
fit = j + 1;
- if (fmtop < fittop)
- fittop = fmtop;
- if (fmascent < fitascent)
- fitascent = fmascent;
- if (fmdescent > fitdescent)
- fitdescent = fmdescent;
- if (fmbottom > fitbottom)
- fitbottom = fmbottom;
+ if (fmTop < fitTop)
+ fitTop = fmTop;
+ if (fmAscent < fitAscent)
+ fitAscent = fmAscent;
+ if (fmDescent > fitDescent)
+ fitDescent = fmDescent;
+ if (fmBottom > fitBottom)
+ fitBottom = fmBottom;
/*
* From the Unicode Line Breaking Algorithm:
@@ -339,25 +333,26 @@
* after but not before.
*/
- if (c == ' ' || c == '\t' ||
- ((c == '.' || c == ',' || c == ':' || c == ';') &&
+ if (c == CHAR_SPACE || c == CHAR_TAB ||
+ ((c == CHAR_DOT || c == CHAR_COMMA ||
+ c == CHAR_COLON || c == CHAR_SEMICOLON) &&
(j - 1 < here || !Character.isDigit(chs[j - 1 - paraStart])) &&
(j + 1 >= spanEnd || !Character.isDigit(chs[j + 1 - paraStart]))) ||
- ((c == '/' || c == '-') &&
+ ((c == CHAR_SLASH || c == CHAR_HYPHEN) &&
(j + 1 >= spanEnd || !Character.isDigit(chs[j + 1 - paraStart]))) ||
- (c >= FIRST_CJK && isIdeographic(c, true) &&
+ (c >= CHAR_FIRST_CJK && isIdeographic(c, true) &&
j + 1 < spanEnd && isIdeographic(chs[j + 1 - paraStart], false))) {
- okwidth = w;
+ okWidth = w;
ok = j + 1;
- if (fittop < oktop)
- oktop = fittop;
- if (fitascent < okascent)
- okascent = fitascent;
- if (fitdescent > okdescent)
- okdescent = fitdescent;
- if (fitbottom > okbottom)
- okbottom = fitbottom;
+ if (fitTop < okTop)
+ okTop = fitTop;
+ if (fitAscent < okAscent)
+ okAscent = fitAscent;
+ if (fitDescent > okDescent)
+ okDescent = fitDescent;
+ if (fitBottom > okBottom)
+ okBottom = fitBottom;
}
} else {
if (ellipsize != null) {
@@ -365,56 +360,56 @@
if (ok != here) {
// Log.e("text", "output ok " + here + " to " +ok);
- while (ok < spanEnd && chs[ok - paraStart] == ' ') {
+ while (ok < spanEnd && chs[ok - paraStart] == CHAR_SPACE) {
ok++;
}
v = out(source,
here, ok,
- okascent, okdescent, oktop, okbottom,
+ okAscent, okDescent, okTop, okBottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- ok == bufend, includepad, trackpad,
+ ok == bufEnd, includepad, trackpad,
chs, widths, here - paraStart,
- ellipsize, ellipsizedWidth, okwidth,
+ ellipsize, ellipsizedWidth, okWidth,
paint);
here = ok;
} else {
// Act like it fit even though it didn't.
- fitwidth = w;
+ fitWidth = w;
here = fit = j + 1;
- if (fmtop < fittop)
- fittop = fmtop;
- if (fmascent < fitascent)
- fitascent = fmascent;
- if (fmdescent > fitdescent)
- fitdescent = fmdescent;
- if (fmbottom > fitbottom)
- fitbottom = fmbottom;
+ if (fmTop < fitTop)
+ fitTop = fmTop;
+ if (fmAscent < fitAscent)
+ fitAscent = fmAscent;
+ if (fmDescent > fitDescent)
+ fitDescent = fmDescent;
+ if (fmBottom > fitBottom)
+ fitBottom = fmBottom;
}
} else {
if (ok != here) {
// Log.e("text", "output ok " + here + " to " +ok);
- while (ok < spanEnd && chs[ok - paraStart] == ' ') {
+ while (ok < spanEnd && chs[ok - paraStart] == CHAR_SPACE) {
ok++;
}
v = out(source,
here, ok,
- okascent, okdescent, oktop, okbottom,
+ okAscent, okDescent, okTop, okBottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- ok == bufend, includepad, trackpad,
+ ok == bufEnd, includepad, trackpad,
chs, widths, here - paraStart,
- ellipsize, ellipsizedWidth, okwidth,
+ ellipsize, ellipsizedWidth, okWidth,
paint);
here = ok;
@@ -422,15 +417,15 @@
// Log.e("text", "output fit " + here + " to " +fit);
v = out(source,
here, fit,
- fitascent, fitdescent,
- fittop, fitbottom,
+ fitAscent, fitDescent,
+ fitTop, fitBottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- fit == bufend, includepad, trackpad,
+ fit == bufEnd, includepad, trackpad,
chs, widths, here - paraStart,
- ellipsize, ellipsizedWidth, fitwidth,
+ ellipsize, ellipsizedWidth, fitWidth,
paint);
here = fit;
@@ -446,10 +441,10 @@
fm.ascent, fm.descent,
fm.top, fm.bottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- here + 1 == bufend, includepad,
+ here + 1 == bufEnd, includepad,
trackpad,
chs, widths, here - paraStart,
ellipsize, ellipsizedWidth,
@@ -470,65 +465,64 @@
ok = fit = here;
w = 0;
- fitascent = fitdescent = fittop = fitbottom = 0;
- okascent = okdescent = oktop = okbottom = 0;
+ fitAscent = fitDescent = fitTop = fitBottom = 0;
+ okAscent = okDescent = okTop = okBottom = 0;
if (--firstWidthLineLimit <= 0) {
- width = restwidth;
+ width = restWidth;
}
}
}
}
if (paraEnd != here) {
- if ((fittop | fitbottom | fitdescent | fitascent) == 0) {
+ if ((fitTop | fitBottom | fitDescent | fitAscent) == 0) {
paint.getFontMetricsInt(fm);
- fittop = fm.top;
- fitbottom = fm.bottom;
- fitascent = fm.ascent;
- fitdescent = fm.descent;
+ fitTop = fm.top;
+ fitBottom = fm.bottom;
+ fitAscent = fm.ascent;
+ fitDescent = fm.descent;
}
// Log.e("text", "output rest " + here + " to " + end);
v = out(source,
- here, paraEnd, fitascent, fitdescent,
- fittop, fitbottom,
+ here, paraEnd, fitAscent, fitDescent,
+ fitTop, fitBottom,
v,
- spacingmult, spacingadd, chooseht,
- choosehtv, fm, hasTabOrEmoji,
+ spacingmult, spacingadd, chooseHt,
+ chooseHtv, fm, hasTabOrEmoji,
needMultiply, paraStart, chdirs, dir, easy,
- paraEnd == bufend, includepad, trackpad,
+ paraEnd == bufEnd, includepad, trackpad,
chs, widths, here - paraStart,
ellipsize, ellipsizedWidth, w, paint);
}
paraStart = paraEnd;
- if (paraEnd == bufend)
+ if (paraEnd == bufEnd)
break;
}
- if (bufend == bufstart || source.charAt(bufend - 1) == '\n') {
- // Log.e("text", "output last " + bufend);
+ if (bufEnd == bufStart || source.charAt(bufEnd - 1) == CHAR_NEW_LINE) {
+ // Log.e("text", "output last " + bufEnd);
paint.getFontMetricsInt(fm);
v = out(source,
- bufend, bufend, fm.ascent, fm.descent,
+ bufEnd, bufEnd, fm.ascent, fm.descent,
fm.top, fm.bottom,
v,
spacingmult, spacingadd, null,
null, fm, false,
- needMultiply, bufend, null, DEFAULT_DIR, true,
+ needMultiply, bufEnd, null, DEFAULT_DIR, true,
true, includepad, trackpad,
- null, null, bufstart,
+ null, null, bufStart,
ellipsize, ellipsizedWidth, 0, paint);
}
}
- private static final char FIRST_CJK = '\u2E80';
/**
* Returns true if the specified character is one of those specified
* as being Ideographic (class ID) by the Unicode Line Breaking Algorithm
@@ -636,14 +630,14 @@
private int out(CharSequence text, int start, int end,
int above, int below, int top, int bottom, int v,
float spacingmult, float spacingadd,
- LineHeightSpan[] chooseht, int[] choosehtv,
+ LineHeightSpan[] chooseHt, int[] chooseHtv,
Paint.FontMetricsInt fm, boolean hasTabOrEmoji,
boolean needMultiply, int pstart, byte[] chdirs,
int dir, boolean easy, boolean last,
- boolean includepad, boolean trackpad,
- char[] chs, float[] widths, int widstart,
- TextUtils.TruncateAt ellipsize, float ellipsiswidth,
- float textwidth, TextPaint paint) {
+ boolean includePad, boolean trackPad,
+ char[] chs, float[] widths, int widthStart,
+ TextUtils.TruncateAt ellipsize, float ellipsisWidth,
+ float textWidth, TextPaint paint) {
int j = mLineCount;
int off = j * mColumns;
int want = off + mColumns + TOP;
@@ -662,19 +656,19 @@
mLineDirections = grow2;
}
- if (chooseht != null) {
+ if (chooseHt != null) {
fm.ascent = above;
fm.descent = below;
fm.top = top;
fm.bottom = bottom;
- for (int i = 0; i < chooseht.length; i++) {
- if (chooseht[i] instanceof LineHeightSpan.WithDensity) {
- ((LineHeightSpan.WithDensity) chooseht[i]).
- chooseHeight(text, start, end, choosehtv[i], v, fm, paint);
+ for (int i = 0; i < chooseHt.length; i++) {
+ if (chooseHt[i] instanceof LineHeightSpan.WithDensity) {
+ ((LineHeightSpan.WithDensity) chooseHt[i]).
+ chooseHeight(text, start, end, chooseHtv[i], v, fm, paint);
} else {
- chooseht[i].chooseHeight(text, start, end, choosehtv[i], v, fm);
+ chooseHt[i].chooseHeight(text, start, end, chooseHtv[i], v, fm);
}
}
@@ -685,20 +679,20 @@
}
if (j == 0) {
- if (trackpad) {
+ if (trackPad) {
mTopPadding = top - above;
}
- if (includepad) {
+ if (includePad) {
above = top;
}
}
if (last) {
- if (trackpad) {
+ if (trackPad) {
mBottomPadding = bottom - below;
}
- if (includepad) {
+ if (includePad) {
below = bottom;
}
}
@@ -708,9 +702,9 @@
if (needMultiply) {
double ex = (below - above) * (spacingmult - 1) + spacingadd;
if (ex >= 0) {
- extra = (int)(ex + 0.5);
+ extra = (int)(ex + EXTRA_ROUNDING);
} else {
- extra = -(int)(-ex + 0.5);
+ extra = -(int)(-ex + EXTRA_ROUNDING);
}
} else {
extra = 0;
@@ -735,45 +729,45 @@
if (easy) {
mLineDirections[j] = linedirs;
} else {
- mLineDirections[j] = AndroidBidi.directions(dir, chdirs, widstart, chs,
- widstart, end - start);
+ mLineDirections[j] = AndroidBidi.directions(dir, chdirs, widthStart, chs,
+ widthStart, end - start);
}
// If ellipsize is in marquee mode, do not apply ellipsis on the first line
if (ellipsize != null && (ellipsize != TextUtils.TruncateAt.MARQUEE || j != 0)) {
- calculateEllipsis(start, end, widths, widstart,
- ellipsiswidth, ellipsize, j,
- textwidth, paint);
+ calculateEllipsis(start, end, widths, widthStart,
+ ellipsisWidth, ellipsize, j,
+ textWidth, paint);
}
mLineCount++;
return v;
}
- private void calculateEllipsis(int linestart, int lineend,
- float[] widths, int widstart,
+ private void calculateEllipsis(int lineStart, int lineEnd,
+ float[] widths, int widthStart,
float avail, TextUtils.TruncateAt where,
- int line, float textwidth, TextPaint paint) {
+ int line, float textWidth, TextPaint paint) {
- if (textwidth <= avail) {
+ if (textWidth <= avail) {
// Everything fits!
mLines[mColumns * line + ELLIPSIS_START] = 0;
mLines[mColumns * line + ELLIPSIS_COUNT] = 0;
return;
}
- float ellipsiswid = paint.measureText("\u2026");
+ float ellipsisWidth = paint.measureText(HORIZONTAL_ELLIPSIS);
int ellipsisStart, ellipsisCount;
- int len = lineend - linestart;
+ int len = lineEnd - lineStart;
if (where == TextUtils.TruncateAt.START) {
float sum = 0;
int i;
for (i = len; i >= 0; i--) {
- float w = widths[i - 1 + linestart - widstart];
+ float w = widths[i - 1 + lineStart - widthStart];
- if (w + sum + ellipsiswid > avail) {
+ if (w + sum + ellipsisWidth > avail) {
break;
}
@@ -787,9 +781,9 @@
int i;
for (i = 0; i < len; i++) {
- float w = widths[i + linestart - widstart];
+ float w = widths[i + lineStart - widthStart];
- if (w + sum + ellipsiswid > avail) {
+ if (w + sum + ellipsisWidth > avail) {
break;
}
@@ -802,9 +796,9 @@
float lsum = 0, rsum = 0;
int left = 0, right = len;
- float ravail = (avail - ellipsiswid) / 2;
+ float ravail = (avail - ellipsisWidth) / 2;
for (right = len; right >= 0; right--) {
- float w = widths[right - 1 + linestart - widstart];
+ float w = widths[right - 1 + lineStart - widthStart];
if (w + rsum > ravail) {
break;
@@ -813,9 +807,9 @@
rsum += w;
}
- float lavail = avail - ellipsiswid - rsum;
+ float lavail = avail - ellipsisWidth - rsum;
for (left = 0; left < right; left++) {
- float w = widths[left + linestart - widstart];
+ float w = widths[left + lineStart - widthStart];
if (w + lsum > lavail) {
break;
@@ -968,6 +962,24 @@
private static final int TAB_INCREMENT = 20; // same as Layout, but that's private
+ private static final char CHAR_FIRST_CJK = '\u2E80';
+
+ private static final char CHAR_NEW_LINE = '\n';
+ private static final char CHAR_TAB = '\t';
+ private static final char CHAR_SPACE = ' ';
+ private static final char CHAR_DOT = '.';
+ private static final char CHAR_COMMA = ',';
+ private static final char CHAR_COLON = ':';
+ private static final char CHAR_SEMICOLON = ';';
+ private static final char CHAR_SLASH = '/';
+ private static final char CHAR_HYPHEN = '-';
+
+ private static final double EXTRA_ROUNDING = 0.5;
+ private static final String HORIZONTAL_ELLIPSIS = "\u2026"; // this is "..."
+
+ private static final int CHAR_FIRST_HIGH_SURROGATE = 0xD800;
+ private static final int CHAR_LAST_LOW_SURROGATE = 0xDFFF;
+
/*
* This is reused across calls to generate()
*/
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 3aebd00..de624e0 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -791,14 +791,19 @@
// scaleAll(), we need to post a Runnable to ensure requestLayout().
// Additionally, only update the text wrap scale if the width changed.
mWebView.post(new PostScale(w != ow &&
- !mWebView.getSettings().getUseFixedViewport()));
+ !mWebView.getSettings().getUseFixedViewport(), mInZoomOverview));
}
private class PostScale implements Runnable {
final boolean mUpdateTextWrap;
+ // Remember the zoom overview state right after rotation since
+ // it could be changed between the time this callback is initiated and
+ // the time it's actually run.
+ final boolean mInZoomOverviewBeforeSizeChange;
- public PostScale(boolean updateTextWrap) {
+ public PostScale(boolean updateTextWrap, boolean inZoomOverview) {
mUpdateTextWrap = updateTextWrap;
+ mInZoomOverviewBeforeSizeChange = inZoomOverview;
}
public void run() {
@@ -807,7 +812,7 @@
// still want to send the notification over to webkit.
// Keep overview mode unchanged when rotating.
final float zoomOverviewScale = getZoomOverviewScale();
- final float newScale = (mInZoomOverview) ?
+ final float newScale = (mInZoomOverviewBeforeSizeChange) ?
zoomOverviewScale : Math.max(mActualScale, zoomOverviewScale);
setZoomScale(newScale, mUpdateTextWrap, true);
// update the zoom buttons as the scale can be changed
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 8e8383a..1df6fe5 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -82,9 +82,9 @@
<protected-broadcast android:name="android.bluetooth.device.action.PAIRING_REQUEST" />
<protected-broadcast android:name="android.bluetooth.device.action.PAIRING_CANCEL" />
- <protected-broadcast android:name="android.hardware.action.USB_CONNECTED" />
- <protected-broadcast android:name="android.hardware.action.USB_DISCONNECTED" />
<protected-broadcast android:name="android.hardware.action.USB_STATE" />
+ <protected-broadcast android:name="android.hardware.action.USB_ACCESSORY_ATTACHED" />
+ <protected-broadcast android:name="android.hardware.action.USB_ACCESSORY_ATTACHED" />
<protected-broadcast android:name="android.hardware.action.USB_DEVICE_ATTACHED" />
<protected-broadcast android:name="android.hardware.action.USB_DEVICE_DETACHED" />
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index e0b67f62..92230a9 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -70,7 +70,7 @@
</a> <span class="new">new!</span></li>
<li><a href="<?cs var:toroot ?>guide/topics/fundamentals/tasks-and-back-stack.html">
<span class="en">Tasks and Back Stack</span>
- </a></li>
+ </a> <span class="new">new!</span></li>
</ul>
</li>
<li class="toggle-list">
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 0c57527..2248752 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -129,16 +129,17 @@
'sdk': {
'layout':"imgLeft",
'icon':"sdk-small.png",
- 'name':"Android 2.3.3",
- 'img':"gingerdroid.png",
- 'title':"Android 2.3.3, more NFC!",
- 'desc': "<p>Android 2.3.3 is now available for the Android SDK. "
-+ "This update adds new NFC capabilities for developers, including advanced tag dispatching APIs "
-+ "and the ability to write to tags.</p>"
-+ "<p>The new APIs enable exciting new applications, such as for ticketing, "
-+ "ratings, check-ins, advertising, and data exchange with other devices. "
-+ "For more information about Android 2.3.3, read the "
-+ "<a href='/sdk/android-2.3.3.html'>version notes</a>.</p>"
+ 'name':"Android 3.0",
+ 'img':"honeycomb-android.png",
+ 'title':"Android 3.0 is here!",
+ 'desc': "<p>Android 3.0 is now available for the Android SDK. It offers a redesigned UI and "
++ "all new developer APIs for an optimized experience on tablets and similar devices. "
++ "For more information about what's in Android 3.0, read the "
++ "<a href='{@docRoot}sdk/android-3.0.html'>version notes</a>.</p>"
++ "<p>If you have an existing SDK, add Android 3.0 as an "
++ "<a href='{@docRoot}sdk/adding-components.html'>SDK "
++ "component</a>. If you're new to Android, install the "
++ "<a href='{@docRoot}sdk/index.html'>SDK starter package</a>."
},
'tv': {
diff --git a/docs/html/resources/articles/avoiding-memory-leaks.jd b/docs/html/resources/articles/avoiding-memory-leaks.jd
index 3361bc1..395f590 100644
--- a/docs/html/resources/articles/avoiding-memory-leaks.jd
+++ b/docs/html/resources/articles/avoiding-memory-leaks.jd
@@ -1,4 +1,6 @@
page.title=Avoiding Memory Leaks
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/backward-compatibility.jd b/docs/html/resources/articles/backward-compatibility.jd
index ad64dfc..f96d587 100644
--- a/docs/html/resources/articles/backward-compatibility.jd
+++ b/docs/html/resources/articles/backward-compatibility.jd
@@ -1,4 +1,6 @@
page.title=Backward Compatibility for Applications
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/can-i-use-this-intent.jd b/docs/html/resources/articles/can-i-use-this-intent.jd
index a726189..c527331 100644
--- a/docs/html/resources/articles/can-i-use-this-intent.jd
+++ b/docs/html/resources/articles/can-i-use-this-intent.jd
@@ -1,4 +1,6 @@
page.title=Can I Use this Intent?
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Android offers a very powerful and yet easy-to-use message type called
diff --git a/docs/html/resources/articles/contacts.jd b/docs/html/resources/articles/contacts.jd
index c837dc3..8365d29 100644
--- a/docs/html/resources/articles/contacts.jd
+++ b/docs/html/resources/articles/contacts.jd
@@ -1,4 +1,6 @@
page.title=Using the Contacts API
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Starting from Android 2.0 (API Level 5), the Android platform provides an
diff --git a/docs/html/resources/articles/creating-input-method.jd b/docs/html/resources/articles/creating-input-method.jd
index 6f932df..e4b77f4 100644
--- a/docs/html/resources/articles/creating-input-method.jd
+++ b/docs/html/resources/articles/creating-input-method.jd
@@ -1,4 +1,6 @@
page.title=Creating an Input Method
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/drawable-mutations.jd b/docs/html/resources/articles/drawable-mutations.jd
index f979829..c5818fc 100644
--- a/docs/html/resources/articles/drawable-mutations.jd
+++ b/docs/html/resources/articles/drawable-mutations.jd
@@ -1,4 +1,6 @@
page.title=Drawable Mutations
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Android's drawables are extremely useful to easily build applications. A
diff --git a/docs/html/resources/articles/faster-screen-orientation-change.jd b/docs/html/resources/articles/faster-screen-orientation-change.jd
index f82e592..52531bb 100644
--- a/docs/html/resources/articles/faster-screen-orientation-change.jd
+++ b/docs/html/resources/articles/faster-screen-orientation-change.jd
@@ -1,4 +1,6 @@
page.title=Faster Screen Orientation Change
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/future-proofing.jd b/docs/html/resources/articles/future-proofing.jd
index ee98186..b8aeedf 100644
--- a/docs/html/resources/articles/future-proofing.jd
+++ b/docs/html/resources/articles/future-proofing.jd
@@ -1,4 +1,6 @@
page.title=Future-Proofing Your Apps
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>It's important to implement your application so that it will not break as new
diff --git a/docs/html/resources/articles/gestures.jd b/docs/html/resources/articles/gestures.jd
index 8711645b..5b8d760 100644
--- a/docs/html/resources/articles/gestures.jd
+++ b/docs/html/resources/articles/gestures.jd
@@ -1,4 +1,6 @@
page.title=Gestures
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Touch screens are a great way to interact with applications on
diff --git a/docs/html/resources/articles/glsurfaceview.jd b/docs/html/resources/articles/glsurfaceview.jd
index 57403ea..45407a9 100644
--- a/docs/html/resources/articles/glsurfaceview.jd
+++ b/docs/html/resources/articles/glsurfaceview.jd
@@ -1,4 +1,6 @@
page.title=Introducing GLSurfaceView
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/index.jd b/docs/html/resources/articles/index.jd
index d2b7645..220a4ed 100644
--- a/docs/html/resources/articles/index.jd
+++ b/docs/html/resources/articles/index.jd
@@ -1,4 +1,6 @@
page.title=Technical Articles
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<dl>
diff --git a/docs/html/resources/articles/layout-tricks-efficiency.jd b/docs/html/resources/articles/layout-tricks-efficiency.jd
index b7b5761..00b4147 100644
--- a/docs/html/resources/articles/layout-tricks-efficiency.jd
+++ b/docs/html/resources/articles/layout-tricks-efficiency.jd
@@ -1,4 +1,6 @@
page.title=Layout Tricks: Creating Efficient Layouts
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>The Android UI toolkit offers several layout managers that are
diff --git a/docs/html/resources/articles/layout-tricks-merge.jd b/docs/html/resources/articles/layout-tricks-merge.jd
index 95409e4..0ca0317 100644
--- a/docs/html/resources/articles/layout-tricks-merge.jd
+++ b/docs/html/resources/articles/layout-tricks-merge.jd
@@ -1,4 +1,6 @@
page.title=Layout Tricks: Merging Layouts
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>The articles showed you how to use the <code><include /></code> tag in XML layouts, to
diff --git a/docs/html/resources/articles/layout-tricks-reuse.jd b/docs/html/resources/articles/layout-tricks-reuse.jd
index 396e2127..179c1d8 100644
--- a/docs/html/resources/articles/layout-tricks-reuse.jd
+++ b/docs/html/resources/articles/layout-tricks-reuse.jd
@@ -1,4 +1,6 @@
page.title=Layout Tricks: Creating Reusable UI Components
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>The Android platform offers a wide variety of UI <em>widgets</em>, small
diff --git a/docs/html/resources/articles/layout-tricks-stubs.jd b/docs/html/resources/articles/layout-tricks-stubs.jd
index 88bcb78..64f07f9 100644
--- a/docs/html/resources/articles/layout-tricks-stubs.jd
+++ b/docs/html/resources/articles/layout-tricks-stubs.jd
@@ -1,4 +1,6 @@
page.title=Layout Tricks: Using ViewStubs
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Sharing and reusing UI components is very easy with Android, thanks to the <a
diff --git a/docs/html/resources/articles/listview-backgrounds.jd b/docs/html/resources/articles/listview-backgrounds.jd
index f4c6998..c4037ba 100644
--- a/docs/html/resources/articles/listview-backgrounds.jd
+++ b/docs/html/resources/articles/listview-backgrounds.jd
@@ -1,4 +1,6 @@
page.title=ListView Backgrounds: An Optimization
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>{@link android.widget.ListView} is one of Android's most widely used widgets.
diff --git a/docs/html/resources/articles/live-folders.jd b/docs/html/resources/articles/live-folders.jd
index be974f4..aeab997 100644
--- a/docs/html/resources/articles/live-folders.jd
+++ b/docs/html/resources/articles/live-folders.jd
@@ -1,4 +1,6 @@
page.title=Live Folders
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Live folders, introduced in Android 1.5 (API Level 3), let you display any source of data
diff --git a/docs/html/resources/articles/live-wallpapers.jd b/docs/html/resources/articles/live-wallpapers.jd
index 7510550..bfbbb34 100644
--- a/docs/html/resources/articles/live-wallpapers.jd
+++ b/docs/html/resources/articles/live-wallpapers.jd
@@ -1,4 +1,6 @@
page.title=Live Wallpapers
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/on-screen-inputs.jd b/docs/html/resources/articles/on-screen-inputs.jd
index 30b4c84..6a028c8 100644
--- a/docs/html/resources/articles/on-screen-inputs.jd
+++ b/docs/html/resources/articles/on-screen-inputs.jd
@@ -1,4 +1,6 @@
page.title=Onscreen Input Methods
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/painless-threading.jd b/docs/html/resources/articles/painless-threading.jd
index 17cec35..fea7ee2 100644
--- a/docs/html/resources/articles/painless-threading.jd
+++ b/docs/html/resources/articles/painless-threading.jd
@@ -1,4 +1,6 @@
page.title=Painless Threading
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>This article discusses the threading model used by Android applications and how applications can ensure best UI performance by spawning worker threads to handle long-running operations, rather than handling them in the main thread. The article also explains the API that your application can use to interact with Android UI toolkit components running on the main thread and spawn managed worker threads. </p>
diff --git a/docs/html/resources/articles/qsb.jd b/docs/html/resources/articles/qsb.jd
index d47ba54..01fb115 100644
--- a/docs/html/resources/articles/qsb.jd
+++ b/docs/html/resources/articles/qsb.jd
@@ -1,4 +1,6 @@
page.title=Quick Search Box
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/speech-input.jd b/docs/html/resources/articles/speech-input.jd
index 282b619..d42bd59 100644
--- a/docs/html/resources/articles/speech-input.jd
+++ b/docs/html/resources/articles/speech-input.jd
@@ -1,4 +1,6 @@
page.title=Speech Input
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p> People love their mobile phones because they can stay in touch wherever they
diff --git a/docs/html/resources/articles/timed-ui-updates.jd b/docs/html/resources/articles/timed-ui-updates.jd
index 863387c..7a0804f 100644
--- a/docs/html/resources/articles/timed-ui-updates.jd
+++ b/docs/html/resources/articles/timed-ui-updates.jd
@@ -1,4 +1,6 @@
page.title=Updating the UI from a Timer
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<img style="margin: 1.5em; float: right;" src="images/JFlubber.png" alt="" id="BLOGGER_PHOTO_ID_5135098660116808706" border="0">
diff --git a/docs/html/resources/articles/touch-mode.jd b/docs/html/resources/articles/touch-mode.jd
index e340062..5eae9b9 100644
--- a/docs/html/resources/articles/touch-mode.jd
+++ b/docs/html/resources/articles/touch-mode.jd
@@ -1,4 +1,6 @@
page.title=Touch Mode
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>This article explains the <em>touch mode</em>, one of the most
diff --git a/docs/html/resources/articles/track-mem.jd b/docs/html/resources/articles/track-mem.jd
index d580e82..c4184b5 100644
--- a/docs/html/resources/articles/track-mem.jd
+++ b/docs/html/resources/articles/track-mem.jd
@@ -1,4 +1,6 @@
page.title=Tracking Memory Allocations
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Writing efficient mobile applications is not always straightforward. In
diff --git a/docs/html/resources/articles/tts.jd b/docs/html/resources/articles/tts.jd
index e3fad91..7d07a89 100644
--- a/docs/html/resources/articles/tts.jd
+++ b/docs/html/resources/articles/tts.jd
@@ -1,4 +1,6 @@
page.title=Using Text-to-Speech
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Starting with Android 1.6 (API Level 4), the Android platform includes a new
diff --git a/docs/html/resources/articles/ui-1.5.jd b/docs/html/resources/articles/ui-1.5.jd
index c10cf52..2edaa2e 100644
--- a/docs/html/resources/articles/ui-1.5.jd
+++ b/docs/html/resources/articles/ui-1.5.jd
@@ -1,4 +1,6 @@
page.title=UI Framework Changes in Android 1.5
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/ui-1.6.jd b/docs/html/resources/articles/ui-1.6.jd
index 10cb524..09108dd 100644
--- a/docs/html/resources/articles/ui-1.6.jd
+++ b/docs/html/resources/articles/ui-1.6.jd
@@ -1,4 +1,6 @@
page.title=UI Framework Changes in Android 1.6
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Android 1.6 introduces numerous enhancements and bug fixes in the UI
diff --git a/docs/html/resources/articles/using-webviews.jd b/docs/html/resources/articles/using-webviews.jd
index 3a1f34c..3a2430b 100644
--- a/docs/html/resources/articles/using-webviews.jd
+++ b/docs/html/resources/articles/using-webviews.jd
@@ -1,4 +1,6 @@
page.title=Using WebViews
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>A small application called <a title="WebViewDemo"
diff --git a/docs/html/resources/articles/wikinotes-intents.jd b/docs/html/resources/articles/wikinotes-intents.jd
index bc64544..78fe62e 100644
--- a/docs/html/resources/articles/wikinotes-intents.jd
+++ b/docs/html/resources/articles/wikinotes-intents.jd
@@ -1,4 +1,6 @@
page.title=WikiNotes: Routing Intents
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
diff --git a/docs/html/resources/articles/wikinotes-linkify.jd b/docs/html/resources/articles/wikinotes-linkify.jd
index 21b1f13..fb49f86 100644
--- a/docs/html/resources/articles/wikinotes-linkify.jd
+++ b/docs/html/resources/articles/wikinotes-linkify.jd
@@ -1,4 +1,6 @@
page.title=WikiNotes: Linkify your Text!
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<img style="margin-left: 1.5em; margin-bottom:1.5em; float: right;"
diff --git a/docs/html/resources/articles/window-bg-speed.jd b/docs/html/resources/articles/window-bg-speed.jd
index bd7a303..c5e5e90 100644
--- a/docs/html/resources/articles/window-bg-speed.jd
+++ b/docs/html/resources/articles/window-bg-speed.jd
@@ -1,4 +1,6 @@
page.title=Window Backgrounds & UI Speed
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>Some Android applications require to squeeze every bit of performance out of
diff --git a/docs/html/resources/articles/zipalign.jd b/docs/html/resources/articles/zipalign.jd
index 013d0fe..9e767aa 100644
--- a/docs/html/resources/articles/zipalign.jd
+++ b/docs/html/resources/articles/zipalign.jd
@@ -1,4 +1,6 @@
page.title=Zipalign: an Easy Optimization
+parent.title=Articles
+parent.link=../browser.html?tag=article
@jd:body
<p>The Android SDK includes a tool called <a
diff --git a/docs/html/resources/samples/get.jd b/docs/html/resources/samples/get.jd
index 1b6d137..86ec836 100644
--- a/docs/html/resources/samples/get.jd
+++ b/docs/html/resources/samples/get.jd
@@ -1,4 +1,6 @@
page.title=Getting the Samples
+parent.title=Sample Code
+parent.link=../browser.html?tag=sample
@jd:body
diff --git a/docs/html/resources/tutorials/hello-world.jd b/docs/html/resources/tutorials/hello-world.jd
index 67c2521..020c738 100644
--- a/docs/html/resources/tutorials/hello-world.jd
+++ b/docs/html/resources/tutorials/hello-world.jd
@@ -1,4 +1,6 @@
page.title=Hello, World
+parent.title=Tutorials
+parent.link=../browser.html?tag=tutorial
@jd:body
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/resources/tutorials/localization/index.jd b/docs/html/resources/tutorials/localization/index.jd
index 8a60814..de4433b 100755
--- a/docs/html/resources/tutorials/localization/index.jd
+++ b/docs/html/resources/tutorials/localization/index.jd
@@ -1,4 +1,6 @@
page.title=Hello, L10N
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
<div id="qv-wrapper">
diff --git a/docs/html/resources/tutorials/notepad/index.jd b/docs/html/resources/tutorials/notepad/index.jd
index f569314..dd92184 100644
--- a/docs/html/resources/tutorials/notepad/index.jd
+++ b/docs/html/resources/tutorials/notepad/index.jd
@@ -1,4 +1,6 @@
page.title=Notepad Tutorial
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
diff --git a/docs/html/resources/tutorials/testing/activity_test.jd b/docs/html/resources/tutorials/testing/activity_test.jd
index c94e8ab..4b861e2 100644
--- a/docs/html/resources/tutorials/testing/activity_test.jd
+++ b/docs/html/resources/tutorials/testing/activity_test.jd
@@ -1,4 +1,6 @@
page.title=Activity Testing
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/resources/tutorials/testing/helloandroid_test.jd b/docs/html/resources/tutorials/testing/helloandroid_test.jd
index b47c334..4d949c8 100644
--- a/docs/html/resources/tutorials/testing/helloandroid_test.jd
+++ b/docs/html/resources/tutorials/testing/helloandroid_test.jd
@@ -1,4 +1,6 @@
page.title=Hello, Testing
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
<div id="qv-wrapper">
<div id="qv">
diff --git a/docs/html/resources/tutorials/views/index.jd b/docs/html/resources/tutorials/views/index.jd
index 6ea7683..bba83307 100644
--- a/docs/html/resources/tutorials/views/index.jd
+++ b/docs/html/resources/tutorials/views/index.jd
@@ -1,4 +1,6 @@
page.title=Hello, Views
+parent.title=Tutorials
+parent.link=../../browser.html?tag=tutorial
@jd:body
<style>
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index d484d60..b35a6e6 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -18,15 +18,17 @@
#define AUDIO_SOURCE_H_
+#include <media/AudioRecord.h>
#include <media/AudioSystem.h>
#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <utils/List.h>
namespace android {
class AudioRecord;
-struct MediaBufferGroup;
-struct AudioSource : public MediaSource {
+struct AudioSource : public MediaSource, public MediaBufferObserver {
// Note that the "channels" parameter is _not_ the number of channels,
// but a bitmask of AudioSystem::audio_channels constants.
AudioSource(
@@ -45,6 +47,9 @@
virtual status_t read(
MediaBuffer **buffer, const ReadOptions *options = NULL);
+ status_t dataCallbackTimestamp(const AudioRecord::Buffer& buffer, int64_t timeUs);
+ virtual void signalBufferReturned(MediaBuffer *buffer);
+
protected:
virtual ~AudioSource();
@@ -61,20 +66,24 @@
kAutoRampStartUs = 1000000,
};
+ Mutex mLock;
+ Condition mFrameAvailableCondition;
+ Condition mFrameEncodingCompletionCondition;
+
AudioRecord *mRecord;
status_t mInitCheck;
bool mStarted;
+ int32_t mSampleRate;
- bool mCollectStats;
bool mTrackMaxAmplitude;
int64_t mStartTimeUs;
int16_t mMaxAmplitude;
int64_t mPrevSampleTimeUs;
- int64_t mTotalLostFrames;
- int64_t mPrevLostBytes;
int64_t mInitialReadTimeUs;
+ int64_t mNumFramesReceived;
+ int64_t mNumClientOwnedBuffers;
- MediaBufferGroup *mGroup;
+ List<MediaBuffer * > mBuffersReceived;
void trackMaxAmplitude(int16_t *data, int nSamples);
@@ -84,6 +93,9 @@
int32_t startFrame, int32_t rampDurationFrames,
uint8_t *data, size_t bytes);
+ void releaseQueuedFrames_l();
+ void waitOutstandingEncodingFrames_l();
+
AudioSource(const AudioSource &);
AudioSource &operator=(const AudioSource &);
};
diff --git a/libs/binder/MemoryHeapBase.cpp b/libs/binder/MemoryHeapBase.cpp
index 624f7eb..9f501e2 100644
--- a/libs/binder/MemoryHeapBase.cpp
+++ b/libs/binder/MemoryHeapBase.cpp
@@ -31,7 +31,7 @@
#include <binder/MemoryHeapBase.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/android_pmem.h>
#endif
@@ -108,7 +108,7 @@
{
if (size == 0) {
// try to figure out the size automatically
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
// first try the PMEM ioctl
pmem_region reg;
int err = ioctl(fd, PMEM_GET_TOTAL_SIZE, ®);
diff --git a/libs/binder/MemoryHeapPmem.cpp b/libs/binder/MemoryHeapPmem.cpp
index 16e92f9..03322ea 100644
--- a/libs/binder/MemoryHeapPmem.cpp
+++ b/libs/binder/MemoryHeapPmem.cpp
@@ -30,7 +30,7 @@
#include <binder/MemoryHeapPmem.h>
#include <binder/MemoryHeapBase.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/android_pmem.h>
#endif
@@ -72,7 +72,7 @@
memset(start_ptr, 0xda, size);
#endif
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
if (size > 0) {
const size_t pagesize = getpagesize();
size = (size + pagesize-1) & ~(pagesize-1);
@@ -107,7 +107,7 @@
// which means MemoryHeapPmem::revoke() wouldn't have been able to
// promote() it.
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
if (mSize != 0) {
const sp<MemoryHeapPmem>& heap(getHeap());
int our_fd = heap->heapID();
@@ -130,7 +130,7 @@
: MemoryHeapBase()
{
char const * const device = pmemHeap->getDevice();
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
if (device) {
int fd = open(device, O_RDWR | (flags & NO_CACHING ? O_SYNC : 0));
LOGE_IF(fd<0, "couldn't open %s (%s)", device, strerror(errno));
@@ -187,7 +187,7 @@
status_t MemoryHeapPmem::slap()
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
size_t size = getSize();
const size_t pagesize = getpagesize();
size = (size + pagesize-1) & ~(pagesize-1);
@@ -205,7 +205,7 @@
status_t MemoryHeapPmem::unslap()
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
size_t size = getSize();
const size_t pagesize = getpagesize();
size = (size + pagesize-1) & ~(pagesize-1);
diff --git a/libs/utils/SystemClock.cpp b/libs/utils/SystemClock.cpp
index 2bdc0ce..062e6d7 100644
--- a/libs/utils/SystemClock.cpp
+++ b/libs/utils/SystemClock.cpp
@@ -19,7 +19,7 @@
* System clock functions.
*/
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/ioctl.h>
#include <linux/rtc.h>
#include <utils/Atomic.h>
@@ -50,7 +50,7 @@
return -1;
#else
struct timeval tv;
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
struct timespec ts;
int fd;
int res;
@@ -66,7 +66,7 @@
LOGD("Setting time of day to sec=%d\n", (int) tv.tv_sec);
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
fd = open("/dev/alarm", O_RDWR);
if(fd < 0) {
LOGW("Unable to open alarm driver: %s\n", strerror(errno));
@@ -106,7 +106,7 @@
*/
int64_t elapsedRealtime()
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
static int s_fd = -1;
if (s_fd == -1) {
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index b1bd828..35dcbcb 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -739,7 +739,7 @@
wp<Thread> weak(strong);
self->mHoldSelf.clear();
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
// this is very useful for debugging with gdb
self->mTid = gettid();
#endif
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 7a1d73b..cd0e021 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -18,38 +18,54 @@
#define LOG_TAG "AudioSource"
#include <utils/Log.h>
-#include <media/stagefright/AudioSource.h>
-
#include <media/AudioRecord.h>
-#include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MediaDebug.h>
+#include <media/stagefright/AudioSource.h>
+#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/foundation/ADebug.h>
#include <cutils/properties.h>
#include <stdlib.h>
namespace android {
+static void AudioRecordCallbackFunction(int event, void *user, void *info) {
+ AudioSource *source = (AudioSource *) user;
+ switch (event) {
+ case AudioRecord::EVENT_MORE_DATA: {
+ source->dataCallbackTimestamp(*((AudioRecord::Buffer *) info), systemTime() / 1000);
+ break;
+ }
+ case AudioRecord::EVENT_OVERRUN: {
+ LOGW("AudioRecord reported overrun!");
+ break;
+ }
+ default:
+ // does nothing
+ break;
+ }
+}
+
AudioSource::AudioSource(
int inputSource, uint32_t sampleRate, uint32_t channels)
: mStarted(false),
- mCollectStats(false),
+ mSampleRate(sampleRate),
mPrevSampleTimeUs(0),
- mTotalLostFrames(0),
- mPrevLostBytes(0),
- mGroup(NULL) {
+ mNumFramesReceived(0),
+ mNumClientOwnedBuffers(0) {
LOGV("sampleRate: %d, channels: %d", sampleRate, channels);
CHECK(channels == 1 || channels == 2);
uint32_t flags = AudioRecord::RECORD_AGC_ENABLE |
AudioRecord::RECORD_NS_ENABLE |
AudioRecord::RECORD_IIR_ENABLE;
-
mRecord = new AudioRecord(
inputSource, sampleRate, AudioSystem::PCM_16_BIT,
channels > 1? AudioSystem::CHANNEL_IN_STEREO: AudioSystem::CHANNEL_IN_MONO,
4 * kMaxBufferSize / sizeof(int16_t), /* Enable ping-pong buffers */
- flags);
+ flags,
+ AudioRecordCallbackFunction,
+ this);
mInitCheck = mRecord->initCheck();
}
@@ -68,6 +84,7 @@
}
status_t AudioSource::start(MetaData *params) {
+ Mutex::Autolock autoLock(mLock);
if (mStarted) {
return UNKNOWN_ERROR;
}
@@ -76,12 +93,6 @@
return NO_INIT;
}
- char value[PROPERTY_VALUE_MAX];
- if (property_get("media.stagefright.record-stats", value, NULL)
- && (!strcmp(value, "1") || !strcasecmp(value, "true"))) {
- mCollectStats = true;
- }
-
mTrackMaxAmplitude = false;
mMaxAmplitude = 0;
mInitialReadTimeUs = 0;
@@ -92,9 +103,6 @@
}
status_t err = mRecord->start();
if (err == OK) {
- mGroup = new MediaBufferGroup;
- mGroup->add_buffer(new MediaBuffer(kMaxBufferSize));
-
mStarted = true;
} else {
delete mRecord;
@@ -105,7 +113,25 @@
return err;
}
+void AudioSource::releaseQueuedFrames_l() {
+ LOGV("releaseQueuedFrames_l");
+ List<MediaBuffer *>::iterator it;
+ while (!mBuffersReceived.empty()) {
+ it = mBuffersReceived.begin();
+ (*it)->release();
+ mBuffersReceived.erase(it);
+ }
+}
+
+void AudioSource::waitOutstandingEncodingFrames_l() {
+ LOGV("waitOutstandingEncodingFrames_l: %lld", mNumClientOwnedBuffers);
+ while (mNumClientOwnedBuffers > 0) {
+ mFrameEncodingCompletionCondition.wait(mLock);
+ }
+}
+
status_t AudioSource::stop() {
+ Mutex::Autolock autoLock(mLock);
if (!mStarted) {
return UNKNOWN_ERROR;
}
@@ -114,29 +140,23 @@
return NO_INIT;
}
- mRecord->stop();
-
- delete mGroup;
- mGroup = NULL;
-
mStarted = false;
-
- if (mCollectStats) {
- LOGI("Total lost audio frames: %lld",
- mTotalLostFrames + (mPrevLostBytes >> 1));
- }
+ mRecord->stop();
+ waitOutstandingEncodingFrames_l();
+ releaseQueuedFrames_l();
return OK;
}
sp<MetaData> AudioSource::getFormat() {
+ Mutex::Autolock autoLock(mLock);
if (mInitCheck != OK) {
return 0;
}
sp<MetaData> meta = new MetaData;
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
- meta->setInt32(kKeySampleRate, mRecord->getSampleRate());
+ meta->setInt32(kKeySampleRate, mSampleRate);
meta->setInt32(kKeyChannelCount, mRecord->channelCount());
meta->setInt32(kKeyMaxInputSize, kMaxBufferSize);
@@ -177,121 +197,118 @@
status_t AudioSource::read(
MediaBuffer **out, const ReadOptions *options) {
+ Mutex::Autolock autoLock(mLock);
+ *out = NULL;
if (mInitCheck != OK) {
return NO_INIT;
}
- int64_t readTimeUs = systemTime() / 1000;
- *out = NULL;
-
- MediaBuffer *buffer;
- CHECK_EQ(mGroup->acquire_buffer(&buffer), OK);
-
- int err = 0;
- if (mStarted) {
-
- uint32_t numFramesRecorded;
- mRecord->getPosition(&numFramesRecorded);
-
-
- if (numFramesRecorded == 0 && mPrevSampleTimeUs == 0) {
- mInitialReadTimeUs = readTimeUs;
- // Initial delay
- if (mStartTimeUs > 0) {
- mStartTimeUs = readTimeUs - mStartTimeUs;
- } else {
- // Assume latency is constant.
- mStartTimeUs += mRecord->latency() * 1000;
- }
- mPrevSampleTimeUs = mStartTimeUs;
- }
-
- uint32_t sampleRate = mRecord->getSampleRate();
-
- // Insert null frames when lost frames are detected.
- int64_t timestampUs = mPrevSampleTimeUs;
- uint32_t numLostBytes = mRecord->getInputFramesLost() << 1;
- numLostBytes += mPrevLostBytes;
-#if 0
- // Simulate lost frames
- numLostBytes = ((rand() * 1.0 / RAND_MAX)) * 2 * kMaxBufferSize;
- numLostBytes &= 0xFFFFFFFE; // Alignment requirement
-
- // Reduce the chance to lose
- if (rand() * 1.0 / RAND_MAX >= 0.05) {
- numLostBytes = 0;
- }
-#endif
- if (numLostBytes > 0) {
- if (numLostBytes > kMaxBufferSize) {
- mPrevLostBytes = numLostBytes - kMaxBufferSize;
- numLostBytes = kMaxBufferSize;
- } else {
- mPrevLostBytes = 0;
- }
-
- CHECK_EQ(numLostBytes & 1, 0);
- timestampUs += ((1000000LL * (numLostBytes >> 1)) +
- (sampleRate >> 1)) / sampleRate;
-
- if (mCollectStats) {
- mTotalLostFrames += (numLostBytes >> 1);
- }
- memset(buffer->data(), 0, numLostBytes);
- buffer->set_range(0, numLostBytes);
- if (numFramesRecorded == 0) {
- buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
- }
- buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs + mPrevSampleTimeUs);
- buffer->meta_data()->setInt64(kKeyDriftTime, readTimeUs - mInitialReadTimeUs);
- mPrevSampleTimeUs = timestampUs;
- *out = buffer;
- return OK;
- }
-
- ssize_t n = mRecord->read(buffer->data(), buffer->size());
- if (n <= 0) {
- buffer->release();
- LOGE("Read from AudioRecord returns %d", n);
- return UNKNOWN_ERROR;
- }
-
- int64_t recordDurationUs = (1000000LL * n >> 1) / sampleRate;
- timestampUs += recordDurationUs;
-
- if (mPrevSampleTimeUs - mStartTimeUs < kAutoRampStartUs) {
- // Mute the initial video recording signal
- memset((uint8_t *) buffer->data(), 0, n);
- } else if (mPrevSampleTimeUs - mStartTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
- int32_t autoRampDurationFrames =
- (kAutoRampDurationUs * sampleRate + 500000LL) / 1000000LL;
-
- int32_t autoRampStartFrames =
- (kAutoRampStartUs * sampleRate + 500000LL) / 1000000LL;
-
- int32_t nFrames = numFramesRecorded - autoRampStartFrames;
- rampVolume(nFrames, autoRampDurationFrames, (uint8_t *) buffer->data(), n);
- }
- if (mTrackMaxAmplitude) {
- trackMaxAmplitude((int16_t *) buffer->data(), n >> 1);
- }
-
- if (numFramesRecorded == 0) {
- buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
- }
-
- buffer->meta_data()->setInt64(kKeyTime, mStartTimeUs + mPrevSampleTimeUs);
- buffer->meta_data()->setInt64(kKeyDriftTime, readTimeUs - mInitialReadTimeUs);
- mPrevSampleTimeUs = timestampUs;
- LOGV("initial delay: %lld, sample rate: %d, timestamp: %lld",
- mStartTimeUs, sampleRate, timestampUs);
-
- buffer->set_range(0, n);
-
- *out = buffer;
+ while (mStarted && mBuffersReceived.empty()) {
+ mFrameAvailableCondition.wait(mLock);
+ }
+ if (!mStarted) {
return OK;
}
+ MediaBuffer *buffer = *mBuffersReceived.begin();
+ mBuffersReceived.erase(mBuffersReceived.begin());
+ ++mNumClientOwnedBuffers;
+ buffer->setObserver(this);
+ buffer->add_ref();
+
+ // Mute/suppress the recording sound
+ int64_t timeUs;
+ CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
+ int64_t elapsedTimeUs = timeUs - mStartTimeUs;
+ if (elapsedTimeUs < kAutoRampStartUs) {
+ memset((uint8_t *) buffer->data(), 0, buffer->range_length());
+ } else if (elapsedTimeUs < kAutoRampStartUs + kAutoRampDurationUs) {
+ int32_t autoRampDurationFrames =
+ (kAutoRampDurationUs * mSampleRate + 500000LL) / 1000000LL;
+
+ int32_t autoRampStartFrames =
+ (kAutoRampStartUs * mSampleRate + 500000LL) / 1000000LL;
+
+ int32_t nFrames = mNumFramesReceived - autoRampStartFrames;
+ rampVolume(nFrames, autoRampDurationFrames,
+ (uint8_t *) buffer->data(), buffer->range_length());
+ }
+
+ // Track the max recording signal amplitude.
+ if (mTrackMaxAmplitude) {
+ trackMaxAmplitude(
+ (int16_t *) buffer->data(), buffer->range_length() >> 1);
+ }
+
+ *out = buffer;
+ return OK;
+}
+
+void AudioSource::signalBufferReturned(MediaBuffer *buffer) {
+ LOGV("signalBufferReturned: %p", buffer->data());
+ Mutex::Autolock autoLock(mLock);
+ --mNumClientOwnedBuffers;
+ buffer->setObserver(0);
+ buffer->release();
+ mFrameEncodingCompletionCondition.signal();
+ return;
+}
+
+status_t AudioSource::dataCallbackTimestamp(
+ const AudioRecord::Buffer& audioBuffer, int64_t timeUs) {
+ LOGV("dataCallbackTimestamp: %lld us", timeUs);
+ Mutex::Autolock autoLock(mLock);
+ if (!mStarted) {
+ LOGW("Spurious callback from AudioRecord. Drop the audio data.");
+ return OK;
+ }
+
+ if (mNumFramesReceived == 0 && mPrevSampleTimeUs == 0) {
+ mInitialReadTimeUs = timeUs;
+ // Initial delay
+ if (mStartTimeUs > 0) {
+ mStartTimeUs = timeUs - mStartTimeUs;
+ } else {
+ // Assume latency is constant.
+ mStartTimeUs += mRecord->latency() * 1000;
+ }
+ mPrevSampleTimeUs = mStartTimeUs;
+ }
+
+ int64_t timestampUs = mPrevSampleTimeUs;
+
+ size_t numLostBytes = mRecord->getInputFramesLost();
+ CHECK_EQ(numLostBytes & 1, 0u);
+ CHECK_EQ(audioBuffer.size & 1, 0u);
+ size_t bufferSize = numLostBytes + audioBuffer.size;
+ MediaBuffer *buffer = new MediaBuffer(bufferSize);
+ if (numLostBytes > 0) {
+ memset(buffer->data(), 0, numLostBytes);
+ memcpy((uint8_t *) buffer->data() + numLostBytes,
+ audioBuffer.i16, audioBuffer.size);
+ } else {
+ if (audioBuffer.size == 0) {
+ LOGW("Nothing is available from AudioRecord callback buffer");
+ buffer->release();
+ return OK;
+ }
+ memcpy((uint8_t *) buffer->data(),
+ audioBuffer.i16, audioBuffer.size);
+ }
+
+ buffer->set_range(0, bufferSize);
+ timestampUs += ((1000000LL * (bufferSize >> 1)) +
+ (mSampleRate >> 1)) / mSampleRate;
+
+ if (mNumFramesReceived == 0) {
+ buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
+ }
+ buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
+ buffer->meta_data()->setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
+ mPrevSampleTimeUs = timestampUs;
+ mNumFramesReceived += buffer->range_length() / sizeof(int16_t);
+ mBuffersReceived.push_back(buffer);
+ mFrameAvailableCondition.signal();
return OK;
}
diff --git a/media/tests/MediaFrameworkTest/AndroidManifest.xml b/media/tests/MediaFrameworkTest/AndroidManifest.xml
index c9d2628b..dd5e026 100644
--- a/media/tests/MediaFrameworkTest/AndroidManifest.xml
+++ b/media/tests/MediaFrameworkTest/AndroidManifest.xml
@@ -22,6 +22,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.permission.WAKE_LOCK" />
+
<application>
<uses-library android:name="android.test.runner" />
<activity android:label="@string/app_name"
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java
index 41f0e22..79fd2cb 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkTest.java
@@ -24,6 +24,7 @@
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
+import android.os.PowerManager;
import android.provider.Downloads;
import android.util.Log;
import android.util.Log;
@@ -48,7 +49,7 @@
import java.net.InetAddress;
-public class MediaFrameworkTest extends Activity {
+public class MediaFrameworkTest extends Activity implements SurfaceHolder.Callback {
//public static Surface video_sf;
public static SurfaceView mSurfaceView;
@@ -63,11 +64,13 @@
public static Bitmap mDestBitmap;
public static ImageView mOverlayView;
-
+ private SurfaceHolder mSurfaceHolder = null;
+ private String TAG = "MediaFrameworkTest";
+ private PowerManager.WakeLock mWakeLock = null;
+
public MediaFrameworkTest() {
}
-
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
@@ -76,7 +79,9 @@
mSurfaceView = (SurfaceView)findViewById(R.id.surface_view);
mOverlayView = (ImageView)findViewById(R.id.overlay_layer);
ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
- mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ mSurfaceHolder = mSurfaceView.getHolder();
+ mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ mSurfaceHolder.addCallback(this);
//Get the midi fd
midiafd = this.getResources().openRawResourceFd(R.raw.testmidi);
@@ -86,8 +91,31 @@
mOverlayView.setLayoutParams(lp);
mDestBitmap = Bitmap.createBitmap((int)640, (int)480, Bitmap.Config.ARGB_8888);
mOverlayView.setImageBitmap(mDestBitmap);
+
+ //Acquire the full wake lock to keep the device up
+ PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "MediaFrameworkTest");
+ mWakeLock.acquire();
}
-
+
+ public void onStop(Bundle icicle) {
+ mWakeLock.release();
+ }
+
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ //Can do nothing in here. The test case will fail if the surface destroyed.
+ Log.v(TAG, "Test application surface destroyed");
+ mSurfaceHolder = null;
+ }
+
+ public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+ //Do nothing in here. Just print out the log
+ Log.v(TAG, "Test application surface changed");
+ }
+
+ public void surfaceCreated(SurfaceHolder holder) {
+ }
+
public void startPlayback(String filename){
String mimetype = "audio/mpeg";
Uri path = Uri.parse(filename);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
index cad7e53..44707401 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/CodecTest.java
@@ -60,11 +60,11 @@
private static boolean onPrepareSuccess = false;
public static boolean onCompleteSuccess = false;
public static boolean mPlaybackError = false;
- public static boolean mIsMediaInfoUnknown = false;
- public static boolean mIsMediaInfoVideoTrackLagging = false;
- public static boolean mIsMediaInfoBadInterleaving = false;
- public static boolean mIsMediaInfoNotSeekable = false;
- public static boolean mIsMediaInfoMetdataUpdate = false;
+ public static int mMediaInfoUnknownCount = 0;
+ public static int mMediaInfoVideoTrackLaggingCount = 0;
+ public static int mMediaInfoBadInterleavingCount = 0;
+ public static int mMediaInfoNotSeekableCount = 0;
+ public static int mMediaInfoMetdataUpdateCount = 0;
public static String printCpuInfo(){
String cm = "dumpsys cpuinfo";
@@ -765,19 +765,19 @@
public boolean onInfo(MediaPlayer mp, int what, int extra) {
switch (what){
case MediaPlayer.MEDIA_INFO_UNKNOWN:
- mIsMediaInfoUnknown = true;
+ mMediaInfoUnknownCount++;
break;
case MediaPlayer.MEDIA_INFO_VIDEO_TRACK_LAGGING:
- mIsMediaInfoVideoTrackLagging = true;
+ mMediaInfoVideoTrackLaggingCount++;
break;
case MediaPlayer.MEDIA_INFO_BAD_INTERLEAVING:
- mIsMediaInfoBadInterleaving = true;
+ mMediaInfoBadInterleavingCount++;
break;
case MediaPlayer.MEDIA_INFO_NOT_SEEKABLE:
- mIsMediaInfoNotSeekable = true;
+ mMediaInfoNotSeekableCount++;
break;
case MediaPlayer.MEDIA_INFO_METADATA_UPDATE:
- mIsMediaInfoMetdataUpdate = true;
+ mMediaInfoMetdataUpdateCount++;
break;
}
return true;
@@ -791,11 +791,11 @@
int nextPosition = 0;
int waittime = 0;
onCompleteSuccess = false;
- mIsMediaInfoUnknown = false;
- mIsMediaInfoVideoTrackLagging = false;
- mIsMediaInfoBadInterleaving = false;
- mIsMediaInfoNotSeekable = false;
- mIsMediaInfoMetdataUpdate = false;
+ mMediaInfoUnknownCount = 0;
+ mMediaInfoVideoTrackLaggingCount = 0;
+ mMediaInfoBadInterleavingCount = 0;
+ mMediaInfoNotSeekableCount = 0;
+ mMediaInfoMetdataUpdateCount = 0;
mPlaybackError = false;
String testResult;
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
index b694d16..20e2936 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/MediaPlayerStressTest.java
@@ -65,11 +65,11 @@
output.write("File Name: " + filename);
output.write(" Complete: " + CodecTest.onCompleteSuccess);
output.write(" Error: " + CodecTest.mPlaybackError);
- output.write(" Unknown Info: " + CodecTest.mIsMediaInfoUnknown);
- output.write(" Track Lagging: " + CodecTest.mIsMediaInfoVideoTrackLagging);
- output.write(" BadInterleaving: " + CodecTest.mIsMediaInfoBadInterleaving);
- output.write(" Not Seekable: " + CodecTest.mIsMediaInfoNotSeekable);
- output.write(" Info Meta data update: " + CodecTest.mIsMediaInfoMetdataUpdate);
+ output.write(" Unknown Info: " + CodecTest.mMediaInfoUnknownCount);
+ output.write(" Track Lagging: " + CodecTest.mMediaInfoVideoTrackLaggingCount);
+ output.write(" BadInterleaving: " + CodecTest.mMediaInfoBadInterleavingCount);
+ output.write(" Not Seekable: " + CodecTest.mMediaInfoNotSeekableCount);
+ output.write(" Info Meta data update: " + CodecTest.mMediaInfoMetdataUpdateCount);
output.write("\n");
}
@@ -92,21 +92,11 @@
else if (CodecTest.mPlaybackError){
mTotalPlaybackError++;
}
- else if (CodecTest.mIsMediaInfoUnknown){
- mTotalInfoUnknown++;
- }
- else if (CodecTest.mIsMediaInfoVideoTrackLagging){
- mTotalVideoTrackLagging++;
- }
- else if (CodecTest.mIsMediaInfoBadInterleaving){
- mTotalBadInterleaving++;
- }
- else if (CodecTest.mIsMediaInfoNotSeekable){
- mTotalNotSeekable++;
- }
- else if (CodecTest.mIsMediaInfoMetdataUpdate){
- mTotalMetaDataUpdate++;
- }
+ mTotalInfoUnknown += CodecTest.mMediaInfoUnknownCount;
+ mTotalVideoTrackLagging += CodecTest.mMediaInfoVideoTrackLaggingCount;
+ mTotalBadInterleaving += CodecTest.mMediaInfoBadInterleavingCount;
+ mTotalNotSeekable += CodecTest.mMediaInfoNotSeekableCount;
+ mTotalMetaDataUpdate += CodecTest.mMediaInfoMetdataUpdateCount;
}
//Test that will start the playback for all the videos
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 3dc8c03f..3d5a4d1 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -22,7 +22,7 @@
#include <sys/ioctl.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/android_pmem.h>
#endif
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index a072aed..a8f4262 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -158,7 +158,9 @@
private void advance() {
// Out with the old...
if (mCurrentView != null) {
- mWindow.removeView(mCurrentView);
+ if (mWindow != null) {
+ mWindow.removeView(mCurrentView);
+ }
mCurrentView = null;
mCurrentKey = null;
mCurrentNotification = null;
diff --git a/services/java/com/android/server/UsbService.java b/services/java/com/android/server/UsbService.java
index 460fd4d..af4c425 100644
--- a/services/java/com/android/server/UsbService.java
+++ b/services/java/com/android/server/UsbService.java
@@ -20,6 +20,7 @@
import android.content.Context;
import android.content.Intent;
import android.hardware.IUsbManager;
+import android.hardware.UsbAccessory;
import android.hardware.UsbConstants;
import android.hardware.UsbDevice;
import android.hardware.UsbEndpoint;
@@ -78,18 +79,63 @@
private int mLastConfiguration = -1;
// lists of enabled and disabled USB functions (for USB device mode)
+ // synchronize on mEnabledFunctions when using either of these lists
private final ArrayList<String> mEnabledFunctions = new ArrayList<String>();
private final ArrayList<String> mDisabledFunctions = new ArrayList<String>();
+ // contains all connected USB devices (for USB host mode)
private final HashMap<String,UsbDevice> mDevices = new HashMap<String,UsbDevice>();
// USB busses to exclude from USB host support
private final String[] mHostBlacklist;
private boolean mSystemReady;
+ private UsbAccessory mCurrentAccessory;
private final Context mContext;
+ private final void functionEnabled(String function, boolean enabled) {
+ synchronized (mEnabledFunctions) {
+ if (enabled) {
+ if (!mEnabledFunctions.contains(function)) {
+ mEnabledFunctions.add(function);
+ }
+ mDisabledFunctions.remove(function);
+ } else {
+ if (!mDisabledFunctions.contains(function)) {
+ mDisabledFunctions.add(function);
+ }
+ mEnabledFunctions.remove(function);
+ }
+ }
+
+ if (enabled && UsbManager.USB_FUNCTION_ACCESSORY.equals(function)) {
+ String[] strings = nativeGetAccessoryStrings();
+ if (strings != null) {
+ Log.d(TAG, "entering USB accessory mode");
+ mCurrentAccessory = new UsbAccessory(strings);
+ Intent intent = new Intent(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, mCurrentAccessory);
+ // add strings as separate extras to allow filtering
+ if (strings[0] != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY_MANUFACTURER, strings[0]);
+ }
+ if (strings[1] != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY_PRODUCT, strings[1]);
+ }
+ if (strings[2] != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY_TYPE, strings[2]);
+ }
+ if (strings[3] != null) {
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY_VERSION, strings[3]);
+ }
+ mContext.sendBroadcast(intent);
+ } else {
+ Log.e(TAG, "nativeGetAccessoryStrings failed");
+ }
+ }
+ }
+
private final UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
@@ -127,17 +173,7 @@
// Note: we do not broadcast a change when a function is enabled or disabled.
// We just record the state change for the next broadcast.
boolean enabled = "1".equals(enabledStr);
- if (enabled) {
- if (!mEnabledFunctions.contains(function)) {
- mEnabledFunctions.add(function);
- }
- mDisabledFunctions.remove(function);
- } else {
- if (!mDisabledFunctions.contains(function)) {
- mDisabledFunctions.add(function);
- }
- mEnabledFunctions.remove(function);
- }
+ functionEnabled(function, enabled);
}
}
}
@@ -182,18 +218,20 @@
return;
try {
- File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles();
- for (int i = 0; i < files.length; i++) {
- File file = new File(files[i], "enable");
- FileReader reader = new FileReader(file);
- int len = reader.read(buffer, 0, 1024);
- reader.close();
- int value = Integer.valueOf((new String(buffer, 0, len)).trim());
- String functionName = files[i].getName();
- if (value == 1) {
- mEnabledFunctions.add(functionName);
- } else {
- mDisabledFunctions.add(functionName);
+ synchronized (mEnabledFunctions) {
+ File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles();
+ for (int i = 0; i < files.length; i++) {
+ File file = new File(files[i], "enable");
+ FileReader reader = new FileReader(file);
+ int len = reader.read(buffer, 0, 1024);
+ reader.close();
+ int value = Integer.valueOf((new String(buffer, 0, len)).trim());
+ String functionName = files[i].getName();
+ if (value == 1) {
+ mEnabledFunctions.add(functionName);
+ } else {
+ mDisabledFunctions.add(functionName);
+ }
}
}
} catch (FileNotFoundException e) {
@@ -359,19 +397,32 @@
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
if (mDevices.get(deviceName) == null) {
// if it is not in mDevices, it either does not exist or is blacklisted
- throw new IllegalArgumentException("device " + deviceName + " does not exist or is restricted");
+ throw new IllegalArgumentException(
+ "device " + deviceName + " does not exist or is restricted");
}
return nativeOpenDevice(deviceName);
}
+ public UsbAccessory getCurrentAccessory() {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
+ return mCurrentAccessory;
+ }
+
+ public ParcelFileDescriptor openAccessory() {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
+ return nativeOpenAccessory();
+ }
+
private final Handler mHandler = new Handler() {
private void addEnabledFunctions(Intent intent) {
+ synchronized (mEnabledFunctions) {
// include state of all USB functions in our extras
- for (int i = 0; i < mEnabledFunctions.size(); i++) {
- intent.putExtra(mEnabledFunctions.get(i), UsbManager.USB_FUNCTION_ENABLED);
- }
- for (int i = 0; i < mDisabledFunctions.size(); i++) {
- intent.putExtra(mDisabledFunctions.get(i), UsbManager.USB_FUNCTION_DISABLED);
+ for (int i = 0; i < mEnabledFunctions.size(); i++) {
+ intent.putExtra(mEnabledFunctions.get(i), UsbManager.USB_FUNCTION_ENABLED);
+ }
+ for (int i = 0; i < mDisabledFunctions.size(); i++) {
+ intent.putExtra(mDisabledFunctions.get(i), UsbManager.USB_FUNCTION_DISABLED);
+ }
}
}
@@ -381,6 +432,26 @@
case MSG_UPDATE:
synchronized (this) {
if (mConnected != mLastConnected || mConfiguration != mLastConfiguration) {
+ if (mConnected == 0 && mCurrentAccessory != null) {
+ // turn off accessory mode when we are disconnected
+ if (UsbManager.setFunctionEnabled(
+ UsbManager.USB_FUNCTION_ACCESSORY, false)) {
+ Log.d(TAG, "exited USB accessory mode");
+
+ Intent intent = new Intent(
+ UsbManager.ACTION_USB_ACCESSORY_DETACHED);
+ intent.putExtra(UsbManager.EXTRA_ACCESSORY, mCurrentAccessory);
+ mContext.sendBroadcast(intent);
+ mCurrentAccessory = null;
+
+ // this will cause an immediate reset of the USB bus,
+ // so there is no point in sending the
+ // function disabled broadcast.
+ return;
+ } else {
+ Log.e(TAG, "could not disable USB_FUNCTION_ACCESSORY");
+ }
+ }
final ContentResolver cr = mContext.getContentResolver();
if (Settings.Secure.getInt(cr,
@@ -408,4 +479,6 @@
private native void monitorUsbHostBus();
private native ParcelFileDescriptor nativeOpenDevice(String deviceName);
+ private native String[] nativeGetAccessoryStrings();
+ private native ParcelFileDescriptor nativeOpenAccessory();
}
diff --git a/services/java/com/android/server/WifiWatchdogService.java b/services/java/com/android/server/WifiWatchdogService.java
index 46d6bef..94531bb 100644
--- a/services/java/com/android/server/WifiWatchdogService.java
+++ b/services/java/com/android/server/WifiWatchdogService.java
@@ -22,8 +22,9 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
+import android.net.ConnectivityManager;
+import android.net.LinkProperties;
import android.net.NetworkInfo;
-import android.net.DhcpInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
@@ -42,6 +43,7 @@
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
+import java.util.Collection;
import java.util.List;
import java.util.Random;
@@ -77,7 +79,8 @@
private Context mContext;
private ContentResolver mContentResolver;
private WifiManager mWifiManager;
-
+ private ConnectivityManager mConnectivityManager;
+
/**
* The main watchdog thread.
*/
@@ -310,19 +313,26 @@
}
/**
- * Gets the DNS of the current AP.
+ * Gets the first DNS of the current AP.
*
- * @return The DNS of the current AP.
+ * @return The first DNS of the current AP.
*/
- private int getDns() {
- DhcpInfo addressInfo = mWifiManager.getDhcpInfo();
- if (addressInfo != null) {
- return addressInfo.dns1;
- } else {
- return -1;
+ private InetAddress getDns() {
+ if (mConnectivityManager == null) {
+ mConnectivityManager = (ConnectivityManager)mContext.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
}
+
+ LinkProperties linkProperties = mConnectivityManager.getLinkProperties(
+ ConnectivityManager.TYPE_WIFI);
+ if (linkProperties == null) return null;
+
+ Collection<InetAddress> dnses = linkProperties.getDnses();
+ if (dnses == null || dnses.size() == 0) return null;
+
+ return dnses.iterator().next();
}
-
+
/**
* Checks whether the DNS can be reached using multiple attempts according
* to the current setting values.
@@ -330,29 +340,28 @@
* @return Whether the DNS is reachable
*/
private boolean checkDnsConnectivity() {
- int dns = getDns();
- if (dns == -1) {
+ InetAddress dns = getDns();
+ if (dns == null) {
if (V) {
myLogV("checkDnsConnectivity: Invalid DNS, returning false");
}
return false;
}
-
+
if (V) {
- myLogV("checkDnsConnectivity: Checking 0x" +
- Integer.toHexString(Integer.reverseBytes(dns)) + " for connectivity");
+ myLogV("checkDnsConnectivity: Checking " + dns.getHostAddress() + " for connectivity");
}
int numInitialIgnoredPings = getInitialIgnoredPingCount();
int numPings = getPingCount();
int pingDelay = getPingDelayMs();
int acceptableLoss = getAcceptablePacketLossPercentage();
-
+
/** See {@link Secure#WIFI_WATCHDOG_INITIAL_IGNORED_PING_COUNT} */
int ignoredPingCounter = 0;
int pingCounter = 0;
int successCounter = 0;
-
+
// No connectivity check needed
if (numPings == 0) {
return true;
@@ -371,20 +380,20 @@
pingCounter++;
successCounter++;
}
-
+
if (V) {
Slog.v(TAG, (dnsAlive ? " +" : " Ignored: -"));
}
if (shouldCancel()) return false;
-
+
try {
Thread.sleep(pingDelay);
} catch (InterruptedException e) {
Slog.w(TAG, "Interrupted while pausing between pings", e);
}
}
-
+
// Do the pings that we use to measure packet loss
for (; pingCounter < numPings; pingCounter++) {
if (shouldCancel()) return false;
@@ -401,40 +410,41 @@
}
if (shouldCancel()) return false;
-
+
try {
Thread.sleep(pingDelay);
} catch (InterruptedException e) {
Slog.w(TAG, "Interrupted while pausing between pings", e);
}
}
-
+
int packetLossPercentage = 100 * (numPings - successCounter) / numPings;
if (D) {
Slog.d(TAG, packetLossPercentage
+ "% packet loss (acceptable is " + acceptableLoss + "%)");
}
-
+
return !shouldCancel() && (packetLossPercentage <= acceptableLoss);
}
private boolean backgroundCheckDnsConnectivity() {
- int dns = getDns();
- if (false && V) {
- myLogV("backgroundCheckDnsConnectivity: Background checking " + dns +
- " for connectivity");
- }
-
- if (dns == -1) {
+ InetAddress dns = getDns();
+
+ if (dns == null) {
if (V) {
myLogV("backgroundCheckDnsConnectivity: DNS is empty, returning false");
}
return false;
}
-
+
+ if (false && V) {
+ myLogV("backgroundCheckDnsConnectivity: Background checking " +
+ dns.getHostAddress() + " for connectivity");
+ }
+
return DnsPinger.isDnsReachable(dns, getBackgroundCheckTimeoutMs());
}
-
+
/**
* Signals the current action to cancel.
*/
@@ -1207,43 +1217,37 @@
/** Used to generate IDs */
private static Random sRandom = new Random();
-
- static boolean isDnsReachable(int dns, int timeout) {
+
+ static boolean isDnsReachable(InetAddress dnsAddress, int timeout) {
DatagramSocket socket = null;
try {
socket = new DatagramSocket();
-
+
// Set some socket properties
socket.setSoTimeout(timeout);
-
+
byte[] buf = new byte[DNS_QUERY_BASE_SIZE];
fillQuery(buf);
-
- // Send the DNS query
- byte parts[] = new byte[4];
- parts[0] = (byte)(dns & 0xff);
- parts[1] = (byte)((dns >> 8) & 0xff);
- parts[2] = (byte)((dns >> 16) & 0xff);
- parts[3] = (byte)((dns >> 24) & 0xff);
- InetAddress dnsAddress = InetAddress.getByAddress(parts);
+ // Send the DNS query
+
DatagramPacket packet = new DatagramPacket(buf,
buf.length, dnsAddress, DNS_PORT);
socket.send(packet);
-
+
// Wait for reply (blocks for the above timeout)
DatagramPacket replyPacket = new DatagramPacket(buf, buf.length);
socket.receive(replyPacket);
// If a timeout occurred, an exception would have been thrown. We got a reply!
return true;
-
+
} catch (SocketException e) {
if (V) {
Slog.v(TAG, "DnsPinger.isReachable received SocketException", e);
}
return false;
-
+
} catch (UnknownHostException e) {
if (V) {
Slog.v(TAG, "DnsPinger.isReachable is unable to resolve the DNS host", e);
diff --git a/services/jni/com_android_server_AlarmManagerService.cpp b/services/jni/com_android_server_AlarmManagerService.cpp
index 0e162bd..aa8c9b3 100644
--- a/services/jni/com_android_server_AlarmManagerService.cpp
+++ b/services/jni/com_android_server_AlarmManagerService.cpp
@@ -33,7 +33,7 @@
#include <errno.h>
#include <unistd.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/ioctl.h>
#include <linux/android_alarm.h>
#endif
@@ -42,7 +42,7 @@
static jint android_server_AlarmManagerService_setKernelTimezone(JNIEnv* env, jobject obj, jint fd, jint minswest)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
struct timezone tz;
tz.tz_minuteswest = minswest;
@@ -64,7 +64,7 @@
static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
return open("/dev/alarm", O_RDWR);
#else
return -1;
@@ -73,14 +73,14 @@
static void android_server_AlarmManagerService_close(JNIEnv* env, jobject obj, jint fd)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
close(fd);
#endif
}
static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong seconds, jlong nanoseconds)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
struct timespec ts;
ts.tv_sec = seconds;
ts.tv_nsec = nanoseconds;
@@ -95,7 +95,7 @@
static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd)
{
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
int result = 0;
do
diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp
index d4513e9..98d0d92 100644
--- a/services/jni/com_android_server_BatteryService.cpp
+++ b/services/jni/com_android_server_BatteryService.cpp
@@ -33,7 +33,7 @@
#include <unistd.h>
#include <dirent.h>
-#if HAVE_ANDROID_OS
+#ifdef HAVE_ANDROID_OS
#include <linux/ioctl.h>
#endif
diff --git a/services/jni/com_android_server_UsbService.cpp b/services/jni/com_android_server_UsbService.cpp
index ef22111..192daaf 100644
--- a/services/jni/com_android_server_UsbService.cpp
+++ b/services/jni/com_android_server_UsbService.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,13 @@
#include <stdio.h>
#include <asm/byteorder.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <linux/usb/f_accessory.h>
+
+#define DRIVER_NAME "/dev/usb_accessory"
namespace android
{
@@ -164,10 +171,67 @@
gParcelFileDescriptorOffsets.mConstructor, fileDescriptor);
}
+static void set_accessory_string(JNIEnv *env, int fd, int cmd, jobjectArray strArray, int index)
+{
+ char buffer[256];
+
+ buffer[0] = 0;
+ int length = ioctl(fd, cmd, buffer);
+ LOGD("ioctl returned %d", length);
+ if (buffer[0]) {
+ jstring obj = env->NewStringUTF(buffer);
+ env->SetObjectArrayElement(strArray, index, obj);
+ env->DeleteLocalRef(obj);
+ }
+}
+
+
+static jobjectArray android_server_UsbService_getAccessoryStrings(JNIEnv *env, jobject thiz)
+{
+ int fd = open(DRIVER_NAME, O_RDWR);
+ if (fd < 0) {
+ LOGE("could not open %s", DRIVER_NAME);
+ return NULL;
+ }
+ jclass stringClass = env->FindClass("java/lang/String");
+ jobjectArray strArray = env->NewObjectArray(4, stringClass, NULL);
+ if (!strArray) goto out;
+ set_accessory_string(env, fd, ACCESSORY_GET_STRING_MANUFACTURER, strArray, 0);
+ set_accessory_string(env, fd, ACCESSORY_GET_STRING_MODEL, strArray, 1);
+ set_accessory_string(env, fd, ACCESSORY_GET_STRING_TYPE, strArray, 2);
+ set_accessory_string(env, fd, ACCESSORY_GET_STRING_VERSION, strArray, 3);
+
+out:
+ close(fd);
+ return strArray;
+}
+
+static jobject android_server_UsbService_openAccessory(JNIEnv *env, jobject thiz)
+{
+ int fd = open(DRIVER_NAME, O_RDWR);
+ if (fd < 0) {
+ LOGE("could not open %s", DRIVER_NAME);
+ return NULL;
+ }
+ jobject fileDescriptor = env->NewObject(gFileDescriptorOffsets.mClass,
+ gFileDescriptorOffsets.mConstructor);
+ if (fileDescriptor != NULL) {
+ env->SetIntField(fileDescriptor, gFileDescriptorOffsets.mDescriptor, fd);
+ } else {
+ return NULL;
+ }
+ return env->NewObject(gParcelFileDescriptorOffsets.mClass,
+ gParcelFileDescriptorOffsets.mConstructor, fileDescriptor);
+}
+
static JNINativeMethod method_table[] = {
{ "monitorUsbHostBus", "()V", (void*)android_server_UsbService_monitorUsbHostBus },
{ "nativeOpenDevice", "(Ljava/lang/String;)Landroid/os/ParcelFileDescriptor;",
(void*)android_server_UsbService_openDevice },
+ { "nativeGetAccessoryStrings", "()[Ljava/lang/String;",
+ (void*)android_server_UsbService_getAccessoryStrings },
+ { "nativeOpenAccessory","()Landroid/os/ParcelFileDescriptor;",
+ (void*)android_server_UsbService_openAccessory },
};
int register_android_server_UsbService(JNIEnv *env)